[转]C# 实现Jwt bearer Authentication
本文转自:https://www.cnblogs.com/aishangyipiyema/p/9262642.html
什么是JWT
JWT(JSON Web Token), 顾名思义就是在Web上以JSON格式传输的Token(RFC 7519)。
该Token被设计为紧凑声明表示格式,特别适用于分布式站点的单点登录(SSO)场景。
紧凑 :意味着size小,所以可以在URL中,Header中,Post Parameter中进行传输,并且包含了所需要的信息。
JWT的构成
JWT一般由三段构成,用"."号分隔开
Header.Payload.Signature
例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c点击链接 如下图
图左边为Header.Payload.Signature的base64编码
图右构成
Header
- alg:声明加密的算法 ,这里为HS256
- typ:声明类型,这里为JWT
然后将Header进行base64编码 得到第一部分
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9Payload
由三部分构成
标准中注册的声明
公共的声明
私有的声明
标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base6编码可以归类为明文信息 。
定义一个payload:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后将其进行base64加密,得到Jwt的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQSignature(数字签名,防止信息被篡改)
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
Header (base64后的)
Payload (base64后的)
Secret
这个部分需要base64加密后的header和base64加密后的payload使用
.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分 。// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');将这三部分用
.连接成一个完整的字符串,构成了最终的jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
下面我们自己来实现一下 JwtBearer Authentication
- 新建一个WebApi项目
新建JwtSeetings类
public class JwtSeetings
{
/// <summary>
/// 谁颁发的jwt
/// </summary>
public string Issuer { get; set; } /// <summary>
/// 谁使用这个jwt
/// </summary>
public string Audience { get; set; } /// <summary>
/// secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,
/// 所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
/// 通过jwt header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分
/// </summary>
public string SecretKey { get; set; }
}appsettings.json里面配置如下
"JwtSeetings": {
"Issuer": "http://localhost:5000",
"Audience": "http://localhost:5000",
"SecretKey": "zhoudafu201807041123"Startup类里面ConfigureServices添加如下代码
services.Configure<JwtSeetings>(Configuration.GetSection("JwtSeetings")); var jwtSeetings = new JwtSeetings();
//绑定jwtSeetings
Configuration.Bind("JwtSeetings", jwtSeetings);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; })
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = jwtSeetings.Issuer,
ValidAudience = jwtSeetings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSeetings.SecretKey))
};
})
;Startup类里面Configure添加如下代码
app.UseAuthentication();新增AuthroizeController控制器,并添加如下代码
[HttpPost]
public ActionResult Post([FromBody]LoginViewModel loginViewModel)
{ if (!ModelState.IsValid)
{
return BadRequest();
}
if (loginViewModel.Name == "jack" && loginViewModel.Password == "rose")
{ var claims = new Claim[]
{
new Claim(ClaimTypes.Name,"jack"),
new Claim(ClaimTypes.Role,"admin")
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSeetings.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(
_jwtSeetings.Issuer,
_jwtSeetings.Audience,
claims,
DateTime.Now,
DateTime.Now.AddMinutes(30),
creds
);
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
} return BadRequest();
}给ValuesController控制器打上[Authorize]特性
用Postman直接访问http://localhost:5000/api/Values 返回401
用Postman访问http://localhost:5000/api/Authroize 得到Token
通过Bearer访问成功
参考博客:https://www.jianshu.com/p/576dbf44b2ae
[转]C# 实现Jwt bearer Authentication的更多相关文章
- ASP.NET Core WebAPI中使用JWT Bearer认证和授权
目录 为什么是 JWT Bearer 什么是 JWT JWT 的优缺点 在 WebAPI 中使用 JWT 认证 刷新 Token 使用授权 简单授权 基于固定角色的授权 基于策略的授权 自定义策略授权 ...
- Add JWT Bearer Authorization to Swagger and ASP.NET Core
Add JWT Bearer Authorization to Swagger and ASP.NET Core If you have an ASP.NET Core web applica ...
- 【转】ASP.NET Core WebAPI JWT Bearer 认证失败返回自定义数据 Json
应用场景:当前我们给微信小程序提供服务接口,接口中使用了权限认证这一块,当我使用 JWT Bearer 进行接口权限认证的时候,返回的结果不是我们客户端想要的,其它我们想要给客户端返回统一的数据结构, ...
- FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
既然我们已经有了所有的安全流程,就让我们来使用 JWT 令牌和安全哈希密码让应用程序真正地安全. 关于 JWT 它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准.字符串看起来像这样: e ...
- [JWT] AngularJS Authentication with JWT
Set up server for JWT Authentication 1. require express 2. require faker: If faker is not install ye ...
- .Net Core JWT Bearer 的认证
关于JWT原理在这不多说,主要由三部分组成:Header.Payload.Signature,有兴趣自己上网了解. 1.首先创建.Net Core 一个Api项目 2.添加 JWT 配置 2.1 修改 ...
- 第29章 保护API - Identity Server 4 中文文档(v1.0.0)
IdentityServer 默认以JWT(JSON Web令牌)格式发出访问令牌. 今天的每个相关平台都支持验证JWT令牌,这里可以找到一个很好的JWT库列表.热门库例如: ASP.NET Core ...
- IdentityServer4【Topic】之保护APIs
Protecting APIs 保护api 默认情况下IdentityServer将access token发布成JWT(json web token)格式的. 现在,每个相关的平台都支持验证JWT令 ...
- IdentityServer4-主题
一.Startup 二.定义Resources 三.定义Clients 四.登录 五.使用外部身份提供商登录 六.Windows身份验证 七.登出 八.注销外部身份提供商 九.联合注销 十.联合网关 ...
随机推荐
- vuejs小白入门
后端做不好,是时候学习一下前端了,听说在很流行vue,那么久跟风学习一波. unbuntu下安装npm,然后安装node,这应该算是开发工具或者执行引擎吧. 感觉web前端框架怎么变,都是对html, ...
- Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路
写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 ...
- node.js Setup Wizard ended prematurely 安装失败
解决: 1. 按照管理员权限运行. 2.安装时禁用掉node 运行环境中的performance counters 和 ETW,或者可以尝试先禁用performance counters .
- JS日历插件 - My97 DatePicker用法详解
一.简介 1. 注意事项 (1)My97DatePicker目录是一个整体,不可破坏里面的目录结构,也不可对里面的文件改名,可以改目录名: (2)各目录及文件的用途: WdatePicker.js 配 ...
- 利用RTL2832u电视棒芯片追踪民航飞机轨迹
我国民航飞机通讯的频率为1090Mhz,而rtl2832u电视棒芯片可以接受的频率范围为24 – 1766 MHz(通过改制Q通道可以接收0-30Mhz的短波)下面开始介绍利用rtl2832u电视棒芯 ...
- JDK 和 OpenJDK 的区别
历史上的原因是,openjdk是jdk的开放原始码版本,以GPL协议的形式放出.在JDK7的时候,openjdk已经成为jdk7的主干开发,sun jdk7是在openjdk7的基础上发布的,其大部分 ...
- [Java]LeetCode133. 克隆图 | Clone Graph
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- [Swift]LeetCode829. 连续整数求和 | Consecutive Numbers Sum
Given a positive integer N, how many ways can we write it as a sum of consecutive positive integers? ...
- [Swift]LeetCode997. 找到小镇的法官 | Find the Town Judge
In a town, there are N people labelled from 1 to N. There is a rumor that one of these people is se ...
- RHEL,红帽CentOS7linux进入单用户(紧急救援)模式修改密码
centos7进入单用户模式 当我们设置用户密码时,有可能会忘记,这时如何登陆呢,单用户模式就可以 首先我们进入开机界面,按e进行选择 会进入以下界面, 然后找到图中红线标注的该行,在行尾添加 i ...




