Azure Oauth 2 не может отобразить все полезные данные претензий jwt - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь создать asp. net core 3.1 api с oauth 2. Аутентификация / авторизация все хорошо с помощью этого фрагмента кода:

services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = "AzureAD";
            })
                .AddCookie()
                .AddOAuth("AzureAD", options =>
                {
                    options.ClientId = Configuration["AppSettings:AzureAuthentication:ClientId"];
                    options.ClientSecret = Configuration["AppSettings:AzureAuthentication:ClientSecret"];
                    //options.ClientSecret = _appSettings.AzureAuthentication.ClientSecret;
                    options.CallbackPath = new PathString("/oauth");
                    options.Scope.Add("openid");
                    //options.Scope.Add("user.read");
                    options.AuthorizationEndpoint = "https://login.microsoftonline.com/xxxxx-5ceb-4dcc-9c08-xxxxxx/oauth2/v2.0/authorize";
                    options.TokenEndpoint = "https://login.microsoftonline.com/xxxxx-5ceb-4dcc-9c08-xxxxx/oauth2/v2.0/token";
                    options.UserInformationEndpoint = "https://graph.microsoft.com/oidc/userinfo";

                    options.SaveTokens = true;

                    // Specify how to map the claims from the jwt 
                    //options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
                    //options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
                    //options.ClaimActions.MapJsonKey("EmailAddresss", "email");
                    options.ClaimActions.MapAll();
                    //options.ClaimActions.MapJsonKey("Username", "unique_name");


                    options.Events = new OAuthEvents
                    {
                        OnCreatingTicket = async context =>
                        {
                            var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);

                            var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
                            response.EnsureSuccessStatusCode();

                            var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement;
                            context.RunClaimActions(user);
                        }
                    };
                });

С успехом я могу перехватить токен доступа и декодирование его онлайн подтверждают, что он имеет эту полезную нагрузку:

"aud": "00000003-0000000-000000000",
  "iss": "https://sts.windows.net/xxxx-xxxxx-xxxxxxx-xxxx-xxxxxxx/",
  "iat": 15772157,
  "nbf": 5545,
  "exp": 15776057,
  "acct": 1,
  "acr": "1",
  "aio": "xxxxAu/8xxxxxx+qmbSExxxxxE8QkIRLdeFfPay244p/Zrzxxxxxr/eYnxxxxxkm/AOxxxxug==",
  "altsecid": "5::100xxxxx9E"
  "amr": [
    "pwd"
  ],
  "app_displayname": "Displayname",
  "appid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",
  "appidacr": "1",
  "email": "fake@hotmail.com",
  "idp": "https://stds.winddga.net/a3b390fds7c2434dbd69/",
  "ipaddr": "255.255.255.255",
  "name": "john, doe",
  "oid": "xxxxx-xxxx-xxxx-xxxx-xxxxxxx",
  "platf": "3",
  "puid": "xxxxxxxx",
  "scp": "openid User.Read profile email",
  "sub": "JFYa_zXr8z2hxXPu87hmLa_yMUyewLxVGJCGUsPfZqo",
  "tid": "xxxxx-xxxx-xxxxx-xxxxx-xxxxxxxxx",
  "unique_name": "Unique_name@hotmail.com",
  "uti": "xxxxx",
  "ver": "1.0",

}

В контроллере я пытаюсь отобразить все эти заявки из полезной нагрузки.

[Authorize]
[HttpGet]
        public ActionResult<string> Get()
        {
            var claims = User.Claims.Select(x => new { Type = x.Type.Split('/').LastOrDefault(), Value =  x.Value}).ToList();
            return JsonSerializer.Serialize(claims);
        }

пользователь (Applicprincipal) содержит только 4 заявки (гораздо меньше, чем я ожидал).

Итак, я знаю, что претензии находятся в полезной нагрузке, но я не могу получить к ним доступ из декодирования jwt. Я ожидаю, что options.ClaimActions.MapAll () отобразит все утверждения, но это только четыре. Если я попытаюсь: options.ClaimActions.MapJsonKey («EmailAddresss», «email»), он будет сопоставлять претензию электронной почты, но это не работает с: options.ClaimActions.MapJsonKey («Имя пользователя», «уникальное_имя»).

Вопрос: Как мне получить доступ ко всем данным (претензии в моем понимании) в моем контроллере, кроме имени изображения и почты?

РЕДАКТИРОВАТЬ: Что я только что понял: это установка претензий от конечная точка пользовательской информации, а не JWT. Я могу декодировать JWT в контроллере c, но я не думаю, что это будет решением. Разве токен доступа где-то не декодирован для доступа?

1 Ответ

1 голос
/ 24 января 2020

Ваше решение для использования AddOAuth получит токен доступа Microsoft Graph и получит профиль пользователя из конечной точки Microsoft Graph UserInfo, поэтому будет отображать претензии только из конечной точки Microsoft Graph UserInfo. Вы можете напрямую запросить /me, чтобы получить информацию о пользователе, используя Microsoft Graph API и добавить к принципу пользователя:

https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http

Другой способ - использование AddOpenIdConnect Middleware который будет считывать заявки из идентификатора токена и OID C конечной точки UserInfo, которые дают больше информации о профиле пользователя:

https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-webapp

Простой способ - использовать шаблон по умолчанию Azure AD: Изменить аутентификацию -> Work or School Accounts при создании основного веб-приложения asp. net.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...