У меня проблема с функцией «авторизации» Swagger для аутентификации приложения WebApi с использованием конечной точки Azure AD 2.0. Я использовал следующие настройки в своем классе запуска, но полученный токен не может проверить токен носителя внутри Swagger. API отлично работает с токеном, отправленным реагирующим клиентом.
private const string AzureAdConfigKey = "AzureAd";
private const string OAuth2Definition = "openid";
private IConfiguration Configuration { get; }
private IHostingEnvironment Environment { get; }
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
Environment = environment;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind(AzureAdConfigKey, options));
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme,
options => options.Authority += "/v2.0");
var authorizationPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(authorizationPolicy)))
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var azureAdAuthority = $"https://login.microsoftonline.com/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0";
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new Info
{
Title = "My Api Name",
Version = "v1"
});
options.AddSecurityDefinition(OAuth2Definition, new OAuth2Scheme
{
Description = "OAuth2 Implicit Grant",
Flow = "implicit",
AuthorizationUrl = $"{azureAdAuthority}/authorize",
TokenUrl = $"{azureAdAuthority}/connect/token",
Scopes = new Dictionary<string, string>
{
{OAuth2Definition, "User.Read"}
}
});
options.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {{OAuth2Definition, null}});
});
services.AddCors(options => options.AddPolicy("AllowSpecificOrigin", builder => builder
.WithOrigins(Configuration["MyAppClientUrl"])
.AllowCredentials()
.AllowAnyHeader()
.AllowAnyMethod()
));
// Other Service Registrations.
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseCors("AllowSpecificOrigin");
app.UseHsts();
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(config =>
{
const string swaggerName = "MyApp Coding Api";
const string swaggerUrl = "/swagger/v1/swagger.json";
config.SwaggerEndpoint(swaggerUrl, swaggerName);
config.RoutePrefix = string.Empty;
config.OAuthAppName(swaggerName);
config.OAuthClientId(Configuration["AzureAd:ClientId"]);
config.OAuthClientSecret(Configuration["AzureAd:ClientSecret"]);
// This is my Api local path.
config.OAuthRealm("https://localhost:44398/swagger/ui/o2c-html");
config.OAuthScopeSeparator(" ");
});
app.UseAuthentication();
app.UseMvc();
}
Ниже представлен токен, сгенерированный клиентом, который отлично работает и реализует .v2.0:
{
"aud": "{Excldued}",
"iss": "https://login.microsoftonline.com/{Excldued}/v2.0",
"iat": 1556730915,
"nbf": 1556730915,
"exp": 1556734815,
"aio": "AVQAq/8LAAAA9lULrpdFyoAfnaWTCkdo8PMz2vL4C0MbDNAxmRBa3rMETsjpnXYFb5izdF/VRWMLzOvwgmw9Zt3zzisWRbLCFMd5KAaJ59wUDqNdSoawS6U = ",
"name": "{Excldued}",
"nonce": "{Excldued}",
"oid": "{Excldued}",
"preferred_username": "{Excldued}",
"roles": [
"Coder",
"Supervisor"
],
"sub": "Jn0w0rhsGpwTKPdSjQBLHeHDv2_TD4kaOjo0x06JWKQ",
"tid": "{Excldued}",
"uti": "pOW4Q_EBdkSv_q0-OHRSAA",
"ver": "2.0"
}
Но swagger генерирует следующий токен .v1.0:
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/{Excluded}/",
"iat": 1556733552,
"nbf": 1556733552,
"exp": 1556737452,
"acct": 0,
"acr": "1",
"aio": "AUQAu/8LAAAA9YXDyeK8KuCHbNgw7RGU8GgJk3qpWB1H+Q3i/dC/VRoAtYvp3NHFIYcTFxn3jfTPvvXRWx5MN35kvO0iCK7ftg= = ",
"amr": [
"pwd",
"mfa"
],
"app_displayname": "{Excluded}",
"appid": "{Excluded}",
"appidacr": "0",
"family_name": "{Excluded}",
"given_name": "{Excluded}",
"ipaddr": "{Excluded}",
"name": "{Excluded}",
"oid": "{Excluded}",
"onprem_sid": "{Excluded}",
"platf": "3",
"puid": "{Excluded}",
"scp": "openid profile User.Read email",
"signin_state": [
"kmsi"
],
"sub": "{Excluded}",
"tid": "{Excluded}",
"unique_name": "{Excluded}",
"upn": "{Excluded}",
"uti": "{Excluded}",
"ver": "1.0",
"xms_st": {
"sub": "{Excluded}"
},
"xms_tcdt": 1361394419
}
Что я делаю неправильно в своей конфигурации Swagger, которая запрашивает конечную точку 1.0 и получает неправильный тип токена?
Это запрос скрипача к конечной точке авторизации Azure AD:
GET https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/authorize?response_type=token&client_id = {ClientId}&redirect_uri=https%3A%2F%2Flocalhost%3A44350%2Foauth2-redirect.html&scope=openid&state = {StateValue}&nonce=123456 HTTP/1.1
Host: login.microsoftonline.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: https://localhost:44350/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Привет, @FrankHu. Я обновил вопрос с запросом Fiddler. Странно то, что API отлично работает с клиентским SPA-приложением, которое выполняет аутентификацию с помощью библиотеки MSAL. Это просто не работает с Swagger или Postman. Спасибо, что проверили это.
Если хотите, я могу связать вас со службой технической поддержки для более подробного изучения. Может быть полезно увидеть полную трассировку скрипача. Я не уверен, является ли этот запрос запросом Swagger. Вы можете написать мне по адресу [email protected] и включить в электронное письмо ссылку на эту ветку, чтобы я мог отправить вам бесплатный запрос в службу поддержки.
@ Саид, как ты это починил?





Причина, по которой вы получаете токен версии 1.0, заключается в том, что вы пытаетесь получить доступ к ресурсу версии 1.0. См. статью здесь: https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens
Access tokens are created based on the audience of the token, meaning the application that owns the scopes in the token. This is how a resource setting accessTokenAcceptedVersion in the app manifest to 2 allows a client calling the v1.0 endpoint to receive a v2.0 access token. Similarly, this is why changing the access token optional claims for your client do not change the access token received when a token is requested for user.read, which is owned by the MS Graph resource. For the same reason, while testing your client application with a personal account (such as hotmail.com or outlook.com), you may find that the access token received by your client is an opaque string. This is because the resource being accessed has requested legacy MSA (Microsoft account) tickets that are encrypted and can't be understood by the client.
Ваш токен версии 1.0 имеет аудиторию для Microsoft Graph, который выдается конечной точкой версии 1.0. Если вы следите за статьей здесь: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow Вы увидите, что даже при попадании в конечную точку версии 2.0 и запросе токена доступа с помощью Postman для ресурса graph.microsoft.com вы получите токен доступа, где у iss нет версии 2.0.
Это также очень полезный ресурс, так как это хороший справочник по некоторым популярным идентификаторам GUID в Azure. : https://www.shawntabrizi.com/aad/common-microsoft-resources-azure-active-directory/
Привет, Саид, можно ли как-нибудь разместить это локально и получить трассировку скрипача/сети, чтобы увидеть, что на самом деле делает Swagger? И если да, можете ли вы предоставить URL-адрес, на который идет swagger? Похоже, что метод configureservices настроен правильно, поэтому он должен перейти к конечной точке версии 2.0,