AspNetCore 2.0按路由配置JWT与OpenID Connect认证方案的问题
解决AspNetCore 2.0按路由配置JWT与OpenID认证方案的问题
这个场景我之前处理过,核心问题在于你当前依赖全局默认认证方案,导致两个认证体系冲突。要实现API用JWT、Hangfire Dashboard用OpenID的分离保护,需要给不同路由配置专属的认证/授权策略,而不是依赖全局默认值。下面是具体的分步解决方案:
1. 调整认证服务的全局配置
首先移除全局的DefaultAuthenticateScheme设置,让每个路由自己决定用哪个认证方案。同时确保Cookie、JWT、OpenID的注册逻辑清晰:
services .AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>() .AddSingleton<IConfigureOptions<OpenIdConnectOptions>, ConfigureOpenIdOptions>() .AddAuthentication(options => { var jwt = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = jwt; // 仅设置默认挑战方案,不全局强制认证方案 }) .AddJwtBearer() .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) .AddOpenIdConnect(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.SignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme; // 其他OpenID配置(如Authority、ClientId)由你的ConfigureOpenIdOptions处理 });
2. 定义分场景的授权策略
为API和Hangfire分别创建独立的授权策略,明确指定各自的认证方案:
services.AddAuthorization(options => { // API专属策略:仅接受JWT认证 options.AddPolicy("ApiJwtPolicy", policy => { policy.RequireAuthenticatedUser(); policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme); }); // Hangfire专属策略:仅接受OpenID登录后的Cookie认证 options.AddPolicy("HangfireOidcPolicy", policy => { policy.RequireAuthenticatedUser(); policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme); }); }); // 给所有API接口默认应用JWT策略 services.AddMvcCore(config => { var apiPolicy = options.GetPolicy("ApiJwtPolicy"); config.Filters.Add(new AuthorizeFilter(apiPolicy)); });
3. 给Hangfire Dashboard配置专属认证流程
单独为/hangfire路由配置认证、授权逻辑,确保未认证时跳转到OpenID登录,而非依赖全局逻辑:
app.Map(new PathString("/hangfire"), hangfireApp => { // 启用认证中间件(针对当前路由) hangfireApp.UseAuthentication(); // 应用Hangfire专属授权策略 hangfireApp.UseAuthorization(new AuthorizationOptions { DefaultPolicy = options.GetPolicy("HangfireOidcPolicy") }); // 处理未认证情况:触发OpenID登录流程 hangfireApp.Use(async (context, next) => { if (!context.User.Identity.IsAuthenticated) { await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme); return; } await next(); }); // 挂载你的Hangfire Dashboard中间件 hangfireApp.UseMiddleware<HangfireDashboardMiddleware>(...); });
为什么之前的配置会出问题?
- 当你设置
DefaultAuthenticateScheme = openId时,所有请求(包括API的JWT请求)都会尝试用OpenID的Cookie去认证,导致API无法正确解析JWT声明; - 当注释掉该设置时,全局默认用JWT认证,Hangfire的请求没有JWT Token,会触发默认的JWT挑战逻辑,而非跳转到OpenID登录页面,最终陷入循环。
通过上述配置,我们把认证逻辑按路由隔离:API接口强制用JWT,Hangfire路由强制用OpenID登录后的Cookie认证,两者互不干扰。
内容的提问来源于stack exchange,提问作者Jason Meckley
相关产品推荐
相关产品推荐

