自定义IAuthorizationFilter重定向登录报错:无Cookies认证处理器
使用默认AuthorizeAttribute时,未认证用户能正常重定向到登录页,但自定义实现IAuthorizationFilter的Attribute时,设置context.Result = new ChallengeResult(CookieAuthenticationDefaults.AuthenticationScheme)会报错:
InvalidOperationException: No authentication handler is registered for the scheme 'Cookies'. The registered schemes are: Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId, Bearer, Google, Facebook. Did you forget to call AddAuthentication().AddSomeAuthHandler?
以下是针对该问题的几种替代解决方法(无需额外添加AddCookie配置):
方法1:使用Identity的Cookie方案名
你的配置依赖的是Identity框架的Cookie认证,它的默认方案名不是CookieAuthenticationDefaults.AuthenticationScheme(即"Cookies"),而是IdentityConstants.ApplicationScheme。直接替换scheme名称即可:
context.Result = new ChallengeResult(IdentityConstants.ApplicationScheme);
ConfigureApplicationCookie本质是配置Identity.Application这个scheme的处理程序,使用这个名称就能找到对应的认证处理器,触发你配置好的登录页重定向逻辑。
方法2:使用默认挑战方案(无需硬编码)
如果不想硬编码scheme名称,可以通过IAuthenticationSchemeProvider获取系统配置的默认挑战方案,适配性更强:
- 在自定义Filter中注入
IAuthenticationSchemeProvider:
public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter { private readonly IAuthenticationSchemeProvider _schemeProvider; public CustomAuthorizeAttribute(IAuthenticationSchemeProvider schemeProvider) { _schemeProvider = schemeProvider; } public async void OnAuthorization(AuthorizationFilterContext context) { if (!context.HttpContext.User.Identity.IsAuthenticated) { var defaultScheme = await _schemeProvider.GetDefaultChallengeSchemeAsync(); context.Result = new ChallengeResult(defaultScheme?.Name); } } }
- 在控制器或Action上通过
TypeFilter使用该Attribute(确保依赖注入生效):
[TypeFilter(typeof(CustomAuthorizeAttribute))] public IActionResult ProtectedAction() { // 业务逻辑 }
方法3:直接使用无参数的ChallengeResult
框架会自动调用配置的默认挑战方案,这也是默认AuthorizeAttribute的处理逻辑,无需手动指定scheme:
context.Result = new ChallengeResult();
此方式会自动触发你通过ConfigureApplicationCookie配置的Identity.Application方案流程,完成登录页重定向。
为什么默认AuthorizeAttribute能正常工作?
默认AuthorizeAttribute会委托AuthorizationMiddleware处理未认证请求,该中间件会自动使用系统配置的默认挑战方案——你通过ConfigureApplicationCookie已经将Identity.Application设为默认的Cookie挑战方案,因此它能正确找到对应的认证处理器完成重定向。
内容的提问来源于stack exchange,提问作者jstuardo

