在ASP.NET 6默认Identity页面中额外添加Basic身份验证处理程序的问题咨询
ASP.NET 6 多认证方案共存(Identity + Basic认证)问题解决
核心逻辑说明
你的实现思路没有问题,AddScheme注册方式也正确,所有问题都是Identity默认多方案适配配置缺失导致的,手动检测Basic头的中间件思路完全可行。
问题逐一解决
1. Basic验证方案出现在外部登录提供程序列表
Identity默认会把所有注册时设置了DisplayName的认证方案识别为外部登录提供方,注册时显式将DisplayName设为null即可隐藏:
// 不要给AddAuthentication传自定义scheme参数,保留Identity默认的cookie主方案 builder.Services.AddAuthentication() // 若你的Handler继承自AuthenticationHandler<TOptions>,TOptions无自定义则用AuthenticationSchemeOptions .AddScheme<AuthenticationSchemeOptions, MyBasicHandler>("myScheme", options => { options.DisplayName = null; // 关键配置,隐藏外部登录列表展示 });
2. 触发Basic验证时跳转登录页无响应
Identity默认未授权请求会跳转至cookie登录页,需要在你的MyBasicHandler中重写质询逻辑,返回Basic认证要求的401响应而非跳转:
// 在MyBasicHandler类中添加以下重写方法 protected override Task HandleChallengeAsync(AuthenticationProperties properties) { Context.Response.StatusCode = StatusCodes.Status401Unauthorized; Context.Response.Headers.WWWAuthenticate = "Basic realm=\"你的站点标识\""; return Task.CompletedTask; }
3. Basic头被忽略、处理程序未调用
默认只会执行全局默认认证方案(Identity cookie),不会主动触发未加入策略的自定义方案,两种实现可选:
方案A:全局授权策略加入Basic方案(无侵入式)
所有请求会依次尝试Basic认证、cookie认证,任意一个通过即可:
builder.Services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .AddAuthenticationSchemes("myScheme", IdentityConstants.ApplicationScheme) .RequireAuthenticatedUser() .Build(); });
方案B:自定义中间件检测Basic头(你猜测的思路)
仅携带Basic头的请求触发自定义认证,不影响普通页面请求逻辑,中间件要放在UseAuthentication之前注册:
// 检测到Authorization头时优先尝试Basic认证 app.UseWhen(context => context.Request.Headers.ContainsKey("Authorization"), appBuilder => { appBuilder.Use(async (context, next) => { var authHeader = context.Request.Headers.Authorization.ToString(); if (authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) { var authResult = await context.AuthenticateAsync("myScheme"); if (authResult.Succeeded) { context.User = authResult.Principal; } } await next(); }); }); // 原有认证、授权中间件顺序不变 app.UseAuthentication(); app.UseAuthorization();
内容的提问来源于stack exchange,提问作者HCL
相关产品推荐
相关产品推荐

