JWT(Json Web Token)

jwt是一种用于身份验证的开放标准,他可以在网络之间传递信息,jwt由三部分组成:头部,载荷,签名。头部包含了令牌的类型和加密算法,载荷包含了用户的信息,签名则是对头部和载荷的加密结果。

jwt鉴权验证是指在用户登录成功后,服务器生成一个jwt令牌并返回给客户端,客户端在后续的请求中携带该令牌,服务通过令牌的签名来确定用户的身份和权限。这种方式可以避免在每个请求中都需要进行身份验证,提高了系统的性能和安全性。

jwt具有以下优点:

1.无状态:jwt令牌包含了所有必要的信息,服务器不需要再每个请求中都进行身份验证,避免了服务器存储会话信息的开销。

2.可扩展性:jwt令牌可以包含任意的信息,可以根据需要添加自定义的字段。

3.安全性:jwt令牌使用签名来保证数据的完整性和真实性,防止数据被篡改或伪造。

4.跨平台:jwt令牌是基于json格式的,可以再不同的变成语言和平台之间进行传递和解析。

如何在webapi中使用JWT?

1.首先在项目中添加如下两个包

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

也可以直接在Nuget包管理工具中搜索

2.创建JwtOptions模型类,同时在appsetting.json中添加对应配置

    public class JwtOptions
{
/// <summary>
/// 签发者
/// </summary>
public string Issuer { get; set; } /// <summary>
/// 接收者
/// </summary>
public string Audience { get; set; } /// <summary>
/// 密钥
/// </summary>
public string Key { get; set; } /// <summary>
/// 过期时间
/// </summary>
public int ExpireSeconds { get; set; }
}
  "JWT": {
"Issuer": "签发方",
"Audience": "接受方",
"Key": "A86DA130-1B95-4748-B3B2-1B6AA9F2F743",//加密密钥
"ExpireSeconds": 600 //密钥过期时间
}

3.创建JWTExtensions静态类,添加AddJWTAuthentication扩展方法

    public static class JWTExtensions
{
public static AuthenticationBuilder AddJWTAuthentication(this IServiceCollection services, JwtOptions jwtOptions)
{
return services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.TokenValidationParameters = new()
{
ValidateIssuer = true,//是否验证发行商
ValidateAudience = true,//是否验证受众者
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证签名键
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Key))
};
});
}
}

4.创建SwaggerGenOptionsExtensions静态类,添加AddAuthenticationHeader扩展方法,为swagger增加Authentication报文头

    public static class SwaggerGenOptionsExtensions
{
/// <summary>
/// 为swagger增加Authentication报文头
/// </summary>
/// <param name="option"></param>
public static void AddAuthenticationHeader(this SwaggerGenOptions option)
{
option.AddSecurityDefinition("Authorization",
new OpenApiSecurityScheme
{
Description = "Authorization header. \r\nExample:Bearer 12345ABCDE",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Authorization"
}
); ; option.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference=new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Authorization"
},
Scheme="oauth2",
Name="Authorization",
In=ParameterLocation.Header,
},
new List<string>()
}
});
}
}

5.创建IJwtService接口及实现JwtService类,其为构建token服务

    public interface IJwtService
{
string BuildToken(IEnumerable<Claim> claims, JwtOptions options);
}
    public class JwtService : IJwtService
{
public string BuildToken(IEnumerable<Claim> claims, JwtOptions options)
{
//过期时间
TimeSpan timeSpan = TimeSpan.FromSeconds(options.ExpireSeconds);//token过期时间
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(options.Key));//加密的token密钥
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);//签名证书,其值为securityKey和HmacSha256Signature算法
var tokenDescriptor = new JwtSecurityToken(options.Issuer, options.Audience, claims, expires: DateTime.Now.Add(timeSpan), signingCredentials: credentials);//表示jwt token的描述信息,其值包括Issuer签发方,Audience接收方,Claims载荷,过期时间和签名证书
return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);//使用该方法转换为字符串形式的jwt token返回
}
}

