[转]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编码 得到第一部分
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Payload
由三部分构成
标准中注册的声明
公共的声明
私有的声明
标准中注册的声明 (建议但不强制使用) :
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的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Signature(数字签名,防止信息被篡改)
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();//绑定jwtSeetingsConfiguration.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://github.com/HisKingdom/JwtAuthSample
参考博客:https://www.jianshu.com/p/576dbf44b2ae
转载于:https://www.cnblogs.com/freeliver54/p/10512031.html
[转]C# 实现Jwt bearer Authentication相关推荐
- ASP.NET Core WebAPI中使用JWT Bearer认证和授权
为什么是 JWT Bearer ASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer, ...
- FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
既然我们已经有了所有的安全流程,就让我们来使用 JWT 令牌和安全哈希密码让应用程序真正地安全. 关于 JWT 它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准.字符串看起 ...
- Salesforce Integration - OAuth2.0 JWT Bearer Flow
应用场景 Salesforce作为Service Provider (SP),外部系统需要访问Salesforce数据: 在授权过程中无需通过UI Login页面输入账密: 不希望外部系统储存账密等可 ...
- ASP.NET Core WebAPI JWT Bearer 认证失败返回自定义数据 Json
开发环境:ASP.NET Core Web API 目标框架:.NET Core 2.2 权限认证:JWT Bearer 提供者:成长的小猪 Jason Song 应用场景:当前我们给微信小程 ...
- .Net Core 2.1 JWT Bearer 的认证
起因 最近想要学习一下 .net core 2.1 相关的知识,即是因为工作需要亦是在微服务和 docker 化的今天不得不去了解了解 .net core.API 第一步即是安全,即为认证(Authe ...
- ABP 6.0.0-rc.1的新特性
2022-07-26官方发布ABP 6.0.0-rc.1版本,本文挑选了几个新特性进行了介绍,主要包括LeptonX Lite默认主题.OpenIddict模块,以及如何将Identity Ser ...
- JWT Authentication Tutorial: An example using Spring Boot--转
原文地址:http://www.svlada.com/jwt-token-authentication-with-spring-boot/ Table of contents: Introductio ...
- SpringBoot+SpringSecurity前后端分离+Jwt的权限认证(改造记录)
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/zzzgd_666/article/details/96444829 前言 一般来说,我们用Spr ...
- Spring Security 实战:使用 JWT 认证访问接口
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 欢迎阅读Spring Security 实战 ...
- ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露
一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...
最新文章
- opencv用haartraining训练出现的一些问题
- 怎么在java中创建一个自定义的collector
- 解决后退,清空验证码(其它文本框保留)
- mysql cluster 7.1搭建
- conda An unexpected error has occurred
- 【废了-准备删除02】信息收集——基于WAMP的drupal7.x管理系统
- 查看oracle客户端的版本,Oracle客户端版本及位数(Windows系统)查看方法
- C#用Socket和S7.net实现安卓手机APP读写西门子PLC数据(安卓APP使用的E4A中文编程软件)
- 802.11a/b/g/n/ac速率表--防迷路,通过博客收藏
- 「经济/商学/理财」简说
- 企业网站优化用户体验以内容为主
- [CF949D]Curfew
- vue如何关闭eslint语法检查
- UVA 487 - Boggle Blitz
- STN向城域云网演进浅析
- 尘埃粒子计数的价格以及使用注意事项
- 使用Hexo平台搭建个人博客
- 12.10 Daily Scrum
- Rust 语言服务器 (RLS)
- Centos7虚拟机磁盘恢复
热门文章
- js简单实现div里面的内容向上平滑滚动。
- JQuery 表格拖动调整列宽效果
- js控制input控件只能输入数字
- 【知识蒸馏综述】用20篇论文走完知识蒸馏在 2014-2020 年的技术进展
- 医疗NLP相关数据集整理
- 每日算法系列【LeetCode 685】冗余连接 II
- NLP学习—22.Transformer的代码实现
- linux错误—1.vim: command not found
- numpy—np.diag(v, k=0)
- 软件技术架构:通过限流与熔断,打造一个“靠谱”的系统