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. all about

    1.三次握手和四次挥手?2.什么是OSI七层结构?3.http vs https?4.what is Ping?基于什么协议?使用方法?5.DNS?6.cookie vs session?7.LDAP ...

  2. 2.SpringMVC注解开发

    1.创建SpringMVC项目 配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-a ...

  3. iOS开发之Alamofire源码解析

    今天博客中的Alamofire源码的版本是以3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是给本篇博客 ...

  4. Nuget4.0 bug一粒

    这个锅到底是nuget的还是msbuild的我也不是很确定 在使用Nuget4.0打包编译项目时 当执行到nuget pack %%~dpna.csproj -build -Prop Configur ...

  5. Javascript高级编程学习笔记(22)—— 对象继承

    继承是所有面向对象的语言最让人津津乐道的概念 许多面向对象的语言都支持两种实现继承的方式: 1.接口继承 2.实现继承 由于ECMAScript中没有函数签名,所以自然也是不支持接口继承 所以JS中能 ...

  6. 吴恩达机器学习笔记18-多类别分类:一对多(Multiclass Classification_ One-vs-all)

    对于之前的一个,二元分类问题,我们的数据看起来可能是像这样: 对于一个多类分类问题,我们的数据集或许看起来像这样: 我用3 种不同的符号来代表3 个类别,问题就是给出3 个类型的数据集,我们如何得到一 ...

  7. Go语言复制文件

    需要使用io包的Copy方法 package main import ( "fmt" "io" "os" ) //自己编写一个函数,接收两个 ...

  8. 第64节:Java中的Spring Boot 2.0简介笔记

    Java中的Spring Boot 2.0简介笔记 spring boot简介 依赖java8的运行环境 多模块项目 打包和运行 spring boot是由spring framework构建的,sp ...

  9. Scala - 快速学习03 - 基础语法

    1- 变量 变量 mutable variable 在程序运行过程中其值可能发生改变的量 关键词var定义变量,定义时直接进行求值 常量 immutable variable 在程序运行过程中其值不会 ...

  10. python --商品评价---- 数据表结构以及理解

    商品评论(评价)功能 1.概述 评论功能已经成为APP和网站开发中的必备功能.本文主要介绍评论功能的数据库设计. 评论功能最主要的是发表评论和回复评论(删除功能在后台).评论功能的拓展功能体现有以下几 ...