一、前言

在上一篇《.NET Core WebAPI 认证授权之JWT(一):JWT介绍》中讲到了JWT的组成,分为三部分,其中标头(header)和载荷(payload)都只是简单的将json内容进行base64编码,而签名部分就要复杂一点,通常会使用HmacSha256或RsaSha256算法进行签名。关于两种算法在上一篇中也有简单的介绍,本文就不多做介绍,直接进行实操落地。本文先介绍使用HmacSHA256算法签名的JWT。开发环境:

VisualStudio 2019 16.8.3

ASP.NET Core 5.0  

二、生成Token

生成签名的算法虽然复杂,但好在.NET有内置的API来生成相应算法的JWT。

1.创建一个用于颁发Token项目,当然也可以将颁发Token步骤合并到API项目中。

.NET Core WebAPI 认证授权之JWT(二):HMAC算法实操_java

2.引入Nuget包Microsoft.AspNetCore.Authentication.JwtBearer(APS.NET Core 5.0 WebAPI项目模板如果勾选Enable OpenAPI会自带这个包),生成Token主要用到了这个包关联的Microsoft.IdentityModel.TokensSystem.IdentityModel.Tokens.Jwt两个t程序集。

.NET Core WebAPI 认证授权之JWT(二):HMAC算法实操_java_02

3.在AuthenticationController中创建一个登录接口,验证用户的账号密码。

public string Login([FromForm] string userName, [FromForm] string password)
{
    //验证账号密码
    if (userName == password) 
    {
        //返回JWT
        return "";
    }
    else
    {
        //返回账号密码错误
        return "";
    }
}

4.验证账号密码正确后,生成JWT。

if (userName == password) //验证账号密码
{
    #region 生成Token
    var claims = new[] {
        new Claim(ClaimTypes.Name, userName)
    };
    
    //密钥 网上随便生成的 建议写配置文件中
    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB")); 
    //定义签名的密钥、算法
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 
    //创建Token
    var token = new JwtSecurityToken(issuer: "leo96.com",   //发布者 随便写 可用于验证 建议写配置文件中
                                    audience: "leo96.com",  //受众 随便写 可用于验证 建议写配置文件中
                                    claims: claims, //声明 存储其他信息
                                    expires: DateTime.Now.AddMinutes(5), //过期时间 可写配置文件中
                                    signingCredentials: creds); //凭证
    //写入Token
    string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
    #endregion

    return returnToken;
}
这是.NET自带的生成JWT的API,此处使用的是HmacSha256算法,其中需要的Key是从网上找的,貌似随便填什么也可以,但是好像不能小于32个字节?(此处不太清楚)

三、Token认证和授权

1.创建API项目,引入Nuget包Microsoft.AspNetCore.Authentication.JwtBearer(APS.NET Core 5.0 WebAPI项目模板如果勾选Enable OpenAPI会自带这个包)。

2.添加JWT认证服务和中间件。

#region 添加JWT认证服务
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,  //是否验证Issuer
            ValidateAudience = true,    //是否验证Audience
            ValidateLifetime = true,    //是否验证有效时间
            ValidateIssuerSigningKey = true,    //是否验证key
            ValidIssuer = "leo96.com", //建议配置文件读取
            ValidAudience = "leo96.com", //建议配置文件读取
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB")) //建议配置文件读取
        };
    });
#endregion
#region 认证中间件
app.UseAuthentication();
#endregion

注意:开启了这些验证后,这里的Issuer、Audience、SecurityKey等需要和之前生成Token时候所使用的相关信息一致

3.添加授权中间件

#region 授权中间件
app.UseAuthorization();
#endregion

PS:WebAPI项目模板默认自带授权中间件。

4.权限拦截

.NET Core WebAPI 认证授权之JWT(二):HMAC算法实操_java_03

使用Authorize特性标注在Controllor或Action上后,访问相应接口就需要JWT验证,验证不通过,就会返回401状态码。

四、使用

同时运行两个程序,我们先请求Login接口,拿到Token,然后请求API带保护的资源时,在请求标头中带上Token,即可。(详见上篇《.NET Core WebAPI 认证授权之JWT(一):JWT介绍》