.NET 6项目基于Azure AD同时实现OAuth2(Bearer Token)与OpenID Connect认证的方案问询(合并Web App与Web API)
.NET 6项目基于Azure AD同时实现OAuth2(Bearer Token)与OpenID Connect认证的方案问询(合并Web App与Web API)
嗨,我完全理解你想把两个轻量服务合并成一个项目的需求——既要支持用户通过Azure AD登录的Web App场景,又要兼容Bearer Token调用的API场景。在.NET 6里确实需要调整一下认证配置逻辑,下面我给你一步步梳理可行的解决方案:
第一步:合并并配置appsettings.json
把原WebApp和WebApi的Azure AD配置整合到同一个配置文件中,示例如下:
{ "WebApp:AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "my-test.onmicrosoft.com", "TenantId": "b1b0b0b0-1b1b-1b1b-1b1b-1b1b1b1b1b1b", "ClientId": "你的WebApp客户端ID", "ClientSecret": "你的WebApp客户端密钥", "CallbackPath": "/signin-oidc", "SignedOutCallbackPath ": "/signout-callback-oidc" }, "WebApi:AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "my-test.onmicrosoft.com", "TenantId": "b1b0b0b0-1b1b-1b1b-1b1b-1b1b1b1b1b1b", "ClientId": "你的WebApi客户端ID" } }
注意:WebApi配置不需要
ClientSecret,因为只需要验证Bearer Token的有效性,而非主动发起认证请求。
第二步:配置Program.cs中的认证与授权服务
你需要同时注册**OIDC认证(用于Web App登录)和JwtBearer认证(用于API令牌验证)**两种方案,再定义对应授权策略:
var builder = WebApplication.CreateBuilder(args); // 关闭默认Claim映射,避免Azure AD的原生Claims被自动重命名 JwtSecurityTokenHandler.DefaultMapInboundClaims = false; // 1. 配置Web App用的OIDC认证(搭配Cookie存储登录状态) builder.Services.AddAuthentication(options => { // 设置默认认证/登录/挑战方案为Cookie+OIDC,适配Web App的会话场景 options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddMicrosoftIdentityWebApp(builder.Configuration, "WebApp:AzureAd") .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches(); // 2. 配置Web API用的JwtBearer认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration, "WebApi:AzureAd"); // 3. 定义自定义授权策略,区分两种访问场景 builder.Services.AddAuthorization(options => { // WebApp策略:仅允许通过Cookie认证(即Azure AD登录后的用户)访问 options.AddPolicy("WebApp", policy => { policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme); policy.RequireAuthenticatedUser(); }); // WebApi策略:仅允许携带有效Bearer Token的请求访问 options.AddPolicy("WebApi", policy => { policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme); policy.RequireAuthenticatedUser(); }); }); // 添加控制器服务 builder.Services.AddControllersWithViews(); var app = builder.Build(); // 中间件配置(注意顺序:认证必须在授权之前) if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
第三步:在控制器中应用授权策略
按照你原本的思路,直接在Action或Controller上标注对应的策略即可:
[ApiController] [Route("[controller]")] public class CombinedController : ControllerBase { [Authorize(Policy = "WebApp")] [HttpGet(nameof(AppMethod))] public async Task<IActionResult> AppMethod() { // 仅通过Azure AD登录的用户可进入此方法 return Ok("Web App用户访问成功"); } [Authorize(Policy = "WebApi")] [HttpPost(nameof(ApiMethod))] public async Task<IActionResult> ApiMethod() { // 仅携带有效Bearer Token的请求可进入此方法 return Ok("API调用成功"); } }
额外注意事项
- Azure AD应用注册需分别配置正确:Web App注册要设置匹配的重定向URI(对应
CallbackPath);Web API注册要暴露API范围,并允许对应客户端应用获取访问令牌。 - 如果Web App需要调用自身的API接口,可调整
TokenAcquisition配置,让Web App登录后自动获取内部API的访问令牌。 - 测试时:Web App场景直接用浏览器访问,会自动跳转到Azure AD登录页;API场景用Postman等工具,在请求头中添加
Authorization: Bearer <你的有效令牌>即可。
备注:内容来源于stack exchange,提问作者Serhat
相关产品推荐
相关产品推荐

