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

时间:2018-04-02 15:56:33

标签: c# azure-ad-b2c owin-middleware

我有以下代码来配置我的ASP.NET MVC Web应用程序中的身份验证过程,包括为用户设置声明" 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}"
    });
}

"名称"声明类型映射到用户的DisplayName,当我使用代码User.Identity.Name时会返回该地图。

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

enter image description here

2 个答案:

答案 0 :(得分:1)

我不确定如何将用户名输入该属性,因为B2C不会返回该值。

您仍然可以获得此值但需要更多工作。 B2C允许您返回" 用户的对象ID "这将作为索赔oid返回。 Sample Token.

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

返回用户的对象ID

user's object id app claim screenshot

UserVoice反馈项:include username in JWT claims

答案 1 :(得分:1)

以上是上述答案的后半部分,其中包括所做的代码更改:

  1. 添加注释了“此处已添加”的代码行,以便声明用户的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