6.将上述服务尽数注册

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IJwtService, JwtService>();
JwtOptions jwtOpt = builder.Configuration.GetSection("JWT").Get<JwtOptions>();
builder.Services.AddJWTAuthentication(jwtOpt);
builder.Services.Configure<SwaggerGenOptions>(c =>
{
c.AddAuthenticationHeader();
});
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseAuthentication();//注意,一定得先启动这个
app.UseAuthorization();
//以下回答来自GPT
//app.UseAuthentication()是启用身份验证中间件,它会验证请求中的身份信息,并将身份信息存储在HttpContext.User属性中。而app.UseAuthorization()是启用授权中间件,它会检查HttpContext.User中的身份信息是否有访问当前请求所需的权限。
//一定要先启用身份验证中间件再启用授权中间件,因为授权中间件需要使用身份验证中间件存储的身份信息来进行权限验证。如果没有启用身份验证中间件,授权中间件将无法获取到身份信息,从而无法进行权限验证。
app.MapControllers();
app.Run();

7.在控制器中添加[ApiController]特性开启jwt鉴权,在登录接口中返回token

    [ApiController]
[Route("[controller]/[action]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
}; private readonly ILogger<WeatherForecastController> _logger;
//jwt服务 private readonly IJwtService _jwtService; private readonly IConfiguration _configuration; public WeatherForecastController(ILogger<WeatherForecastController> logger, IJwtService jwtService, IConfiguration configuration)
{
_logger = logger;
_jwtService = jwtService;
_configuration = configuration;
} [HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
} //AllowAnonymous允许匿名访问
[AllowAnonymous, HttpGet]
public string GetToken()
{
var jwtopntion = _configuration.GetSection("JWT").Get<JwtOptions>();
List<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "用户1"));
claims.Add(new Claim(ClaimTypes.Role, "超级管理员"));
return _jwtService.BuildToken(claims, jwtopntion);
}
}

效果测试

直接调用Get方法返回401,鉴权失败

调用GetToken方法,取得token

点击右上角绿色按钮

value中输入的值为bearer,空一格,加上之前取得的token,点击授权

调用成功

