Я пытаюсь создать 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, но я не думаю, что это будет решением. Разве токен доступа где-то не декодирован для доступа?