You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net Core 2.0自定义授权返回401:认证成功但控制器未执行

问题根源:ClaimsIdentity未指定认证类型

我一眼就看出问题所在了——你在自定义认证Handler的HandleAuthenticateAsync方法里创建ClaimsIdentity时,没有传入认证类型参数!这会导致即使你返回了AuthenticateResult.Success,当前用户的身份依然会被判定为未认证,最终被[Authorize]特性拦截返回401。

为什么会这样?

ClaimsIdentity的IsAuthenticated属性有个关键规则:只有当你在构造它时传入了非空的认证类型(authenticationType),这个属性才会返回true。如果没传这个参数,哪怕你给Identity添加了Claim,它依然会被判定为未认证状态。而[Authorize]特性正是依赖这个属性来判断用户是否合法的,所以它会直接拒绝请求,根本不会走到控制器代码里。

修复方案

修改HandleAuthenticateAsync里创建ClaimsIdentity的代码,把Scheme.Name作为第二个参数传入:

protected override async Task<AuthenticateResult> HandleAuthenticateAsync() {
    string token = Request.Headers["Authorization"];
    if (string.IsNullOrEmpty(token)) return AuthenticateResult.Fail("Failing string");
    // Using external service to validate token and get user id
    int Id = GetUserId(token);
    return AuthenticateResult.Success(
        new AuthenticationTicket(
            new ClaimsPrincipal(
                // 这里添加Scheme.Name作为认证类型参数
                new ClaimsIdentity(
                    new List<Claim>() { new Claim(ClaimTypes.Sid, Id.ToString()) }, 
                    Scheme.Name)), 
        Scheme.Name));
}

额外验证点

你可以在调试时检查ClaimsPrincipal.Identity.IsAuthenticated的值:修复前它会是false,修复后就会变成true,此时[Authorize]特性就会允许请求进入控制器执行逻辑了。

内容的提问来源于stack exchange,提问作者Matheus Lacerda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:55:45