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

ASP.NET Core自定义授权处理器未触发,请求返回403问题排查

问题分析与修复方案

你遇到的核心问题是全局授权中间件无法获取资源,导致资源授权处理器根本不会被触发,具体原因和修复步骤如下:

核心问题

控制器方法上的[Authorize(Policy = "SameUser")]会在请求进入控制器之前,由全局UseAuthorization中间件执行授权检查。但此时你还没有加载Trip资源(这一步是在控制器方法内部的GetByIdAsync才做的),所以你的TripAuthorizationHandler(需要Trip资源的处理器)无法被调用,直接返回403,甚至不会进入控制器方法内的代码。

修复步骤

1. 移除控制器上的全局策略授权

删掉[Authorize(Policy = "SameUser")],只保留[Authorize]确保用户已完成认证:

[Authorize]
[HttpPut("trips/{tripId}")]
public async Task<IActionResult> UpdateTrip([FromBody] TripPostDto request, int tripId)
{
    var trip = await _tripService.GetByIdAsync(tripId);
    if (trip == null)
    {
        return NotFound();
    }

    var authorizationResult = await _authorizationService.AuthorizeAsync(User, trip, "SameUser");

    if (authorizationResult.Succeeded)
    {
        await _tripService.UpdateAsync(tripId, request);
        return NoContent();
    }
    else if (User.Identity.IsAuthenticated)
    {
        return Forbid();
    }
    else
    {
        return Challenge();
    }
}

2. 验证资源授权的关键细节

  • 检查JWT声明:确保Token中包含userId声明,且值的类型和Trip.ApplicationUserId一致(比如都是字符串,避免int与字符串直接比较导致不相等)。
  • 确认Trip资源有效性:GetByIdAsync必须返回有效的Trip实例,如果返回null,后续授权检查也会失败。
  • 处理器注册验证:你的Program.cs中已经正确注册了TripAuthorizationHandler,这部分无需修改:
    builder.Services.AddTransient<IAuthorizationHandler, TripAuthorizationHandler>();
    

3. 额外验证点

确保TokenService生成JWT时正确添加了userId声明,示例代码如下:

public async Task<AccessTokenDto> GetTokenAsync(ApplicationUser user)
{
    var claims = new List<Claim>
    {
        new Claim("userId", user.Id.ToString()),
        // 其他必要声明(如角色、邮箱等)
    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Key"]));
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: _configuration["JWT:Issuer"],
        audience: _configuration["JWT:Audience"],
        claims: claims,
        expires: DateTime.Now.AddHours(1),
        signingCredentials: creds);

    return new AccessTokenDto
    {
        AccessToken = new JwtSecurityTokenHandler().WriteToken(token)
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:10:45