如何在Swagger UI(版本10.1.7)中配置,使其通过Authorization头发送Bearer令牌?
我们最近将.NET项目迁移到 Swashbuckle.AspNetCore 10.1.7,版本来自6.6.2,作为一次更大范围的.NET 8到 .NET 10迁移的一部分。不过,我在新版本的Swagger UI上遇到了严重的认证/授权问题。
在迁移之前,我们的认证/授权设置如下:
- OAuth2隐式授权方案
我们使用隐式流来登录并获取访问令牌。
Authority/Identity Provider Configuration:
```cs
public static AuthenticationBuilder AddAuthenticationForClientPortalApi(
this IServiceCollection services,
AuthorityConfig authorityConfig,
Action
return services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = authorityConfig.BaseUrl;
options.ApiName = authorityConfig.ApiName;
configureOptions?.Invoke(options);
});
} ```
我们添加了 oauth2 安全定义,通过在身份提供者的登录页提交凭据来获取访问令牌。
```cs
return services.AddTransient
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = authFlow == AuthFlowType.Implicit ?
new OpenApiOAuthFlows()
{
Implicit = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri(authorityConfig?.AuthorizationUrl),
Scopes = scopes
}
} :
new OpenApiOAuthFlows()
{
ClientCredentials = new OpenApiOAuthFlow()
{
TokenUrl = new Uri(authorityConfig?.AuthorizationUrl),
Scopes = scopes
}
}
});
options.OperationFilter<TAuthFilter>();
options.EnableAnnotations();
if (maskSchemas)
{
options.CustomSchemaIds(type =>
Convert.ToBase64String(Encoding.UTF8.GetBytes(type?.FullName.ToSha256() ?? ""))
.Trim('='));
}
});
``` 2. Swagger UI登录流程
该配置允许通过Swagger UI的 Authorize按钮进行登录,并隐式重定向到身份提供者的登录页。 3. 请求执行
执行已授权的端点请求时,自动在请求头中插入 Authorization 头部及 Bearer 的访问令牌。如下所示:
在迁移到最新的 Swashbuckle.AspNetCore 包(仅命名空间调整)。后,步骤3 的行为发生了变化;当我使用Swagger UI执行任意API请求时,发送到API的只有一个cookie,缺少带有 Bearer 令牌的 Authorization 头部。如下所示:
如何在版本10.x.x中配置Swagger UI,使其在携带cookie的同时,将接收到的Bearer令牌放入一个 Authorization 头部发送,并保持初始的OAuth2隐式流登录?此外,在版本10.x.x中,Swagger UI在首次登录/解锁API页面后,会将授权数据存储在哪里?
以下是我当前在项目中引用的包
<PackageReference Include="Microsoft.OpenApi" Version="2.4.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
我已经搜索了类似的问题,但没有找到针对.NET 10和 Swashbuckle.AspNetCore 10.1.7的解答。早期版本的变通方法似乎并不适用。
解决方案
在花了一定时间研究Swashbuckle.AspNetCore 10.1.7的源码后,我想到的变通办法是注册一个JavaScript拦截器函数。希望对某些人有帮助
app.UseSwaggerUI(options =>
{
// Configuration code above
options.UseRequestInterceptor(
"(req) => {" +
"const token = window.ui.authSelectors.authorized().getIn(['oauth2', 'token', 'access_token']);" +
"if (token) req.headers['Authorization'] = 'Bearer ' + token;" +
"return req;" +
"}");
configureOptions?.Invoke(options);
这个拦截器将把Bearer令牌添加到通过Swagger UI提交的每一个HTTP请求中。

