.NET Core JWT无权限问题解决方案

一、问题描述

最近,有一位刚入行的小白开发者遇到了一个问题:在使用.NET Core开发时,使用JWT(JSON Web Token)进行身份验证,但一直提示无权限。作为经验丰富的开发者,我将向他解释整个问题的解决流程,并提供每一步需要做的事情和相应的代码。下面是解决问题的步骤:

步骤 说明
1 确保JWT的配置正确
2 实现认证和授权
3 生成和验证JWT
4 添加JWT到HTTP头部
5 保护API资源

二、JWT配置

在项目的appsettings.json文件中,我们需要添加一个JWT配置部分,用于指定令牌的发行人、密钥和有效期等信息。下面是一个示例:

"JwtSettings": {
  "Issuer": "YourIssuer",
  "Audience": "YourAudience",
  "SecretKey": "YourSecretKey",
  "ExpirationDays": 30
}

三、认证和授权

在Startup.cs文件的ConfigureServices方法中,需要添加JWT的认证和授权服务。具体代码如下:

// 配置认证服务
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["JwtSettings:Issuer"],
            ValidAudience = Configuration["JwtSettings:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSettings:SecretKey"]))
        };
    });

// 配置授权服务
services.AddAuthorization(options =>
{
    options.AddPolicy("YourPolicyName", policy =>
    {
        policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
        policy.RequireAuthenticatedUser();
        // 添加其他授权要求
    });
});

以上代码中,我们通过AddAuthentication方法添加了JWT的认证服务,并通过AddJwtBearer方法配置了JWT的验证参数。在AddAuthorization方法中,我们添加了授权策略,其中包括了JWT的认证方案和要求用户进行身份验证。

四、生成和验证JWT

在登录或认证成功后,我们需要生成JWT,并将其返回给客户端。下面是生成和验证JWT的代码示例:

// 生成JWT
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "YourUserName"),
    // 添加其他声明
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSettings:SecretKey"]));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
    Configuration["JwtSettings:Issuer"],
    Configuration["JwtSettings:Audience"],
    claims,
    expires: DateTime.Now.AddDays(Convert.ToDouble(Configuration["JwtSettings:ExpirationDays"])),
    signingCredentials: credentials
);

var encodedToken = new JwtSecurityTokenHandler().WriteToken(token);

// 验证JWT
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
    ValidateIssuerSigningKey = true,
    ValidateIssuer = true,
    ValidateAudience = true,
    ValidIssuer = Configuration["JwtSettings:Issuer"],
    ValidAudience = Configuration["JwtSettings:Audience"],
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSettings:SecretKey"]))
};

ClaimsPrincipal claimsPrincipal;
try
{
    claimsPrincipal = tokenHandler.ValidateToken(encodedToken, validationParameters, out _);
}
catch (Exception ex)
{
    // 验证失败,处理异常
}

以上代码中,我们使用JwtSecurityToken类生成JWT,并使用JwtSecurityTokenHandler类的WriteToken方法将其编码为字符串。在验证JWT时,我们使用JwtSecurityTokenHandler类的ValidateToken方法进行验证,并指定相应的验证参数。

五、添加JWT到HTTP头部

在API接口中,我们需要将JWT添加到HTTP头部,以便在请求时进行验证和授权。下面是在Controller中添加JWT到HTTP头部的代码示例:

[Authorize("YourPolicyName")]
public class YourController : ControllerBase
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        var jwt = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
        // 使用jwt进行相应的验证和授权
        return "Success";
    }
}

以上代码中,我们使用Authorize属性指定了