.NET Core集成Azure AD认证后,如何提取并自动携带令牌?
解决方案:Azure AD认证后自动处理Swagger令牌
一、提取并保存令牌到Cookie(适配Swagger前端场景)
.NET Core中可以通过OpenID Connect的认证事件捕获令牌,存入Cookie后让Swagger自动携带,无需手动复制。
1. 配置认证事件捕获令牌
在Program.cs的认证配置中,通过OnAuthorizationCodeReceived事件获取访问令牌并写入Cookie:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches(); // 配置交互式OpenID Connect认证流 builder.Services.AddAuthentication() .AddOpenIdConnect(options => { builder.Configuration.Bind("AzureAd", options); options.ResponseType = "code id_token"; options.Scope.Add("api://{你的API资源ID}/access_as_user"); // 替换为实际API权限 options.Events = new OpenIdConnectEvents { OnAuthorizationCodeReceived = async context => { // 获取用户访问令牌 var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>(); var accessToken = await tokenAcquisition.GetAccessTokenForUserAsync( new[] { "api://{你的API资源ID}/access_as_user" }, authenticationScheme: OpenIdConnectDefaults.AuthenticationScheme, user: context.Principal); // 将令牌写入Cookie,设置安全属性 context.HttpContext.Response.Cookies.Append("SwaggerAccessToken", accessToken, new CookieOptions { HttpOnly = false, // 允许Swagger的JS读取 Secure = builder.Environment.IsProduction(), // 生产环境强制HTTPS SameSite = SameSiteMode.Lax, Expires = DateTimeOffset.UtcNow.AddHours(1) // 和令牌过期时间同步 }); // 清理认证流程的临时参数,重定向到干净的Swagger页面 context.HandleCodeRedemption(); context.Response.Redirect("/swagger"); } }; });
2. 让Swagger自动携带Cookie中的令牌
修改Swagger配置,注入自定义JS拦截请求,自动添加Authorization头:
builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "你的API", Version = "v1" }); // 添加Bearer认证定义 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "JWT授权头,格式为Bearer {token}" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty<string>() } }); }); // 注入自定义JS到Swagger UI app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "你的API V1"); c.InjectJavascript("/swagger-custom.js"); });
在wwwroot目录下创建swagger-custom.js,实现Cookie读取和请求拦截:
// 从Cookie中获取令牌 function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } // 拦截Swagger的请求,自动添加Authorization头 const originalFetch = window.fetch; window.fetch = function(resource, options) { const token = getCookie('SwaggerAccessToken'); if (token) { options = options || {}; options.headers = options.headers || {}; options.headers['Authorization'] = `Bearer ${token}`; } return originalFetch(resource, options); };
二、临时方案:直接提取令牌字符串(不推荐生产环境)
如果无法使用Cookie存储,可以在认证后将令牌作为参数传递到Swagger,再通过JS提取并填充到授权栏:
1. 修改重定向逻辑携带令牌
options.Events = new OpenApiConnectEvents { OnAuthorizationCodeReceived = async context => { var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>(); var accessToken = await tokenAcquisition.GetAccessTokenForUserAsync( new[] { "api://{你的API资源ID}/access_as_user" }, authenticationScheme: OpenIdConnectDefaults.AuthenticationScheme, user: context.Principal); // 重定向到Swagger并携带令牌(仅临时测试用) context.Response.Redirect($"/swagger?access_token={accessToken}"); context.HandleCodeRedemption(); } };
2. 在Swagger中提取并填充令牌
修改swagger-custom.js实现URL参数提取:
// 从URL参数中获取令牌 function getUrlParam(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } window.onload = function() { const token = getUrlParam('access_token'); if (token) { // 自动填充Swagger的Bearer令牌输入框 const authInput = document.querySelector('input[type="text"][placeholder="Enter value"]'); if (authInput) { authInput.value = token; // 自动触发授权按钮点击 const authButton = authInput.parentElement.querySelector('button'); if (authButton) authButton.click(); } // 清理URL中的令牌参数,避免泄露 window.history.replaceState({}, document.title, window.location.pathname); } };
关键说明
- 你之前无法读取
/swagger/access_token的URL,是因为Azure AD的认证回调地址是/signin-oidc,令牌由OpenID Connect中间件处理,必须在认证事件中捕获,而非直接读取Swagger的页面URL。 - 生产环境优先使用Cookie方案,务必开启HTTPS和
Secure=true,降低令牌泄露风险。
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

