本文转自: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

  1. 新建一个WebApi项目

  1. 新建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; } }
  2. appsettings.json里面配置如下

    "JwtSeetings": {"Issuer": "http://localhost:5000","Audience": "http://localhost:5000", "SecretKey": "zhoudafu201807041123"
  3. 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)) }; }) ;
  4. Startup类里面Configure添加如下代码

     app.UseAuthentication();
  5. 新增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(); }
  6. 给ValuesController控制器打上[Authorize]特性

  7. 用Postman直接访问http://localhost:5000/api/Values 返回401

  8. 用Postman访问http://localhost:5000/api/Authroize 得到Token

  9. 通过Bearer访问成功

源代码 https://github.com/HisKingdom/JwtAuthSample

参考博客:https://www.jianshu.com/p/576dbf44b2ae

转载于:https://www.cnblogs.com/freeliver54/p/10512031.html

[转]C# 实现Jwt bearer Authentication相关推荐

  1. ASP.NET Core WebAPI中使用JWT Bearer认证和授权

    为什么是 JWT Bearer ASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer,  ...

  2. FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2

    既然我们已经有了所有的安全流程,就让我们来使用 JWT 令牌和安全哈希密码让应用程序真正地安全. 关于 JWT        它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准.字符串看起 ...

  3. Salesforce Integration - OAuth2.0 JWT Bearer Flow

    应用场景 Salesforce作为Service Provider (SP),外部系统需要访问Salesforce数据: 在授权过程中无需通过UI Login页面输入账密: 不希望外部系统储存账密等可 ...

  4. ASP.NET Core WebAPI JWT Bearer 认证失败返回自定义数据 Json

    开发环境:ASP.NET Core Web API 目标框架:.NET Core 2.2  权限认证:JWT Bearer    提供者:成长的小猪 Jason Song 应用场景:当前我们给微信小程 ...

  5. .Net Core 2.1 JWT Bearer 的认证

    起因 最近想要学习一下 .net core 2.1 相关的知识,即是因为工作需要亦是在微服务和 docker 化的今天不得不去了解了解 .net core.API 第一步即是安全,即为认证(Authe ...

  6. ABP 6.0.0-rc.1的新特性

      2022-07-26官方发布ABP 6.0.0-rc.1版本,本文挑选了几个新特性进行了介绍,主要包括LeptonX Lite默认主题.OpenIddict模块,以及如何将Identity Ser ...

  7. JWT Authentication Tutorial: An example using Spring Boot--转

    原文地址:http://www.svlada.com/jwt-token-authentication-with-spring-boot/ Table of contents: Introductio ...

  8. SpringBoot+SpringSecurity前后端分离+Jwt的权限认证(改造记录)

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/zzzgd_666/article/details/96444829 前言 一般来说,我们用Spr ...

  9. Spring Security 实战:使用 JWT 认证访问接口

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 欢迎阅读Spring Security 实战 ...

  10. ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露

    一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...

最新文章

  1. opencv用haartraining训练出现的一些问题
  2. 怎么在java中创建一个自定义的collector
  3. 解决后退,清空验证码(其它文本框保留)
  4. mysql cluster 7.1搭建
  5. conda An unexpected error has occurred
  6. 【废了-准备删除02】信息收集——基于WAMP的drupal7.x管理系统
  7. 查看oracle客户端的版本,Oracle客户端版本及位数(Windows系统)查看方法
  8. C#用Socket和S7.net实现安卓手机APP读写西门子PLC数据(安卓APP使用的E4A中文编程软件)
  9. 802.11a/b/g/n/ac速率表--防迷路,通过博客收藏
  10. 「经济/商学/理财」简说
  11. 企业网站优化用户体验以内容为主
  12. [CF949D]Curfew
  13. vue如何关闭eslint语法检查
  14. UVA 487 - Boggle Blitz
  15. STN向城域云网演进浅析
  16. 尘埃粒子计数的价格以及使用注意事项
  17. 使用Hexo平台搭建个人博客
  18. 12.10 Daily Scrum
  19. Rust 语言服务器 (RLS)
  20. Centos7虚拟机磁盘恢复

热门文章

  1. js简单实现div里面的内容向上平滑滚动。
  2. JQuery 表格拖动调整列宽效果
  3. js控制input控件只能输入数字
  4. 【知识蒸馏综述】用20篇论文走完知识蒸馏在 2014-2020 年的技术进展
  5. 医疗NLP相关数据集整理
  6. 每日算法系列【LeetCode 685】冗余连接 II
  7. NLP学习—22.Transformer的代码实现
  8. linux错误—1.vim: command not found
  9. numpy—np.diag(v, k=0)
  10. 软件技术架构:通过限流与熔断,打造一个“靠谱”的系统