netCore WebAPI基础4

netCore WebAPI基础4

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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30



    ## 启用授权

    1. program

    ```csharp
    //注册身份认证服务。参数,默认身份认证类型
    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();
    2. 在需要授权的操作方法上增加`[Authorize]`

用户角色权限

claim

  • 表述用户的身份,说明用户的角色、表示用户所具有的的权限
  • 最小不可分割的单位,使用的灵活度高,可以自由组合
  1. 创建角色
1
2
3
4
5
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);
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    2. 操作方法增加`[Authorize(AuthenticationSchemes ="Bearer")]` //identity多角色验证时必须指定

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

    1. 自定义类

    ```csharp
    public class ApplictionUser:IdentityUser
    {
    public string? Address { set; get; }
    public virtual ICollection<IdentityUserRole<string>> UserRoles { get; set; }
    }

  2. 在context中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 初始化用户与角色的种子数据
// 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
});
作者

步步为营

发布于

2024-06-02

更新于

2025-03-15

许可协议