如何访问Swashbuckle.AspNetCore保护的API并实现令牌自动填充?
我来帮你梳理这两个疑问,以及对应的解决办法:
1. 访问令牌存储在哪里?
当你在 Swagger UI 完成 IdentityServer4 的授权流程后,获取到的 access_token(以及可能的 refresh_token)是存储在浏览器的 Session Storage 里的。你可以打开浏览器开发者工具(F12),切换到「Application」标签,找到「Session Storage」,就能看到以 swaggerOAuth2 开头的存储项,里面就包含了这些令牌信息。
而你在 API 的 accessToken 变量中能拿到令牌,是因为 API 收到请求后,从请求头的 Authorization 字段(格式为 Bearer {token})里解析出令牌,再通过 HttpContext.Authentication.GetTokenAsync 从认证中间件的上下文里获取到的。
2. 为什么 Swagger UI 不能自动填充令牌到授权头?
核心原因是你的 Swagger 配置缺少了安全要求绑定和Swagger UI 的 OAuth 客户端配置,导致 Swagger UI 不知道要把存储的令牌自动应用到受保护的 API 端点请求中。
正确的操作步骤与代码调整
步骤1:完善 SwaggerGen 的安全配置(ConfigureServices 方法)
需要添加安全要求过滤器,明确告诉 Swagger 哪些端点需要使用 OAuth2 认证,同时确保安全定义的配置正确:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "API v1", Version = "v1" }); c.SwaggerDoc("v2", new Info { Title = "API v2", Version = "v2" }); // 配置 OAuth2 安全定义 c.AddSecurityDefinition("oauth2", new OAuth2Scheme { Type = "oauth2", Flow = "accessCode", AuthorizationUrl = "http://localhost:5000/connect/authorize", TokenUrl = "http://localhost:5000/connect/token", Scopes = new Dictionary<string, string> { { "api1", "My API" } } }); // 添加安全要求:指定哪些端点需要应用 OAuth2 认证 c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "oauth2", new[] { "api1" } } }); // 如果你使用自定义的 OperationFilter,确保它能识别安全要求 // c.OperationFilter<AuthorizationHeaderParameterOperationFilter>(); // (如果没有特殊自定义需求,上面的 AddSecurityRequirement 已经足够) });
步骤2:配置 Swagger UI 的 OAuth 客户端参数(Configure 方法)
在启用 Swagger UI 时,需要添加客户端ID、回调地址等配置,让 Swagger UI 能正确和 IdentityServer4 交互并自动应用令牌:
app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "API v2"); // OAuth2 客户端配置(和 IdentityServer4 中注册的客户端一致) c.OAuthClientId("swagger"); // 你的 IdentityServer4 中注册的 Swagger 客户端ID c.OAuthClientSecret("secret"); // 客户端密钥(如果有设置的话) c.OAuthAppName("Swagger UI"); c.OAuthScopeSeparator(" "); c.OAuthUsePkce(); // 如果你的 IdentityServer4 启用了 PKCE,打开这个选项 });
步骤3:确保 IdentityServer4 的客户端配置正确
在 IdentityServer4 的客户端注册代码中,必须添加 Swagger UI 的回调地址:
new Client { ClientId = "swagger", ClientName = "Swagger UI", AllowedGrantTypes = GrantTypes.Code, RequirePkce = true, ClientSecrets = { new Secret("secret".Sha256()) }, // Swagger UI 默认的回调地址,根据你的 API 端口调整 RedirectUris = { "http://localhost:5001/swagger/oauth2-redirect.html" }, PostLogoutRedirectUris = { "http://localhost:5001/swagger/" }, AllowedScopes = { "api1" }, AllowAccessTokensViaBrowser = true // 允许浏览器获取令牌 }
完成以上配置后,你再重新运行项目:
- 打开 Swagger UI,点击「Authorize」按钮,完成 IdentityServer4 的授权流程
- 回到 Swagger UI,调用带有
[Authorize]属性的端点时,Swagger 会自动从 Session Storage 中读取令牌,添加到请求的Authorization头里,无需手动输入。
内容的提问来源于stack exchange,提问作者Mini Dev 1

