我正在尝试使用他们的 Office 365 帐户对我的站点的用户进行身份验证,因此我一直在遵循有关使用 OWIN OpenID Connect 中间件添加身份验证的指南,并成功地验证并检索了他们的个人资料.
我现在正在尝试获取用户的电子邮件地址(以便我可以使用他们的联系方式填充他们的系统帐户),但我似乎无法收到电子邮件声明.我尝试使用范围 openid profile email 发出请求,但声明集不包含任何邮件信息.
有没有办法通过 OpenID Connect 端点从 Azure AD 获取用户的电子邮件?
我在同一个问题上苦苦挣扎了几天才找到解决方案.回答您的问题:是的,只要您:
profile 或 email 范围,并且请注意,电子邮件地址可能不会在 email 声明中返回:在我的情况下(一旦我让它工作)它会在 name 声明中返回.
但是,根本没有得到电子邮件地址可能是由以下问题之一引起的:
根据本指南 Azure Active Directory v2.0 端点中的范围、权限和同意,即使您包含 email 范围,您也可能无法获得电子邮件地址:p><块引用>
email 声明仅在电子邮件地址与用户帐户相关联时包含在令牌中,但情况并非总是如此.如果它使用 email 范围,您的应用应该准备好处理令牌中不存在 email 声明的情况.
如果您收到其他与个人资料相关的声明(如 given_name 和 family_name),这可能是问题所在.
这就是我的原因.我没有收到任何与个人资料相关的声明(名字、姓氏、用户名、电子邮件等).
在我的例子中,身份处理堆栈如下所示:
问题出在 IdentityServer3.AspNetIdentity AspNetIdentityUserService 类中:InstantiateNewUserFromExternalProviderAsync() 方法如下所示:
受保护的虚拟任务<TUser>InstantiateNewUserFromExternalProviderAsync(字符串提供者,字符串 providerId,IEnumerable<Claim>索赔){var user = new TUser() { UserName = Guid.NewGuid().ToString("N") };返回 Task.FromResult(user);}注意它会传入一个声明集合然后忽略它.我的解决方案是创建一个派生自此的类并将该方法重写为如下所示:
受保护的覆盖任务<TUser>InstantiateNewUserFromExternalProviderAsync(字符串提供者,字符串 providerId,IEnumerable<Claim>索赔){var user = 新的 TUser{用户名 = Guid.NewGuid().ToString("N"),索赔=索赔};返回 Task.FromResult(user);}我不确切知道您正在使用什么中间件组件,但很容易看到从您的外部提供商返回的原始声明;这至少会告诉您他们恢复正常,并且问题出在您的中间件的某个地方.只需将 Notifications 属性添加到您的 OpenIdConnectAuthenticationOptions 对象,如下所示:
//将 Azure AD 配置为提供程序var azureAdOptions = 新的 OpenIdConnectAuthenticationOptions{AuthenticationType = 常量.Azure.AuthenticationType,标题 = Resources.AzureSignInCaption,范围 = 常量.Azure.Scopes,ClientId = Config.Azure.ClientId,权限 = 常量.Azure.AuthenticationRootUri,PostLogoutRedirectUri = Config.Identity.RedirectUri,RedirectUri = Config.Azure.PostSignInRedirectUri,AuthenticationMode = AuthenticationMode.Passive,TokenValidationParameters = 新的 TokenValidationParameters{验证发行人 = 假},通知 = 新的 OpenIdConnectAuthenticationNotifications{AuthorizationCodeReceived = 上下文 =>{//记录 Azure AD 返回的所有声明var 声明 = context.AuthenticationTicket.Identity.Claims;foreach(声明中的 var 声明){Log.Debug("{0} = {1}", claim.Type, claim.Value);}返回空值;}},SignInAsAuthenticationType = signInAsType//这必须在 TokenValidationParameters 之后};app.UseOpenIdConnectAuthentication(azureAdOptions);I'm trying to authenticate users to my site with their Office 365 accounts, so I have been following the guidance on using the OWIN OpenID Connect middleware to add authentication and successfully managed to authenticate and retrieve their profile.
I am now trying to get the email address of the user (so I can populate their system account with their contact details), but I can't seem to get an email claim back. I have tried making a request using the scope openid profile email, but the claim-set does not contain any mail information.
Is there a way to get the email of a user from Azure AD via the OpenID Connect endpoint?
I struggled with the same problem for a few days before arriving at a solution. In answer to your question: yes, you should be able to get the e-mail address back in your claims as long as you:
profile or email scope in your request, andNote that the e-mail address may not be returned in an email claim: in my case (once I got it working) it's coming back in a name claim.
However, not getting the e-mail address back at all could be caused by one of the following issues:
As per this guide to Scopes, permissions, and consent in the Azure Active Directory v2.0 endpoint, even if you include the email scope you may not get an e-mail address back:
The
If you're getting other profile-related claims back (like given_name and family_name), this might be the problem.
This was the cause for me. I wasn't getting any profile-related claims back (first name, last name, username, e-mail, etc.).
In my case, the identity-handling stack looks like this:
The problem was in the IdentityServer3.AspNetIdentity AspNetIdentityUserService class: the InstantiateNewUserFromExternalProviderAsync() method looks like this:
protected virtual Task<TUser> InstantiateNewUserFromExternalProviderAsync(
string provider,
string providerId,
IEnumerable<Claim> claims)
{
var user = new TUser() { UserName = Guid.NewGuid().ToString("N") };
return Task.FromResult(user);
}
Note it passes in a claims collection then ignores it. My solution was to create a class derived from this and override the method to something like this:
protected override Task<TUser> InstantiateNewUserFromExternalProviderAsync(
string provider,
string providerId,
IEnumerable<Claim> claims)
{
var user = new TUser
{
UserName = Guid.NewGuid().ToString("N"),
Claims = claims
};
return Task.FromResult(user);
}
I don't know exactly what middleware components you're using, but it's easy to see the raw claims returned from your external provider; that'll at least tell you they're coming back OK and that the problem is somewhere in your middleware. Just add a Notifications property to your OpenIdConnectAuthenticationOptions object, like this:
// Configure Azure AD as a provider
var azureAdOptions = new OpenIdConnectAuthenticationOptions
{
AuthenticationType = Constants.Azure.AuthenticationType,
Caption = Resources.AzureSignInCaption,
Scope = Constants.Azure.Scopes,
ClientId = Config.Azure.ClientId,
Authority = Constants.Azure.AuthenticationRootUri,
PostLogoutRedirectUri = Config.Identity.RedirectUri,
RedirectUri = Config.Azure.PostSignInRedirectUri,
AuthenticationMode = AuthenticationMode.Passive,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = context =>
{
// Log all the claims returned by Azure AD
var claims = context.AuthenticationTicket.Identity.Claims;
foreach (var claim in claims)
{
Log.Debug("{0} = {1}", claim.Type, claim.Value);
}
return null;
}
},
SignInAsAuthenticationType = signInAsType // this MUST come after TokenValidationParameters
};
app.UseOpenIdConnectAuthentication(azureAdOptions);
这篇关于通过 OpenID Connect 从 Azure AD 获取用户的电子邮件地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
ASP.NET Core 使用 Azure Active Directory 进行身份验证并ASP.NET Core authenticating with Azure Active Directory and persisting custom Claims across requests(ASP.NET Core 使用 Azure Active Directory 进行身
ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用ASP.NET Core 2.0 Web API Azure Ad v2 Token Authorization not working(ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用)
如何获取守护进程或服务器到 C# ASP.NET Web API 的How do I get Azure AD OAuth2 Access Token and Refresh token for Daemon or Server to C# ASP.NET Web API(如何获取守护进程或服务器到 C# ASP.N
异步调用时 Azure KeyVault Active Directory AcquireTokenAAzure KeyVault Active Directory AcquireTokenAsync timeout when called asynchronously(异步调用时 Azure KeyVault Active Directory AcquireTokenAsync 超
使用电子邮件地址和应用程序密码从 oauth2/tokenGetting access token using email address and app password from oauth2/token(使用电子邮件地址和应用程序密码从 oauth2/token 获取访问令
新的 Azure AD 应用程序在通过管理门户更新之前无New Azure AD application doesn#39;t work until updated through management portal(新的 Azure AD 应用程序在通过管理门户更新之前无法运行