.net-core - 通过 Azure AD 验证的 Swagger 使用 webapi 时出现“无效令牌”
问题描述
我尝试从 swagger (Swashbuckle) 客户端对我的 WebApi (dotnet core 3.1) 使用 AAD 身份验证。在我的 Startup 课程中,我的配置如下:
// Configure authentication
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
我对 AzureAd 的设置:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "xxxx-xxxxx1b",
"Domain": "myoffice.onmicrosoft.com",
"TenantId": "xxxxx-xxxxa5",
"Scope": "api://xxxxxxxx-abc3cff48f1b/Full.Access",
"ScopeDescription": "Full Access"
},
...
services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.OAuth2,
In = ParameterLocation.Header,
Flows = new OpenApiOAuthFlows()
{
Implicit = new OpenApiOAuthFlow
{
TokenUrl = new Uri($"Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/token"),
AuthorizationUrl = new Uri($"{Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/authorize"),
Scopes =
{
{
Configuration["AzureAd:Scope"],Configuration["AzureAd:ScopeDescription"]
}
}
}
}
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
在我的配置方法中:
app.UseSwaggerUI(c =>
{
c.RoutePrefix = string.Empty;
c.SwaggerEndpoint($"/swagger/{ApiVersion}/swagger.json", ApiName);
c.OAuthClientId(Configuration["AzureAd:ClientId"]);
c.OAuthScopeSeparator(" ");
});
Swagger 使用我的凭据正确登录到 AAD,当我使用受[Authorize]
令牌保护的路由时,我收到 401 错误并显示以下消息,从而正确发送到 API:
www-authenticate: Bearer error="invalid_token"error_description="The issuer 'https://login.microsoftonline.com/{tenantid}/v2.0' is invalid"
urlhttps://login.microsoftonline.com/{tenantid}/v2.0
位于 iss 部分的令牌中。
怎么了?
解决方案
根据您的错误和代码,您没有告诉您的应用程序 ValidIssuer。所以你得到了错误。请在文件方法ConfigureServices
中 添加以下代码startup.cs
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuers = new[] {
},
});
例如
为您的 Web API 配置 Azure AD。更多详细信息,请参阅文档
一种。创建 Azure AD Web api 应用程序
湾。 公开 API
C。配置代码
- 配置文件
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "ClientId": "[Client_id-of-web-api-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]", "TenantId": "<your tenant id>" },
- 在 Stratup.cs 中添加以下代码
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options)); services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options => { options.Authority += "/v2.0"; options.TokenValidationParameters = new TokenValidationParameters { /** * with the single-tenant application, you can configure your issuers * with the multiple-tenant application, please set ValidateIssuer as false to disable issuer validation */ ValidIssuers = new[] { $"https://sts.windows.net/{Configuration["AzureAD:TenantId"]}/", $"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/v2.0" }, ValidAudiences = new[] { options.Audience, $"api://{options.Audience}" } }; });
配置招摇。更多详情,请参阅博客。
一种。创建 Azure Web 应用程序
湾。配置 API 权限。关于如何配置,可以参考文档
C。代码
安装 SDK
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
配置文件
"Swagger": { "ClientId": "" },
在 ConfigureServices 方法中将以下代码添加到 Startup.cs:
services.AddSwaggerGen(o => { // Setup our document's basic info o.SwaggerDoc("v1", new OpenApiInfo { Title = "Protected Api", Version = "1.0" }); // Define that the API requires OAuth 2 tokens o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { Implicit = new OpenApiOAuthFlow { Scopes = new Dictionary<string, string> { { "api://872ebcec-c24a-4399-835a-201cdaf7d68b/user_impersonation","allow user to access api"} }, AuthorizationUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/authorize"), TokenUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/token") } } }); o.AddSecurityRequirement(new OpenApiSecurityRequirement{ { new OpenApiSecurityScheme{ Reference = new OpenApiReference{ Id = "oauth2", Type = ReferenceType.SecurityScheme } },new List<string>() } }); });
将以下代码添加到 Configure 方法中:
app.UseSwagger(); app.UseSwaggerUI(c => { c.OAuthClientId(Configuration["Swagger:ClientId"]); c.OAuthScopeSeparator(" "); c.OAuthAppName("Protected Api"); c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); });
推荐阅读
- android - 布尔值 isChecked 不随 foreach 变化
- python - 有人知道这个算法的 O 表示法吗?我认为这可能是指数级的,但并不完全确定
- git - 如何将本地分支中新创建的分支推送到远程上游仓库?
- python - 如何将 26 个数字拆分为这种格式:(12 1034 0000 1212 9056 1111 7806)
- c++ - 诡异的 QTcpSocket 行为
- sql - 在oracle sql中获取每天最大重复行
- sql - 将记录从 Arduino / Esp8622 插入 MS SQL 数据库
- javascript - Yaml 文件在 Gatsby Graphql 查询中返回 null
- python - 如何将具有 [1] (对象)等值的列转换为数值?
- python-3.x - 为什么我在提供的内容中收到 ValueError?