JWT

举报
步步为营 发表于 2023/03/02 11:17:56 2023/03/02
【摘要】 nuget安装`Microsoft.AspNetCore.Authentication.JwtBearer`

JWT

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

模拟用户登陆

  1. nuget安装Microsoft.AspNetCore.Authentication.JwtBearer

  2. [HttpPost("login")]
    [AllowAnonymous] //不用登陆就可以访问,因为是登陆页
    public IActionResult login([FromBody] LoginDto loginDto)
    {
        //1验证用户名密码
          ...
        //2创建JWT
        //2.1header
        var signingAlgorithm = SecurityAlgorithms.HmacSha256;//定义算法
                                                             //2.2payload
        var claims = new[] { 
            //sub用户id
            new Claim(JwtRegisteredClaimNames.Sub,"fake_user_id"),
       	 	};	
        //2.3signiture
        var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);//将私钥转换成UTF8的字节形式
        var signingKey = new SymmetricSecurityKey(secretByte); //先使用非对称算法对私钥进行加密
        var signingCredentials = new SigningCredentials(signingKey, signingAlgorithm);//再使用HmacSha256来加密一下非对称加密后的私钥
        var token = new JwtSecurityToken(
            issuer: _configuration["Authentication:Issuer"], //谁发布的token
            audience: _configuration["Authentication:Audience"], //token发布给谁
            claims,
            notBefore: DateTime.UtcNow,//发布时间
            expires: DateTime.UtcNow.AddDays(1),//有效期,1天有效
            signingCredentials//数字签名
            );
        var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);//将token转换成字符串
        //3返回jwt
        return Ok(tokenStr);
    }
    
    

    启用授权

    1. program
    //注册身份认证服务。参数,默认身份认证类型
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(opt =>//配置jwt认证
        {
            var secretByte = Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]);
            opt.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateIssuer = true,//验证发布者
                ValidIssuer = builder.Configuration["Authentication:Issuer"],
    
                ValidateAudience = true,//验证持有者
                ValidAudience = builder.Configuration["Authentication:Audience"],
    
                ValidateLifetime = true,//验证是否过期
                //将私钥从配置传入进来进行非对称加密
                IssuerSigningKey = new SymmetricSecurityKey(secretByte)
            };
        });
    ...
    app.UseAuthentication();
    app.UseAuthorization();
    app.Run();
    
    1. 在需要授权的操作方法上增加[Authorize]

用户角色权限

claim

  • 表述用户的身份,说明用户的角色、表示用户所具有的的权限
  • 最小不可分割的单位,使用的灵活度高,可以自由组合
  1. 创建角色
var claims = new[] { 
                //sub用户id
                new Claim(JwtRegisteredClaimNames.Sub,"fake_user_id"),
                new Claim(ClaimTypes.Role,"Admin")//添加管理员角色
            };
  1. 启用授权在需要管理员授权的操作方法上增加[Authorize(Roles ="Admin")]

用户模型与数据库

  1. nuget安装Microsoft.AspNetCore.Identity.EntityFrameworkCore
  2. Program中增加builder.Services.AddIdentity<IdentityUser,IdentityRole>().AddEntityFrameworkStores<AppDbContext>();
  3. 数据库context继承IdentityDbContext,public class AppDbContext:IdentityDbContext<IdentityUser>

用户登陆

  1. private readonly IConfiguration _configuration;
    private readonly UserManager<IdentityUser> _userManager;
    private readonly SignInManager<IdentityUser> _signInManager;
    public AuthenticateController(IConfiguration configuration, UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
    { _configuration = configuration;
        _userManager = userManager;
        _signInManager = signInManager;
    }
    [HttpPost("login")]
    [AllowAnonymous]
    public async Task< IActionResult> login([FromBody] LoginDto loginDto)
    {
        //1验证用户名密码
        var loginResult = await _signInManager.PasswordSignInAsync(
                loginDto.Email,
                loginDto.Password,
                false,
                false
            );
        if (!loginResult.Succeeded)
        {
            return BadRequest();
        }
        var user = await _userManager.FindByNameAsync(loginDto.Email);
        var roleNames = await _userManager.GetRolesAsync(user);
        //2创建JWT
        //2.1header
        var signingAlgorithm = SecurityAlgorithms.HmacSha256;//定义算法
                                                             //2.2payload
        var claims = new List<Claim> { 
            //sub用户id
            new Claim(JwtRegisteredClaimNames.Sub,user.Id),
        };
        foreach (var roleName in roleNames)
        {
            var roleClaim = new Claim(ClaimTypes.Role, roleName);
            claims.Add(roleClaim);
        }
        //2.3signiture
        var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);//将私钥转换成UTF8的字节形式
        var signingKey = new SymmetricSecurityKey(secretByte); //先使用非对称算法对私钥进行加密
        var signingCredentials = new SigningCredentials(signingKey, signingAlgorithm);//再使用HmacSha256来验证一下非对称加密后的私钥
        var token = new JwtSecurityToken(
            issuer: _configuration["Authentication:Issuer"], //谁发布的token
            audience: _configuration["Authentication:Audience"], //token发布给谁
            claims,
            notBefore: DateTime.UtcNow,//发布时间
            expires: DateTime.UtcNow.AddDays(1),//有效期,1天有效
            signingCredentials//数字签名
            );
        var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);//将token转换成字符串
        //3返回jwt
        return Ok(tokenStr);
    }
    
    
  2. 操作方法增加[Authorize(AuthenticationSchemes ="Bearer")] //identity多角色验证时必须指定

定制用户模型并添加初始化用户数据

  1. 自定义类
public class ApplictionUser:IdentityUser
{
    public string? Address { set; get; }
    public virtual ICollection<IdentityUserRole<string>> UserRoles { get; set; }
}

  1. 在context中
// 初始化用户与角色的种子数据
// 1. 更新用户与角色的外键关系
modelBuilder.Entity<ApplictionUser>(b => {
    b.HasMany(x => x.UserRoles)
    .WithOne()
    .HasForeignKey(ur => ur.UserId)
    .IsRequired();
});
// 2. 添加角色
var adminRoleId = "308660dc-ae51-480f-824d-7dca6714c3e2"; // guid 
modelBuilder.Entity<IdentityRole>().HasData(
    new IdentityRole
    {
        Id = adminRoleId,
        Name = "Admin",
        NormalizedName = "Admin".ToUpper()
    }
);
// 3. 添加用户
var adminUserId = "90184155-dee0-40c9-bb1e-b5ed07afc04e";
ApplictionUser adminUser = new ApplictionUser
{
    Id = adminUserId,
    UserName = "admin@fakexiecheng.com",
    NormalizedUserName = "admin@fakexiecheng.com".ToUpper(),
    Email = "admin@fakexiecheng.com",
    NormalizedEmail = "admin@fakexiecheng.com".ToUpper(),
    TwoFactorEnabled = false,
    EmailConfirmed = true,
    PhoneNumber = "123456789",
    PhoneNumberConfirmed = false
};
PasswordHasher<ApplictionUser> ph = new PasswordHasher<ApplictionUser>();
adminUser.PasswordHash = ph.HashPassword(adminUser, "Fake123$");
modelBuilder.Entity<ApplictionUser>().HasData(adminUser);
// 4. 给用户加入管理员权限
// 通过使用 linking table:IdentityUserRole
modelBuilder.Entity<IdentityUserRole<string>>()
    .HasData(new IdentityUserRole<string>()
    {
        RoleId = adminRoleId,
        UserId = adminUserId
    });
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。