Как установить TokenValidationParameters.NameClaimType на имя пользователя вместо имени для пользователя Azure AD B2C?

У меня есть следующий код для настройки процесса аутентификации в моем веб-приложении ASP.NET MVC, включая установку требования к «имени» пользователя при проверке токена удостоверения пользователя, полученного приложением.

(Обратите внимание, что я следую этот пример кода)

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?

введите здесь описание изображения


person aBlaze    schedule 02.04.2018    source источник


Ответы (2)


Я не уверен, как вы можете получить имя пользователя в этом свойстве, поскольку B2C не возвращает это значение.


Вы все еще можете получить это значение, но для этого потребуется больше работы. B2C позволяет вам вернуть «Идентификатор объекта пользователя», который будет возвращен как заявка oid. Sample Token.

Вы можете получить утверждение oid, а затем запросить Azure AD, чтобы получить значение имени пользователя. См. этот ответ SO при запросе Azure AD.

Возвращает идентификатор объекта пользователя

скриншот заявки приложения с идентификатором объекта пользователя


Элемент отзыва UserVoice: включить имя пользователя в утверждения JWT

person spottedmahn    schedule 02.04.2018
comment
Спасибо за помощь! Теперь я могу подтвердить, что идентификатор объекта пользователя (oid) существует, так как мне удалось его декодировать с помощью инструмента https://jwt.ms/. Как я могу легко получить oid в веб-приложении? - person aBlaze; 03.04.2018
comment
Я попытался GET https://graph.windows.net/me?api-version=1.6, но это, к сожалению, возвращает мне Error 401: Unauthorized. Я также пытался посмотреть в объекте TokenValidationParameters, чтобы увидеть, есть ли там ObjectIdClaimType или подобный объект, но не смог его найти. - person aBlaze; 03.04.2018
comment
На самом деле, я смог выяснить это, добавив пользовательское утверждение в свой обратный вызов OnAuthorizationCodeReceived: Security.Claims.ClaimsIdentity)User.Identity).FindFirst(ObjectId).Value;` Оказывается, мне не нужна ваша помощь с этим. Спасибо, споттедман! - person aBlaze; 03.04.2018
comment
Вы должны дать ответ :) @Emilia. Рад помочь :) - person spottedmahn; 03.04.2018
comment
Я попытался отредактировать ваш ответ, чтобы включить изменения, связанные с кодом, которые я сделал, но 2 человека отклонили мое редактирование. Иногда я не понимаю StackOverflow. смешной. Я не уверен, что у вас есть право принять мое редактирование вашего ответа, но если да, пожалуйста, примите его или дайте мне знать, как я могу его улучшить, чтобы он был приемлемым. - person aBlaze; 04.04.2018


Вот вторая половина приведенного выше ответа, включающая внесенные изменения в код:

  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. Затем позже в веб-приложении, когда вам нужно получить и использовать 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. Вам может понадобиться получить UserPrincipalName или SignInName, в зависимости от вашего типа пользователя. Для получения дополнительной информации см. " здесь.

person aBlaze    schedule 04.04.2018
comment
Re # 3: Для пользователей B2C значение будет в SignName. Я предполагаю, что UPN — это свойство Azure AD. - person spottedmahn; 17.04.2018