Identity Server 4 API无法授权自身端点,请求时跳转登录页问题求助
根因分析
- 中间件顺序错误
ASP.NET Core要求身份认证中间件必须在授权中间件之前执行,当前配置中UseAuthorization调用早于UseIdentityServer和UseAuthentication,请求还未解析Token就触发授权校验,无法识别用户身份,进而触发默认Cookie认证的跳转逻辑。 - 认证配置冲突
AddLocalApiAuthentication()是IdentityServer专门为自身API提供的官方认证方案配置,额外手动添加的AddJwtBearer配置冗余,且会和Identity自带的Cookie认证、本地API认证方案冲突,导致认证逻辑混乱。 - 授权特性未指定正确认证方案
IS4服务同时集成了面向页面的Cookie认证和面向API的Bearer认证,未指定方案时[Authorize]默认走Cookie认证流程,携带Bearer token的请求会被判定为未登录,触发登录页跳转。
修复步骤
- 修正中间件执行顺序,调整
Configure方法代码如下:
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { app.UseExceptionHandler(builder => { builder.Run(async context => { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); var error = context.Features.Get<IExceptionHandlerFeature>(); if (error != null) { context.Response.AddApplicationError(error.Error.Message); await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false); } }); }); app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.None }); app.UseStaticFiles(); app.UseCors("AllowAll"); app.UseIdentityServer(); app.UseAuthentication(); app.UseAuthorization(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
- 删除
ConfigureServices中冗余的自定义JWT配置,即移除以下代码段:
services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.RequireHttpsMetadata = false; options.Authority = "http://localhost:5000"; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false }; });
- 给API端点的
[Authorize]特性指定正确的认证方案:
// 所有登录用户可访问 [Authorize(AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme)] [HttpGet] [Route("api/[controller]/debug")] public async Task<IActionResult> DebugEndpoint() { return Ok("debug ok"); } // 仅Admin角色用户可访问 [Authorize("Admin", AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme)] [HttpGet] [Route("api/[controller]/admin-debug")] public async Task<IActionResult> AdminDebugEndpoint() { return Ok("admin debug ok"); }
- 补充本地API资源配置,在
Config.GetApiResources()中添加本地API资源:
public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { // 原有业务API资源保留不变 new ApiResource(IdentityServerConstants.LocalApi.ScopeName) }; }
注意事项
需确认IdentityClaimsProfileService已将角色Claim正确写入JWT返回内容,否则角色校验会失败。
内容的提问来源于stack exchange,提问作者Grumbunks
相关产品推荐
相关产品推荐

