Net6之Jwt认证+Bearer认证 2.0

net6,jwt,认证,bearer · 浏览次数 : 43

小编点评

**第二次博客的改变** * 简化了令牌模型类,密钥写入配置文件等部分。 * 使用 `SymmetricSecurityKey` 类的 `Key` 属性存储密钥,简化密钥管理。 * 使用 `JwtBearerEvents` 类定义认证失败和成功事件,更清晰地处理错误。 * 引入 `SwashBuckle.AspNetCore.Filters` 库中的 `SecurityRequirementsOperationFilter` 来设置安全性。 * 在 API 文档中添加了关于认证角色信息的 API 描述。 * 使用 `SecuritySchemeType.ApiKey` 定义了 JWT 的 API 凭证类型。

正文

以前接触过,写过博客,第二次再写有了新的体会。第一次博客:https://www.cnblogs.com/zhang-3/p/16184067.html

过程:

  1. 生成token令牌(钥匙)
  2. 添加bearer认证 (验证钥匙是否正确)
  3. 给接口或控制器添加验证 (锁)
  4. 给接口添加显示的小锁

1.引入包:System.IdentityModel.Tokens.Jwt

这次博客比第一次简化了好多,比如令牌的model类,密钥写在配置文件等,暂时省略了

  public static string IssueJwt(string id,string Name)
        {
            string iss = "发行人";
            string aud = "受众人";
            string secret = "12345678912345671234567891234567";

            //载荷
            var claims = new List<Claim>()
            {
                 //jwtID唯一
                 new Claim(JwtRegisteredClaimNames.Jti,id),
                 //发行人可以理解为网站属于发行人
                 new Claim(JwtRegisteredClaimNames.Iss,iss),
                 //受众可以理解为哪些人可以使用
                 new Claim(JwtRegisteredClaimNames.Aud,aud),
                 //主体可以理解为对令牌的说明
                 new Claim(JwtRegisteredClaimNames.Sub,"主体"),
                 //发行时间即为令牌生成的时间
                 new Claim (JwtRegisteredClaimNames.Iat,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 //在此时间之前不可用
                 new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 //令牌过期时间
                 new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(60)).ToUnixTimeSeconds()}"),
                 new Claim(ClaimTypes.Name,Name)
            };

            //使用密钥生成签名凭证
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //序列化jwt
            var jwt = new JwtSecurityTokenHandler().WriteToken(
                new JwtSecurityToken(
                issuer: iss,
                claims: claims,
                signingCredentials: creds));
            return jwt;
        }
   
复制
生成token

2.引入包:Microsoft.AspNetCore.Authentication.JwtBearer 

//注册bearer认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    var SigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("12345678912345671234567891234567"));
    //验证的参数
    o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        //验证密钥
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = SigningKey,
        //验证发行者
        ValidateIssuer = true,
        ValidIssuer = "发行人",
        //验证受众
        ValidateAudience = true,
        ValidAudience = "受众人",
        //验证有效期
        ValidateLifetime = true,
        ClockSkew = TimeSpan.FromSeconds(30),
        //必须有过期值/时间
        RequireExpirationTime = true
    };
    o.Events = new JwtBearerEvents()
    {
        //当JWT Bearer认证失败时,即请求未包含有效的JWT令牌或令牌验证失败,该事件会被触发
        OnChallenge = context =>
        {
            context.Response.Headers.Add("Token-Error", context.ErrorDescription);
            return Task.CompletedTask;
        },
        //当JWT Bearer认证过程中出现异常时,例如令牌过期、签名验证失败等情况,该事件会被触发
        OnAuthenticationFailed = context =>
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            var token = context.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", string.Empty).Replace("bearer",string.Empty).Trim();

            var jwtToken = jwtHandler.ReadJwtToken(token);

            if (jwtToken.Issuer != "发行人")
            {
                context.Response.Headers.Add("Token-Error-Iss", "issuer is wrong!");
            }

            if (jwtToken.Audiences.FirstOrDefault() != "受众人")
            {
                context.Response.Headers.Add("Token-Error-Aud", "Audience is wrong!");
            }
            // 如果过期,则把<是否过期>添加到,返回头信息中
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }
            return Task.CompletedTask;
        }
    };
});
复制
bearer认证

3和4:引入包:SwashBuckle.AspNetCore.Filters