如何在.net6webapi中配置Jwt实现鉴权验证的更多相关文章

  1. 如何在sharepoint2010中配置Google Anlytics 分析服务

      简介 Google Analytics(分析)不仅可以帮助您衡量销售与转化情况,而且能为您提供新鲜的深入信息,帮助您了解访问者如何使用您的网站,他们如何到达您的网站,以及您可以如何吸引他们不断回访 ...

  2. 如何在Eclipse中配置Tomcat(免安装版)

    如何在Eclipse中配置Tomcat(免安装版) 2013-10-09 23:19wgelgrsh | 分类:JAVA相关 | 浏览642次 分享到:   2013-10-10 17:10提问者采纳 ...

  3. 如何在appconfig中配置服务的ip

    开发了一个WindowsService消息服务器,刚开始一直都是在代码中把IP地址写死,所以每次只要是更换了新的IP地址后,都需要重新编译项目.所以考虑把ip配置到config文件中, 这样做的好处是 ...

  4. 如何在IAR中配置CRC参数(转)

    源:如何在IAR中配置CRC参数 前言 STM32全系列产品都具有CRC外设,对CRC的计算提供硬件支持,为应用程序节省了代码空间.CRC校验值可以用于数据传输中的数据正确性的验证,也可用于数据存储时 ...

  5. 【神经网络与深度学习】如何在Caffe中配置每一个层的结构

    如何在Caffe中配置每一个层的结构 最近刚在电脑上装好Caffe,由于神经网络中有不同的层结构,不同类型的层又有不同的参数,所有就根据Caffe官网的说明文档做了一个简单的总结. 1. Vision ...

  6. 如何在Mac中配置Python虚拟环境,踩了好多坑

    如何在Mac中配置Python虚拟环境 1.安装virtualenv pip3 install virtualenv 2.安装virtualenvwrapper pip3 install virtua ...

  7. SpringCloud 2020.0.4 系列之 JWT用户鉴权

    1. 概述 老话说的好:善待他人就是善待自己,虽然可能有所付出,但也能得到应有的收获. 言归正传,之前我们聊了 Gateway 组件,今天来聊一下如何使用 JWT 技术给用户授权,以及如果在 Gate ...

  8. 如何在SpringBoot中集成JWT(JSON Web Token)鉴权

    这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...

  9. 如何在 Linux 中配置基于密钥认证的 SSH

    什么是基于 SSH 密钥的认证? 众所周知,Secure Shell,又称 SSH,是允许你通过无安全网络(例如 Internet)和远程系统之间安全访问/通信的加密网络协议.无论何时使用 SSH 在 ...

  10. 如何在idea中配置Tomcat服务器

    .IDEA 中动态 web 工程的操作         a)IDEA 中如何创建动态 web 工程        1.创建一个新模块: 2.选择你要创建什么类型的模块 3.输入你的模块名,点击[Fin ...

随机推荐

  1. [WEB13] ctf.show_web13

    [WEB13] ctf.show_web13 .user.ini绕过 文件上传的要求: 文件的大小要小于24,并且对名字的,后缀的长度都有要求,后缀和名字都不可以包含php的情况下,需要上传一句话木马 ...

  2. JVM——锁

    对象头[每个对象都具有对象头] Mark:对象头的标记(32位),描述对象的 hash.锁信息.垃圾回收标记.年龄:内容包括:①.指向锁记录的指针:②.指向 monitor 的指针:③.GC 标记:④ ...

  3. unable to find Qt5Core.dll on PATH(已解决,超简单)

    不久之前我在引用PyQt5库的时候总是出现unable to find Qt5Core.dll on PATH的错误,错误如下: 百度上都是说什么打包的时候出错,然后加上一句话,我试过以后也不行,后来 ...

  4. 使用Electron-packager打包已有的web项目,发布客户端

    1.先拉electron代码 git clone https://github.com/electron/electron-quick-start 2.将web项目拷贝到electron-quick- ...

  5. python协程详细解释以及例子

    目录 1.协程 1.1greenlet实现协程 1.2yield关键字实现协程 1.3使用asyncio模块实现协程 1.4async & await关键字实现协程 2.协程意义 3.异步编程 ...

  6. 【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(上)

    承接上文 承接之前的[精华推荐 |[算法数据结构专题]「延时队列算法」史上非常详细分析和介绍如何通过时间轮(TimingWheel)实现延时队列的原理指南],让我们基本上已经知道了「时间轮算法」原理和 ...

  7. vue之箭头函数

    目录 说明 解决方法一 重新定义this 解决方法二 使用箭头函数 无参数的箭头函数 有一个参数的箭头函数 有两个参数的箭头函数 有一个参数一个返回值的箭头函数 说明 当在一个方法(函数)里面再定义一 ...

  8. 【JSOI2008】最大值

    [JSOI2008]最大值 线段树裸题!动态RMQ. 这道题的操作是直接在序列末尾添加数值,所以连\(push_{down}\),以及建树什么的都不用了.. 这真是写过的最简短的一道\(seg_{tr ...

  9. v-if与v-show造成部分元素丢失的问题——v-if复用元素问题

    pre { overflow-y: auto; max-height: 400px } img { max-width: 500px; max-height: 300px } 问题描述 在写tab切换 ...

  10. lnmp中遇到open_basedir配置无效问题

    在使用LNMP包安装PHP时,发现直接修改php.ini的配置是无法生效的,其原因竟然是因为nginx的配置文件,覆盖了php.ini的配置.  ----------------------–  LN ...