JWT签名与验签
签名Token生产
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; namespace CoreTest.Controllers
{
public class TokenController : Controller
{
private ITokenHelper _tokenHelper = null; public TokenController(ITokenHelper tokenHelper)
{
_tokenHelper = tokenHelper;
} public IActionResult Index(string code, string pwd)
{
User user = TemporaryData.GetUser(code);
if (null != user && user.Password.Equals(pwd))
{
return Ok(_tokenHelper.CreateToken(user));
}
return BadRequest();
} [HttpPost]
[Authorize]
public IActionResult Index()
{
return Ok(_tokenHelper.RefreshToken(Request.HttpContext.User));
} } public interface ITokenHelper
{
Token CreateAccessToken(User user);
ComplexToken CreateToken(User user);
ComplexToken CreateToken(Claim[] claims);
Token RefreshToken(ClaimsPrincipal claimsPrincipal);
} public class TokenHelper : ITokenHelper
{
private IOptions<JWTConfig> _options;
public TokenHelper(IOptions<JWTConfig> options)
{
_options = options;
} public Token CreateAccessToken(User user)
{
Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name) }; return CreateToken(claims, TokenType.AccessToken);
} public ComplexToken CreateToken(User user)
{
Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name)
//下面两个Claim用于测试在Token中存储用户的角色信息,对应测试在FlyLolo.JWT.API的两个测试Controller的Put方法,若用不到可删除
, new Claim(ClaimTypes.Role, "TestPutBookRole"), new Claim(ClaimTypes.Role, "TestPutStudentRole")
}; return CreateToken(claims);
} public ComplexToken CreateToken(Claim[] claims)
{
return new ComplexToken { AccessToken = CreateToken(claims, TokenType.AccessToken), RefreshToken = CreateToken(claims, TokenType.RefreshToken) };
} /// <summary>
/// 用于创建AccessToken和RefreshToken。
/// 这里AccessToken和RefreshToken只是过期时间不同,【实际项目】中二者的claims内容可能会不同。
/// 因为RefreshToken只是用于刷新AccessToken,其内容可以简单一些。
/// 而AccessToken可能会附加一些其他的Claim。
/// </summary>
/// <param name="claims"></param>
/// <param name="tokenType"></param>
/// <returns></returns>
private Token CreateToken(Claim[] claims, TokenType tokenType)
{
var now = DateTime.Now;
var expires = now.Add(TimeSpan.FromMinutes(tokenType.Equals(TokenType.AccessToken) ? _options.Value.AccessTokenExpiresMinutes : _options.Value.RefreshTokenExpiresMinutes));//设置不同的过期时间
var token = new JwtSecurityToken(
issuer: _options.Value.Issuer,
audience: tokenType.Equals(TokenType.AccessToken) ? _options.Value.Audience : _options.Value.RefreshTokenAudience,//设置不同的接受者
claims: claims,
notBefore: now,
expires: expires,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)), SecurityAlgorithms.HmacSha256));
return new Token { TokenContent = new JwtSecurityTokenHandler().WriteToken(token), Expires = expires };
} public Token RefreshToken(ClaimsPrincipal claimsPrincipal)
{
var code = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.NameIdentifier));
if (null != code)
{
return CreateAccessToken(TemporaryData.GetUser(code.Value.ToString()));
}
else
{
return null;
}
}
} public class User
{
public string Code { get; set; }
public string Name { get; set; }
public string Password { get; set; }
} public class Token
{
public string TokenContent { get; set; } public DateTime Expires { get; set; }
} public enum TokenType
{
AccessToken = ,
RefreshToken =
} public class ComplexToken
{
public Token AccessToken { get; set; }
public Token RefreshToken { get; set; }
} public class JWTConfig
{
public string Issuer { get; set; }
public string Audience { get; set; }
public string IssuerSigningKey { get; set; }
public int AccessTokenExpiresMinutes { get; set; }
public string RefreshTokenAudience { get; set; }
public int RefreshTokenExpiresMinutes { get; set; }
} public static class TemporaryData
{
private static List<User> Users = new List<User>()
{
new User { Code = "", Name = "张三", Password = "" },
new User { Code = "", Name = "李四", Password = "" }
}; public static User GetUser(string code)
{
return Users.FirstOrDefault(m => m.Code.Equals(code));
}
}
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*", "JWT": {
"Issuer": "FlyLolo",
"Audience": "TestAudience",
"IssuerSigningKey": "FlyLolo1234567890",
"AccessTokenExpiresMinutes": "",
"RefreshTokenAudience": "RefreshTokenAudience",
"RefreshTokenExpiresMinutes": ""
}
}
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CoreTest.Controllers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; namespace CoreTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Controllers.UserInfo>(Configuration.GetSection("User"));
services.AddSingleton<ITokenHelper, TokenHelper>();
services.Configure<JWTConfig>(Configuration.GetSection("JWT"));
JWTConfig config = new JWTConfig();
Configuration.GetSection("JWT").Bind(config); services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = config.Issuer,
ValidAudience = config.RefreshTokenAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey))
};
}); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
} app.UseHttpsRedirection(); app.UseAuthentication();
app.UseMvc(route =>
{
route.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}"
);
});
}
}
}
Token验证
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; namespace ClientTest.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class BookController : ControllerBase
{
// GET: api/<controller>
[HttpGet]
[AllowAnonymous]
public IEnumerable<string> Get()
{
return new string[] { "ASP", "C#" };
} // POST api/<controller>
[HttpPost]
public JsonResult Post()
{
return new JsonResult("Create Book ...");
}
} public class JWTConfig
{
public string Issuer { get; set; }
public string Audience { get; set; }
public string IssuerSigningKey { get; set; }
public int AccessTokenExpiresMinutes { get; set; }
}
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"JWT": {
"Issuer": "FlyLolo",
"Audience": "TestAudience",
"IssuerSigningKey": "FlyLolo1234567890",
"AccessTokenExpiresMinutes": ""
}
}
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClientTest.Controllers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; namespace ClientTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
#region 读取配置
JWTConfig config = new JWTConfig();
Configuration.GetSection("JWT").Bind(config);
#endregion #region 启用JWT认证
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).
AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = config.Issuer,
ValidAudience = config.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)),
ClockSkew = TimeSpan.FromMinutes()
};
});
#endregion services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
} app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
}
}
JWT签名与验签的更多相关文章
- .NET RSA解密、签名、验签
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Sec ...
- PHP SHA1withRSA加密生成签名及验签
最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来. ...
- 中行P1签名及验签
分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...
- 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式
# 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...
- erlang的RSA签名与验签
1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...
- Delphi微信支付【支持MD5和HMAC-SHA256签名与验签】
作者QQ:(648437169) 点击下载➨微信支付 微信支付api文档 [Delphi 微信支付]支持付款码支付.二维码支付.订单查询.申请退款.退款查询.撤销订单.关闭订单. ...
- Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】
作者QQ:(648437169) 点击下载➨Delphi支付宝支付 支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...
- RSA后台签名前台验签的应用(前台采用jsrsasign库)
写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...
- Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】
作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...
随机推荐
- 源码学习之Spring (系统架构简单解析)
Spring Framework 系统架构总览图 Spring Framework的模块依赖关系图 Spring Framework各个模块功能说明 Spring核心模块 模块名称 主要功能 Spri ...
- python-12-字典的嵌套与int快速排序
前言 字典的增删改查我们都有一定的认识与了解啦,但是字典也可以嵌套列表.字典.元组等数据结构. 一.字典的嵌套 1.修改.添加 dic = { "name": ["lin ...
- mysqlslap详解--MySQL自带的性能压力测试工具(转)
本文的参考博客地址为:https://blog.csdn.net/fuzhongfaya/article/details/80943991 和 https://www.cnblogs.com/davy ...
- MySQL for OPS 10:MyCAT 分布式架构
写在前面的话 在学习的索引的时候,有提到,当数据表数据达到 800W 的时候,索引的性能就开始逐步下降.对于一个公司而言,主要业务数据表达到 1000W 都很容易.同时这张表一般都是业务常用的表,操作 ...
- 删除链表的中间节点和a/b处的节点
问题描述: 删除链表的中间节点和a/b处的节点 给定链表的头结点head,实现删除链表的中间节点的函数: 例如: 不删除任何节点: 1-->2,删除节点1: 1-->2-->3,删除 ...
- Spring MVC HTTP406 Not Acceptable
今天在搞前后端分离用springmvc传递json数据的时候,第一步就卡主了,本着完事开头难的做法(哈哈哈), 报了个406?什么鬼? 百度之后发现很多人也同我一样遇到过这个问题,记录下. 找到的处理 ...
- iota: Golang 中优雅的常量
阅读约 11 分钟 注:该文作者是 Katrina Owen,原文地址是 iota: Elegant Constants in Golang 有些概念有名字,并且有时候我们关注这些名字,甚至(特别)是 ...
- Python【day 14-4】sorted filter map+递归文件夹+二分法查找
def func(x): #普通函数 return x*x ret1 = func(10) #匿名函数 f = lambda x:x*x # 匿名函数写法: 匿名函数名=lambda 参数:返回值 ' ...
- 自定义滚动条样式纯(css)
啥都不说先看图: 注: 只适合chrom,不适用IE和fireFox 下面展示代码: <html lang="en"> <head> <meta ch ...
- HTTP协议中的Range和Content-Range
" 琢磨HTTP协议的每一个细节." HTTP协议博大精深,每一个细节都应细细体会. 否则,在协议还原的过程中,你会遇到各种问题. 今天,本文中将对HTTP协议的Range和Con ...