如何为 Azure AD B2C 用户将 TokenValidationParameters.NameClaimType 设置为 "username" 而不是 "name"?

How to set TokenValidationParameters.NameClaimType to "username" instead of "name" for Azure AD B2C user?

我有以下代码在我的 ASP.NET MVC 网络应用程序中配置身份验证过程,包括在验证应用程序收到的用户身份令牌时设置对用户 "name" 的声明.

(注意我关注的是this sample code

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        CookieSecure = CookieSecureOption.Always
    });

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        // Generate the metadata address using the tenant and policy information
        MetadataAddress = String.Format(AadInstance, Tenant, DefaultPolicy),

            // These are standard OpenID Connect parameters, with values pulled from web.config
            ClientId = ClientId,
            Authority = Authority,
            PostLogoutRedirectUri = RedirectUri,
            RedirectUri = RedirectUri,

            Notifications = new OpenIdConnectAuthenticationNotifications()
            {
                RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                AuthenticationFailed = OnAuthenticationFailed,
                AuthorizationCodeReceived = OnAuthorizationCodeReceived,
            },

            // Specify the claims to validate
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name"
            },

            // Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
            Scope = $"{OpenIdConnectScopes.OpenId} {ReadTasksScope} {WriteTasksScope}"
    });
}

"name" 声明类型映射到用户的 DisplayName,当我使用代码 User.Identity.Name.

时返回该类型

如何让 User.Identity.Name 映射到用户的用户名,如下面 Azure Active Directory B2C 用户的屏幕截图所示?

我不确定如何将用户名输入 属性,因为 B2C 没有 return 该值。


您仍然可以获得此值,但需要更多的工作。 B2C 确实允许您 return“用户的对象 ID”,它将作为声明返回 oidSample Token.

您可以获取oid 声明,然后查询Azure AD 以获取用户名值。请参阅有关查询 Azure AD 的 SO answer

Return 用户对象 ID


Azure 反馈项目:include username in JWT claims


这是上面答案的第二部分,其中包括所做的代码更改:

  1. 添加注释为 "Added line here" 的代码行,以便声明用户的 ObjectId

    private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
    {
        // Extract the code from the response notification
        var code = notification.Code;
    
        string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
        TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
        ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null);
    
        ///////////////////////////////////
        // Added line here
        ///////////////////////////////////
        // Add a custom claim to the user's ObjectId ('oid' in the token); Access it with this code: ((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirst("ObjectId").Value
        notification.AuthenticationTicket.Identity.AddClaim(new System.Security.Claims.Claim("ObjectId", signedInUserID));
    
        try
        {
            AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, Scopes);
        }
        catch (Exception ex)
        {
            MyLogger.LogTrace("Failed to retrieve AuthenticationResult Token for user " + signedInUserID, MyLogger.LogLevel.Critical);
            return;
        }
    }
    
  2. 然后在 Web 应用程序中,当您需要获取和使用用户的 ObjectId 时,请执行以下操作:

    try
    {
        string signedInUserObjectId = ((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirst("ObjectId").Value;
    }
    catch (Exception e)
    {
        ... This should never happen, but better safe than sorry ...
    }
    
  3. 最后,使用 Azure AD 图形客户端,您可以使用 ObjectId 获取用户对象,其中包含用户名。您需要的具体查询是 GET https://graph.windows.net/myorganization/users/{user_id}?api-version。根据您的用户类型,您可能需要获取 UserPrincipalNameSignInName。更多信息,see the "Get a user" section here.