Jwtbearer Authentication

什么是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();
    //绑定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))
    };
    })
    ;
  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

C# 实现Jwtbearer Authentication的更多相关文章

  1. 任务36:应用Jwtbearer Authentication

    任务36:应用Jwtbearer Authentication D:\MyDemos\jesse 新建项目:dotnet new webapi --name JwtAuthSample VS2017运 ...

  2. 【ASP.NET Core快速入门】(十一)应用Jwtbearer Authentication、生成jwt token

    准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...

  3. 菜鸟入门【ASP.NET Core】11:应用Jwtbearer Authentication、生成jwt token

    准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...

  4. 36-应用Jwtbearer Authentication

    新建.net core webapi项目 E:\coding\netcore>dotnet new webapi --name JwtAuthSample 创建需要用到的实体对象类 namesp ...

  5. Nancy基于JwtBearer认证的使用与实现

    前言 最近在看JSON Web Token(Jwt)相关的东西,但是发现在Nancy中直接使用Jwt的组件比较缺乏,所以就在空闲时间写了一个. 这个组件是开源的,不过目前只支持.NET Core,后续 ...

  6. [转]C# 实现Jwt bearer Authentication

    本文转自:https://www.cnblogs.com/aishangyipiyema/p/9262642.html 什么是JWT JWT(JSON Web Token), 顾名思义就是在Web上以 ...

  7. ASP.NET Core集成现有系统认证

    我们现在大多数转向ASP.NET Core来使用开发的团队,应该都不是从0开始搭建系统,而是老的业务系统已经在运行,ASP.NET Core用来开发新模块.那么解决用户认证的问题,成为我们的第一个拦路 ...

  8. 极简版ASP.NET Core学习路径及教程

    绝承认这是一个七天速成教程,即使有这个效果,我也不愿意接受这个名字.嗯. 这个路径分为两块: 实践入门 理论延伸 有了ASP.NET以及C#的知识以及项目经验,我们几乎可以不再需要了解任何新的知识就开 ...

  9. asp.net core WebAPI学习以及 发布(***入门学习)

    A asp.net Core 系列[一]——创建Web应用 asp.net Core 系列[二]—— 使用 ASP.NET Core 和 VS2017 for Windows 创建 Web API a ...

随机推荐

  1. HTML标签的绝对路径和相对路径

    我在javaweb中写json的Demo的时候遇到了这个问题,图片一一直取不出来,查了好久终于解决了,所以现在记录一下. 绝对路径: 其实很容易理解,如果你是一个普通的项目,那就是它在你电脑里真实存在 ...

  2. 记一次Weblogic发布Springboot遇到的坑

    项目使用的是Springboot,之前直接使用JAR包的方式发布,但在客户这边实施发布的时候,客户使用的容器是weblogic,版本为 10.3.6.  痛苦就此开始! 不过项目组还有另外一个也同样使 ...

  3. MFC对话框和属性表

    对话框主要有两类,分为模式和无模式,它们的功能都被封装在了CDialog中.与对话框相近的是属性表,属性表实际上是具有制表页(TAB 页)的对话框,将对话框中控件更好的组织在一起.借助Cpropert ...

  4. Android-shape圆形&转圈圈

    圆形: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="h ...

  5. 微信机器人 index

    <?phprequire_once ('src/wechat.php');$wechat = new wechat();$act = isset($_GET['act'])?$_GET['act ...

  6. win10个人助理conrtana软件能否支持用户反馈、后续优化

    上网查找了一下,win10的个人助理不支持用户反馈.这些反馈都是用户通过别的途径来发表反馈的信息,这个缺陷让用户不是特别满意,因为反馈信息不再那么简答,变得越来越繁琐.有些人还会担心自己反馈的问题会不 ...

  7. 当GDPR来敲门,中国互联网企业该如何应对?

    本文来自 网易云社区 . 欧盟<通用数据保护条例>(General Data Protection Regulation,GDPR)已于2018年5月25日正式生效,谷歌.Facebook ...

  8. Vipe-技术选型

    1.AOP,IOC框架-Spring 选择Spring是最不需要考虑的.应该90%以上的JAVA项目都有用Spring. 2.ORM框架-Mybatis Mybatis入门比较简单,并且对SQL语法的 ...

  9. 升讯威微信营销系统开发实践:(2)中控服务器的详细设计( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  10. js实用方法记录-指不定哪天就会用到的js方法

    js实用方法记录-指不定哪天就会用到的js方法 常用或者不常用都有 判断是否在微信浏览器中 测试代码:isWeiXin()==false /** * 是否在微信中 */ function isWeix ...