.NET & JWT

使用 JWT 库

JWT,a JWT(JSON Web Token) implementation for .NET

该库支持生成和解析JSON Web Token

你可以直接通过Nuget获取,也可以自己下载和编译源码.

1// 不要忘了 using 2using JWT; 3using JWT.Algorithms; 4using JWT.Builder; 5 6// 自定义秘钥 7// jwt 的生成和解析都需要使用 8const string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";

创建 JWT

1// 使用 JwtBuilder 来生成 token 2string token = new JwtBuilder() 3 .WithAlgorithm(new HMACSHA256Algorithm()) // 使用算法 4 .WithSecret(secret) // 使用秘钥 5 .AddClaim("exp", DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds()) 6 .AddClaim("claim2", "claim2-value") 7 .Build(); 8 9Console.WriteLine(token);

生成的 token 如下:

1// 注意:是通过.符号分隔成3段,分别对应的是header.payload.signature 2eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1Mjg3MjA2NTEsImNsYWltMiI6ImNsYWltMi12YWx1ZSJ9.56xcZALlJuwROe3qssCbe_DDjpQShk-Ik7kWAzONWFU

生成后可以分发出去, 别人拿着 token 来请求接口的时候, 我们需要解析验证

1// 使用 JwtBuilder 来解析 token 2try 3{ 4 string json = new JwtBuilder() 5 .WithSecret(secret) 6 .MustVerifySignature() 7 .Decode(token); 8 9 Console.WriteLine(json); 10} 11catch (TokenExpiredException) 12{ 13 Console.WriteLine("token 已过期"); 14} 15catch (SignatureVerificationException) 16{ 17 Console.WriteLine("token 签名无效"); 18}

解析后得到的 json 字符串如下:

1{ 2 "exp": 1528721303, 3 "claim2": "claim2-value" 4}

使用 Microsoft.IdentityModel.Tokens 库

  • 新建一个 ASP.NET Core API 项目
  • 新增一个控制器 AuthController

生成 JWT

1using Microsoft.AspNetCore.Mvc; 2using Microsoft.Extensions.Configuration; 3using Microsoft.IdentityModel.Tokens; 4using System; 5using System.IdentityModel.Tokens.Jwt; 6using System.Security.Claims; 7using System.Text; 8 9namespace WebApplication1.Controllers 10{ 11 [ApiController] 12 [Route("[controller]/[action]")] 13 public class AuthController : Controller 14 { 15 private readonly IConfiguration _configuration; 16 17 public AuthController(IConfiguration configuration) 18 { 19 _configuration = configuration; 20 } 21 22 [HttpGet] 23 public IActionResult Token() 24 { 25 var claims = new[] 26 { 27 new Claim(type: ClaimTypes.Name, value: "username") 28 }; 29 30 var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["IssuerSigningKey"])); 31 var creds = new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256); 32 //.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token. 33 /** 34 * Claims (Payload) 35 Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段: 36 iss: The issuer of the token,token 是给谁的 37 sub: The subject of the token,token 主题 38 exp: Expiration Time。 token 过期时间,Unix 时间戳格式 39 iat: Issued At。 token 创建时间, Unix 时间戳格式 40 jti: JWT ID。针对当前 token 的唯一标识 41 除了规定的字段外,可以包含其他任何 JSON 兼容的字段。 42 * */ 43 var token = new JwtSecurityToken( 44 issuer: "test.com", // 45 audience: "test.com", 46 claims: claims, 47 expires: DateTime.Now.AddMinutes(1), 48 signingCredentials: creds); 49 50 return Ok(new 51 { 52 access_token = new JwtSecurityTokenHandler().WriteToken(token: token) 53 }); 54 } 55 } 56}

生成的 JWT 可以放到 jwt.io 里验证一下.

使用 IdentityServer4 库

IdentityServerTools 是 IdentityServer4 中的一个工具类, 封装了 JWT 生成方法, 以便使用.

