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. 实现一个CRDT工具库——LWWReg

    LWWReg LWW Register是一种数据结构,用于存储一个值和一个时间戳,支持读取和写入操作.在写入时,如果新的时间戳比原来的时间戳更大,那么就更新值和时间戳:在读取时,直接返回当前的值.这个 ...

  2. THFuse: An infrared and visible image fusion network using transformer and hybrid feature extractor 论文解读

    THFuse: An infrared and visible image fusion network using transformer and hybrid feature extractor ...

  3. ACM-NEFU新生训练2-排序和CMP

    A.谁考了第k名-排序 Description 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩. Input 第一行有两个整数,分别是学生的人数n(1≤ ...

  4. 一次线上OOM问题的个人复盘

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 上个月,我们一个java服务上线后,偶尔会发生内存OOM(Out Of Memory)问题,但由于OOM导致服务 ...

  5. 图与网络分析—R实现(四)

    三 最短路问题 最短路问题(short-path problem)是图论理论的一个经典问题.寻找最短路径就是在指定网络中两结点间找一条距离最小的路.最短路不仅仅指一般地理意义上的距离最短,还可以引申到 ...

  6. Laplace分布算子开发经验分享

    摘要:Laplace 用于 Laplace 分布的概率统计与随机采样. 本文分享自华为云社区<Laplace分布算子开发经验分享>,作者:李长安. 1.任务解析 详细描述: Laplace ...

  7. Numpy浅拷贝与深拷贝

    Numpy中的浅拷贝与深拷贝 浅拷贝 共享内存地址的两个变量,当其中一个变量的值改变时另外一个也随之改变. Example a = np.array([1, 2, 3, 4, 5]) b = a pr ...

  8. Semantic Kernel 入门系列:💬Semantic Function

    如果把提示词也算作一种代码的话,那么语义技能所带来的将会是全新编程方式,自然语言编程. 通常情况下一段prompt就可以构成一个Semantic Function,如此这般简单,如果我们提前可以组织好 ...

  9. 写一个 Hello SpringBoot2 项目

    需求:向浏览发送/hello请求,并响应 Hello,Spring Boot 2 解决: 项目目录:controller层.Main启动项.pom.xml controller层:写好逻辑跳转,当浏览 ...

  10. React Native 开发环境搭建——nodejs安装、yarn安装、JDK安装多个版本、安装Android Studio、配置Android SDK的环境变量

    一.React Native介绍 二.开发环境的搭建 2.1.Node.js安装 Node.js要求14版或更新 https://nodejs.org/en 查看版本: 2.2.yarn安装 Yarn ...