我正在尝试使用 PCKE 获取 OAuth 代码流,以便与 Swashbuckle (6.2.3) 和 .NET 6 中的 swagger ui 一起使用。有一些事情发生了成功:
问题是当我尝试使用 swagger UI 调用示例天气预报 API 时,授权标头中没有附加任何令牌,并且在请求中看起来像这样:
authorization: Bearer undefined
这是我的代码:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
const string oAuth2 = "oauth2";
options.AddSecurityDefinition(oAuth2, new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(builder.Configuration["AzureAdB2C:AuthorizationUrl"]),
TokenUrl = new Uri(builder.Configuration["AzureAdB2C:TokenUrl"]),
Scopes = {{"openid", "Sign users in"}, {"offline_access", "Maintain access to data you have given it access to"}}
}
},
In = ParameterLocation.Header,
BearerFormat = "JWT",
Scheme = "bearer",
Name = "authorization"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = oAuth2,
Type = ReferenceType.SecurityScheme
},
}, new List<string> {"openid", "offline_access"}
}
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.OAuthClientId(builder.Configuration["AzureAdB2C:ClientId"]);
options.OAuthScopes("openid", "offline_access");
options.OAuthUsePkce();
});
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
我不确定我错过了什么。有什么想法吗?
更新: 我已经能够让它与这样的东西一起工作:
options.UseRequestInterceptor("(req) => { req.headers['Authorization'] = 'Bearer ' + window?.swaggerUIRedirectOauth2?.auth?.token?.id_token; return req; }");
但这看起来不是一个合适的解决方案。
您可以在 OpenApiSecurityScheme 中指定使用 id_token 而不是默认的 access_token,方法是将其添加到扩展中:
Extensions =
{
// Setting x-tokenName to id_token will send response_type=token id_token and the nonce to the auth provider.
// x-tokenName also specifieds the name of the value from the response of the auth provider to use as bearer token.
{ "x-tokenName", new OpenApiString("id_token") }
}
来源:https://github.com/inouiw/SwaggerUIJsonWebToken/blob/master/Program.cs
您已经定义了
SecurityDefinition
和 SecurityRequirement
,但错过了指定哪些端点需要授权的部分。该令牌仅附加到调用授权端点的请求。
您需要添加
options.OperationFilter<MyOperationFilter>();
到您的
AddSwaggerGen(
配置,过滤器如下所示:
public class MyOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any())
{
operation.Security = new List<OpenApiSecurityRequirement>
{
//same security requirment defined in AddSecurityRequirement
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = oAuth2,
Type = ReferenceType.SecurityScheme
},
}, new List<string> {"openid", "offline_access"}
}
}
};
}
}
}