按照套路, 注入 IdentityServer4 服务, 这里我们仅使用工具类来生成 JWT, 所以不需要配置其他东西.

1public void ConfigureServices(IServiceCollection services) 2{ 3 services.AddIdentityServer() 4 .AddDeveloperSigningCredential(); 5 // 省略其他 6}

在控制器中构造函数注入使用

1using IdentityServer4; 2using Microsoft.AspNetCore.Mvc; 3using System; 4using System.Security.Claims; 5using System.Threading.Tasks; 6 7// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 8 9namespace WebApplication1.Controllers 10{ 11 [ApiController] 12 [Route("api/[controller]")] 13 public class AuthController : ControllerBase 14 { 15 private readonly IdentityServerTools _identityServerTools; 16 17 public AuthController(IdentityServerTools identityServerTools) 18 { 19 _identityServerTools = identityServerTools; 20 } 21 22 [HttpGet] 23 public async Task<IActionResult> TokenAsync() 24 { 25 // 完整的场景, 应该验证用户密码 26 Claim[] claims = new Claim[] 27 { 28 new Claim(type: ClaimTypes.NameIdentifier, value: Guid.NewGuid().ToString("N")), 29 new Claim(type: ClaimTypes.Name, value: "admin"), 30 new Claim(type: ClaimTypes.Gender, value: "man"), 31 new Claim(type: ClaimTypes.Email, value: "xxx@xxx.com"), 32 new Claim(type: "custom", value: "value"), 33 }; 34 35 // 可以按自己需求, 返回指定结构的数据 36 return Ok(value: await _identityServerTools.IssueJwtAsync(lifetime: 3600, claims: claims)); 37 } 38 } 39}

这个时候访问 /api/auth 应该就能看到一段老长老长的 JWT 了, 可以扔到 jwt.io 里验证下.

身份认证

上面介绍了几种不同库生成 JWT 的方法, 当别人拿着我们分发出去的 JWT 来访问我们的接口时, 需要对其进行身份认证

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using Microsoft.AspNetCore.Authentication.JwtBearer; 7using Microsoft.AspNetCore.Builder; 8using Microsoft.AspNetCore.Hosting; 9using Microsoft.AspNetCore.Mvc; 10using Microsoft.Extensions.Configuration; 11using Microsoft.Extensions.DependencyInjection; 12using Microsoft.Extensions.Logging; 13using Microsoft.Extensions.Options; 14using Microsoft.IdentityModel.Tokens; 15 16namespace WebApplication1 17{ 18 public class Startup 19 { 20 public Startup(IConfiguration configuration) 21 { 22 Configuration = configuration; 23 } 24 25 public IConfiguration Configuration { get; } 26 27 // This method gets called by the runtime. Use this method to add services to the container. 28 public void ConfigureServices(IServiceCollection services) 29 { 30 services.AddAuthentication(options => 31 { 32 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 33 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 34 }).AddJwtBearer(options => 35 { 36 options.TokenValidationParameters = new TokenValidationParameters 37 { 38 ValidateIssuer = false, // 是否验证 Issuer 39 ValidIssuer = "test.com", 40 ValidateAudience = false, // 是否验证 Audience 41 ValidAudience = "", 42 ValidateIssuerSigningKey = true, // 是否验证签名秘钥 43 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["IssuerSigningKey"])), 44 ValidateLifetime = true, // 是否验证失效时间 45 }; 46 }); 47 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 48 } 49 50 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 51 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 52 { 53 app.UseAuthentication(); // 使用身份验证 54 if (env.IsDevelopment()) 55 { 56 app.UseDeveloperExceptionPage(); 57 } 58 59 app.UseMvc(); 60 } 61 } 62}

参考

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

springboot结合jwt实现基于restful接口的身份认证

基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~下面直接看如何实现1、首先添加jwt的jar包,pom.xml中添加依赖包:<dependency<groupIdio.jsonwebtoken</groupId

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )