Identity标识框架配上JWT的使用

在Identity标识框架的代码上继续编写

.Net中的标识框架Identity_风的艺术的博客-CSDN博客

添加NuGet包

NugetMicrosoft.AspNetCore.Authentication.JwtBearer

创建存储JWT数据类

public class JWTOptions

{

    public string SigningKey { get; set; }

    public int ExpireSeconds { get; set; }

}

在appsettings.json上设置你的对称密钥

"JWT": {

  "SigningKey": "fasdfad&9045dafz222#fadpio@0232",

  "ExpireSeconds": "86400"

}

配置JWT

//从配置文件中获取JWT数据

builder.Services.Configure(builder.Configuration.GetSection("JWT"));

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

.AddJwtBearer(x =>

{

    //将配置文件的JWT数据转换为JWToptions这个类

    var jwtOpt = builder.Configuration.GetSection("JWT").Get();

    //创建对称安全密钥

    byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt.SigningKey);

    var secKey = new SymmetricSecurityKey(keyBytes);

    //令牌验证参数配置

    x.TokenValidationParameters = new()

    {

        ValidateIssuer = false,

        ValidateAudience = false,

        ValidateLifetime = true,

        ValidateIssuerSigningKey = true,

        IssuerSigningKey = secKey

    };

});

创建一个方法用来生成token令牌

private static string BuildToken(IEnumerable claims, JWTOptions options)

{

    DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds);

    byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey);

    var secKey = new SymmetricSecurityKey(keyBytes);//获取对称安全密钥

    var credentials = new SigningCredentials(secKey,

        SecurityAlgorithms.HmacSha256Signature);//令牌的加密方式

    var tokenDescriptor = new JwtSecurityToken(expires: expires,

        signingCredentials: credentials, claims: claims);//完成令牌的制作

    return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);//返回令牌数据

}

创建一个新的登录,登录成功后生成一个令牌发送给客户端

[HttpPost]

public async Task Login2(LoginRequest req,

            [FromServices] IOptions jwtOptions)

{

    string userName = req.UserName;

    string password = req.Password;

    var user = await userManager.FindByNameAsync(userName);

    if (user == null)

    {

        return NotFound($"用户名不存在{userName}");

    }

    var success = await userManager.CheckPasswordAsync(user, password);

    if (!success)

    {

        return BadRequest("Failed");

    }

    var claims = new List();

    claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));

    claims.Add(new Claim(ClaimTypes.Name, user.UserName));

    var roles = await userManager.GetRolesAsync(user);

    foreach (string role in roles)

    {

        claims.Add(new Claim(ClaimTypes.Role, role));

    }

    //登录成功后生成令牌,将令牌发送给客户端

    string jwtToken = BuildToken(claims, jwtOptions.Value);

    return Ok(jwtToken);

}

验证是否登录成功,如果没用登录成功不能访问该Action

[Authorize]验证Token是否合理

[HttpGet]

[Authorize]

public IActionResult Hello()

{

    string id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;

    string userName = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;

    IEnumerable roleClaims = this.User.FindAll(ClaimTypes.Role);

    string roleNames = string.Join(',', roleClaims.Select(c => c.Value));

    return Ok($"id={id},userName={userName},roleNames ={roleNames}");

}

执行Login2获取令牌数据

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoieXprIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW4iLCJleHAiOjE2ODE5OTIyNDV9.jtbuWZEUFeh_pTKyrIvAlUyL50mKQeTQX_cTMrP0m34

使用Postman访问Hello

在请求头中添加一个键值。将令牌放置Value这边。Value的Bearer后面要有一个空格之后将令牌粘贴上去,令牌复制时不能有空格换行,否则会报错401

Identity标识框架配上JWT的使用_第1张图片

[Authorize]的注意事项

  • ASP.NET Core中身份验证和授权验证的功能由Authentication、Authorization中间件提供app.UseAuthentication()、app.UseAuthorization() 。
  • 控制器类上标注[Authorize],则所有操作方法都会被进行身份验证和授权验证;对于标注了[Authorize]的控制器中,如果其中某个操作方法不想被验证,可以在操作方法上添加[AllowAnonymous]。
  • ASP.NET Core会按照HTTP协议的规范,从Authorization取出来令牌,并且进行校验、解析,然后把解析结果填充到User属性中,这一切都是ASP.NET Core完成的,不需要开发人员自己编写代码。但是一旦出现401,没有详细的报错信息,很难排查,这是初学者遇到的难题。
  • 可以在[Authorize]特性后面补充参数例如只能允许指定角色访问该Action,其他角色访问该Action会出现403报错

[Authorize(Role="admin")]

你可能感兴趣的:(ASP.Net,MVC,.net,core)