JWT

1、解析

1)客户端向授权服务系统发起请求,申请获取“令牌”。

2)授权服务根据用户身份,生成一张专属“令牌”,并将该“令牌”以JWT规范返回给客户端

3)客户端将获取到的“令牌”放到http请求的headers中后,向主服务系统发起请求。主服务系统收到请求后会从headers中获取“令牌”,并从“令牌”中解析出该用户的身份权限,然后做出相应的处理(同意或拒绝返回资源)

2、配置JWT

1、添加NuGet包Microsoft.AspNetCore.Authentication.JwtBearer

2、在appsettings.json中添加JWT配置节点

   "JWT": {
    "SecKey": "Jamin1127!#@$%@%^^&*(~Czmjklneafguvioszb%yuv&*6WVDf5dw#5dfw6f5w6faW%FW^f5wa65f^AWf56", //密钥
    "Issuer": "Jamin",  //发行者
    "ExpireSeconds": 7200 //过期时间
  }

3、在Program类里进行服务注册

#region JWT服务
// 注册JWT服务
builder.Services.AddSingleton(new JwtHelper(builder.Configuration));
builder.Services.AddAuthentication( JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true, //是否验证Issuer
        ValidIssuer = builder.Configuration["Jwt:Issuer"], //发行人Issuer
        ValidateAudience = false, //是否验证Audience      
        ValidateIssuerSigningKey = true, //是否验证SecurityKey
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecKey"])), //SecurityKey
        ValidateLifetime = true, //是否验证失效时间
        ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
        RequireExpirationTime = true,
    };
}
);
#endregion
//swagger里添加JWT授权
    builder.Services.AddSwaggerGen(c=> {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web API", Version = "v1" });
    //开启注释
    var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath, true);
    // 配置 JWT Bearer 授权
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer"
    });
    var securityScheme = new OpenApiSecurityScheme
    {
        Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
    };
    var securityRequirement = new OpenApiSecurityRequirement { { securityScheme, new string[] { } } };
    c.AddSecurityRequirement(securityRequirement);
});
//启用验证中间件
app.UseAuthentication();
app.UseAuthorization();

4、创建JWT类进行Token配置

using Microsoft.IdentityModel.Tokens;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Blog.core.Common.Auth
{
    /// <summary>
    /// 授权JWT类
    /// </summary>
    public class JwtHelper
    {
        private readonly IConfiguration _configuration;
        /// <summary>
        /// Token配置
        /// </summary>
        /// <param name="configuration"></param>
        public JwtHelper(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        /// <summary>
        /// 创建Token 这里面可以保存自己想要的信息
        /// </summary>
        /// <param name="username"></param>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public string CreateToken(string username, string mobile)
        {
            try
            {
                // 1. 定义需要使用到的Claims
                var claims = new[]
                {
                    new Claim("username", username),
                    new Claim("mobile", mobile),
                    /* 可以保存自己想要信息,传参进来即可
                    new Claim("sex", "sex"),
                    new Claim("limit", "limit"),
                    new Claim("head_url", "xxxxx")
                    */
                };
                // 2. 从 appsettings.json 中读取SecretKey
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                // 3. 选择加密算法
                var algorithm = SecurityAlgorithms.HmacSha256;
                // 4. 生成Credentials
                var signingCredentials = new SigningCredentials(secretKey, algorithm);
                // 5. 根据以上,生成token
                var jwtSecurityToken = new JwtSecurityToken(
                    _configuration["Jwt:Issuer"],    //Issuer
                    _configuration["Jwt:ExpireSeconds"],  //ExpireSeconds
                    claims,                          //Claims,
                    DateTime.Now,                    //notBefore
                    DateTime.Now.AddSeconds(30),     //expires
                    signingCredentials               //Credentials
                );
                // 6. 将token变为string
                var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
                return token;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 获取信息
        /// </summary>
        /// <param name="jwt"></param>
        /// <returns></returns>
        public static string ReaderToken(string jwt)
        {
            var str = string.Empty;
            try
            {
                //获取Token的三种方式
                //第一种直接用JwtSecurityTokenHandler提供的read方法
                var jwtHander = new JwtSecurityTokenHandler();
                JwtSecurityToken jwtSecurityToken = jwtHander.ReadJwtToken(jwt);
                str = jwtSecurityToken.ToString();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return str;
        }
        /// <summary>
        /// 解密jwt
        /// </summary>
        /// <param name="jwt"></param>
        /// <returns></returns>
        public string JwtDecrypt(string jwt)
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                JwtSecurityTokenHandler tokenHandler = new();
                TokenValidationParameters valParam = new();
                var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                valParam.IssuerSigningKey = securityKey;
                valParam.ValidateIssuer = false;
                valParam.ValidateAudience = false;
                //解密
                ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,
                        valParam, out SecurityToken secToken);
                foreach (var claim in claimsPrincipal.Claims)
                {
                    sb.Append($"{claim.Type}={claim.Value}");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return sb.ToString();
        }
    }
}

5、创建用户实体,进行用户密码的接收

using System.ComponentModel.DataAnnotations;
namespace Blog.core.Models
{
    public class UserInfo
    {
        /// <summary>
        /// 其中 [Required] 表示非空判断,其他自己研究百度
        /// </summary>
        [Required]
        public string UserName { get; set; }
        [Required]
        public string Password { get; set; }
        [Required]
        public string PhoneNumber { get; set; }
}
}

6、创建控制器,进行JWT的APi调用

using Blog.core.Common.Auth;
using Blog.core.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Blog.core.Controllers
{
        [Route("[controller]/[action]")]
        [ApiController]
        public class UserController : ControllerBase
        {
            private readonly JwtHelper _jwt;
            /// <summary>
            /// 初始化
            /// </summary>
            /// <param name="jwtHelper"></param>
            public UserController(JwtHelper jwtHelper)
            {
                _jwt = jwtHelper;
            }
            /// <summary>
            /// 获取Token
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public IActionResult GetToken(UserInfo user)
            {
                //参数验证等等....
                if (string.IsNullOrEmpty(user.UserName))
                {
                    return Ok("参数异常!");
                }
                //这里可以连接mysql数据库做账号密码验证
                //这里可以做Redis缓存验证等等
                //这里获取Token,当然,这里也可以选择传结构体过去
                var token = _jwt.CreateToken(user.UserName, user.PhoneNumber);
                  //解密后的Token
                  var PWToken = _jwt.JwtDecrypt( token);
                  return Ok(token+"解密后:"+PWToken);
            }
            /// <summary>
            /// 获取自己的详细信息,其中 [Authorize] 就表示要带Token才行
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            [Authorize]
            public IActionResult GetSelfInfo()
            {
                //执行到这里,就表示已经验证授权通过了
                /*
                 * 这里返回个人信息有两种方式
                 * 第一种:从Header中的Token信息反向解析出用户账号,再从数据库中查找返回
                 * 第二种:从Header中的Token信息反向解析出用户账号信息直接返回,当然,在前面创建        Token时,要保存进使用到的Claims中。
                */
                return Ok("授权通过了!");
            }
        }  
}

在这里插入图片描述

注:获取Token后在Swagger上输入token的value就可以进行接口的调用了

在这里插入图片描述

到此这篇关于ASP.NET中 Swagger添加JWT验证的流程的文章就介绍到这了,更多相关Swagger添加JWT验证内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部