builder.Services.AddSwaggerGen(a =>
{
    // 开启加权小锁(暂时不知道什么意思)
    a.OperationFilter<AddResponseHeadersFilter>();
    //(接口显示认证角色信息)
    a.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
    // 在header中添加token,传递到后台(添加小锁)
    a.OperationFilter<SecurityRequirementsOperationFilter>();

    a.AddSecurityDefinition("oauth2", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
    {
        Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
        Name = "Authorization",        //jwt默认的参数名称
        In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
        Type = SecuritySchemeType.ApiKey//安全方案/类型(模式)APIkey
    });
});
复制
添加到swagger显示锁

 

 

 

与Net6之Jwt认证+Bearer认证 2.0相似的内容:

Net6之Jwt认证+Bearer认证 2.0

以前接触过,写过博客,第二次再写有了新的体会。第一次博客:https://www.cnblogs.com/zhang-3/p/16184067.html 过程: 生成token令牌(钥匙) 添加bearer认证 (验证钥匙是否正确) 给接口或控制器添加验证 (锁) 给接口添加显示的小锁 1.引入包:

关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

在.Net Framework时代,我们生成验证码大多都是用System.Drawing。 在.Net 6中使用也是没有问题的。 但是,System.Drawing却依赖于Windows GDI+。 为了实现跨平台,我陷入了沉思!! 微软推荐使用SkiaSharp 进行替代,所以就开始了,踩坑之旅

.Net6新版本的AssemblyLoadContext 加载程序集和卸载程序集

.Net6新版本的AssemblyLoadContext 加载程序集和卸载程序集 准备俩个项目 第一个是控制台 第二个项目是类库 类库项目中只有一个示例class 将类库的代码生成dll 并且设置属性为复制到输出目录 using System.Runtime.Loader; var domain =

NET6使用AutoFac依赖注入(仓储模式)

第一次使用autofac,然后net6最新长期支持的,就想着在net6的基础上使用autofac,我对依赖注入理解很差,一知半解的搞了好久。好在有了一点点的头绪,记录下省的以后忘记(突然发现自己以前用过的东西忘了好多……) 1.首先你要有个仓储模式的项目、这个自己搭建吧 2.在Program.cs文

.NET6 + EF Core + MySQL 创建实体和数据库、EFCore 数据迁移

前言 接上期文章《.NET6项目连接数据库方式方法》,有人问了我几个问题,现在就这几个问题,拓展延申一下创建实体类、数据库。把ORM框架和数据迁移都写进去。 安装ORM框架,这里我们采用EFCore 安装EFCore 我的项目是在Linux上创建的,使用的是vscode开发工具远程开发。为了方便大家

.NET6项目连接数据库方式方法

前言 接上一篇Linux系统下创建dotnet项目,这一篇我们聊聊.NET6环境下dotnet项目连接数据库的方式方法,包括数据库字符串该如何配置。看了很多博主写的文章,连接数据库字符串配置的方式和位置五花八门,这篇文章给大家介绍一下连接数据库字符串的配置方式方法,顺便介绍下一个新创建的dotnet

如何在Net6.0里配置多版本支持并支持注释说明的Swagger

一、前言 现在已经进入了微服务的开发时代了,在这个时代,如果有人问你什么是微服务,你说不知道,就有点太丢人了,别人会有异样的眼光看你,俗话说:唾液淹死人。没办法,我们只能去学习新的东西。一提到微服务,有一个绕不过的话题就是作为微服务的载体,WebAPI是离不开的。但是我们今天不讲WebAPI是什么,

如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权

一、简介 我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是WebAPI,在 Net6.0中,有两类 WebAPI,一类是极简 WebAPI,它砍掉了很多冗余的东西,更纯粹的是做 API的,也更适合做微服务的开发。另外一类就是我们通常使用的正常 API,这个没得说,也是我们使用最

DoNet Core的启动过程-WebApplicationBuilder

1.前言 在NET6开始做ASP.NETCore的开发,我们首先要看的是启动过程,而WebApplication和WebApplicationBuilder 类是启动过程好不开的类,WebApplicationBuilder 来引导启动,这和前面Core的版本引导启动分为Program和Startu

Azure DevOps(一)基于 Net6.0 的 WPF 程序如何进行持续集成、持续编译

一,引言 我们是否正在为如何快速的编译、部署客户端应用程序而烦恼?这也是博主最近遇到的问题。目前博主所在公司主要做项目级的定制化开发,多以 C/S 架构的 WPF 程序为主,每次到了协助开发团队给实施团队编译好的要测试程序包时,就会出现多人协助,编译、打包好的二进制程序包 pull 最新代码 ,以及