最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

asp.net core集成JWT的步驟記錄

 更新時(shí)間:2019年06月13日 08:56:42   作者:7tiny  
這篇文章主要給大家介紹了關(guān)于asp.net core集成JWT的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用asp.net core具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

【什么是JWT】

JSON Web Token(JWT)是目前最流行的跨域身份驗(yàn)證解決方案。

JWT的官網(wǎng)地址:https://jwt.io/

通俗地來(lái)講,JWT是能代表用戶身份的令牌,可以使用JWT令牌在api接口中校驗(yàn)用戶的身份以確認(rèn)用戶是否有訪問(wèn)api的權(quán)限。

JWT中包含了身份認(rèn)證必須的參數(shù)以及用戶自定義的參數(shù),JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對(duì)進(jìn)行簽名。

【什么時(shí)候應(yīng)該使用JSON Web令牌?】

授權(quán):這是使用JWT的最常見方案。一旦用戶登錄,每個(gè)后續(xù)請(qǐng)求將包括JWT,允許用戶訪問(wèn)該令牌允許的路由,服務(wù)和資源。Single Sign On是一種現(xiàn)在廣泛使用JWT的功能,因?yàn)樗拈_銷很小,并且能夠在不同的域中輕松使用。

信息交換:JSON Web令牌是在各方之間安全傳輸信息的好方法。因?yàn)镴WT可以簽名 - 例如,使用公鑰/私鑰對(duì) - 您可以確定發(fā)件人是他們所說(shuō)的人。此外,由于使用標(biāo)頭和有效負(fù)載計(jì)算簽名,您還可以驗(yàn)證內(nèi)容是否未被篡改。

【JWT有什么優(yōu)勢(shì)?】  

  1. 用戶向服務(wù)器發(fā)送用戶名和密碼。
  2. 服務(wù)器驗(yàn)證通過(guò)后,在當(dāng)前對(duì)話(session)里面保存相關(guān)數(shù)據(jù),比如用戶角色、登錄時(shí)間等等。
  3. 服務(wù)器向用戶返回一個(gè) session_id,寫入用戶的 Cookie。
  4. 用戶隨后的每一次請(qǐng)求,都會(huì)通過(guò) Cookie,將 session_id 傳回服務(wù)器。
  5. 服務(wù)器收到 session_id,找到前期保存的數(shù)據(jù),由此得知用戶的身份。

  這種模式的問(wèn)題在于,擴(kuò)展性(scaling)不好。單機(jī)當(dāng)然沒(méi)有問(wèn)題,如果是服務(wù)器集群,或者是跨域的服務(wù)導(dǎo)向架構(gòu),就要求 session 數(shù)據(jù)共享,每臺(tái)服務(wù)器都能夠讀取 session。如果session存儲(chǔ)的節(jié)點(diǎn)掛了,那么整個(gè)服務(wù)都會(huì)癱瘓,體驗(yàn)相當(dāng)不好,風(fēng)險(xiǎn)也很高。

  相比之下,JWT的實(shí)現(xiàn)方式是將用戶信息存儲(chǔ)在客戶端,服務(wù)端不進(jìn)行保存。每次請(qǐng)求都把令牌帶上以校驗(yàn)用戶登錄狀態(tài),這樣服務(wù)就變成了無(wú)狀態(tài)的,服務(wù)器集群也很好擴(kuò)展。

【JWT令牌結(jié)構(gòu)】

在緊湊的形式中,JSON Web Tokens由dot(.)分隔的三個(gè)部分組成,它們是:

  • Header 頭
  • Payload 有效載荷
  • Signature 簽名

因此,JWT通常如下所示:

  xxxxx.yyyyy.zzzzz

1.Header 頭

標(biāo)頭通常由兩部分組成:令牌的類型,即JWT,以及正在使用的簽名算法,例如HMAC SHA256或RSA。

例如:

{
 "alg": "HS256",
 "typ": "JWT"
}

然后,這個(gè)JSON被編碼為Base64Url,形成JWT的第一部分。

2.Payload有效載荷

Payload 部分也是一個(gè) JSON 對(duì)象,用來(lái)存放實(shí)際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個(gè)官方字段,供選用。

  • iss (issuer):簽發(fā)人
  • exp (expiration time):過(guò)期時(shí)間
  • sub (subject):主題
  • aud (audience):受眾
  • nbf (Not Before):生效時(shí)間
  • iat (Issued At):簽發(fā)時(shí)間
  • jti (JWT ID):編號(hào)

除了官方字段,你還可以在這個(gè)部分定義私有字段,下面就是一個(gè)例子。例如:

{
 "sub": "1234567890",
 "name": "John Doe",
 "admin": true
}

注意,JWT 默認(rèn)是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個(gè)部分。這個(gè) JSON 對(duì)象也要使用 Base64URL 算法轉(zhuǎn)成字符串。

3.Signature 簽名

Signature 部分是對(duì)前兩部分的簽名,防止數(shù)據(jù)篡改。

首先,需要指定一個(gè)密鑰(secret)。這個(gè)密鑰只有服務(wù)器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認(rèn)是 HMAC SHA256),按照下面的公式產(chǎn)生簽名。

HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)

簽名用于驗(yàn)證消息在此過(guò)程中未被更改,并且,在使用私鑰簽名的令牌的情況下,它還可以驗(yàn)證JWT的發(fā)件人是否是它所聲稱的人?! ?/p>

把他們?nèi)齻€(gè)全部放在一起

輸出是三個(gè)由點(diǎn)分隔的Base64-URL字符串,可以在HTML和HTTP環(huán)境中輕松傳遞,而與基于XML的標(biāo)準(zhǔn)(如SAML)相比更加緊湊。

下面顯示了一個(gè)JWT,它具有先前的頭和​​有效負(fù)載編碼,并使用機(jī)密簽名。

如果您想使用JWT并將這些概念付諸實(shí)踐,您可以使用jwt.io Debugger來(lái)解碼,驗(yàn)證和生成JWT。

【JSON Web令牌如何工作?】

在身份驗(yàn)證中,當(dāng)用戶使用其憑據(jù)成功登錄時(shí),將返回JSON Web令牌。由于令牌是憑證,因此必須非常小心以防止出現(xiàn)安全問(wèn)題。一般情況下,您不應(yīng)該將令牌保留的時(shí)間超過(guò)要求。

每當(dāng)用戶想要訪問(wèn)受保護(hù)的路由或資源時(shí),用戶代理應(yīng)該使用承載模式發(fā)送JWT,通常在Authorization標(biāo)頭中。標(biāo)題的內(nèi)容應(yīng)如下所示:

Authorization: Bearer <token>

在某些情況下,這可以是無(wú)狀態(tài)授權(quán)機(jī)制。服務(wù)器的受保護(hù)路由將檢查Authorization標(biāo)頭中的有效JWT,如果存在,則允許用戶訪問(wèn)受保護(hù)資源。如果JWT包含必要的數(shù)據(jù),則可以減少查詢數(shù)據(jù)庫(kù)以進(jìn)行某些操作的需要,盡管可能并非總是如此。

如果在標(biāo)Authorization頭中發(fā)送令牌,則跨域資源共享(CORS)將不會(huì)成為問(wèn)題,因?yàn)樗皇褂胏ookie。

下圖顯示了如何獲取JWT并用于訪問(wèn)API或資源:

應(yīng)用程序向授權(quán)服務(wù)器請(qǐng)求授權(quán)校驗(yàn)用戶身份,校驗(yàn)成功,返回token應(yīng)用程序使用訪問(wèn)令牌訪問(wèn)受保護(hù)的資源【ASP.Net Core 集成JWT】

前面我們介紹了JWT的原理,下面我們?cè)赼sp.net core實(shí)際項(xiàng)目中集成JWT。

首先我們新建一個(gè)Demo asp.net core 空web項(xiàng)目

添加數(shù)據(jù)訪問(wèn)模擬api,ValuesController

其中api/value1是可以直接訪問(wèn)的,api/value2添加了權(quán)限校驗(yàn)特性標(biāo)簽 [Authorize]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Demo.Jwt.Controllers
{
  [ApiController]
  public class ValuesController : ControllerBase
  {
    [HttpGet]
    [Route("api/value1")]
    public ActionResult<IEnumerable<string>> Get()
    {
      return new string[] { "value1", "value1" };
    }

    [HttpGet]
    [Route("api/value2")]
    [Authorize]
    public ActionResult<IEnumerable<string>> Get2()
    {
      return new string[] { "value2", "value2" };
    }
  }
}

添加模擬登陸,生成Token的api,AuthController

這里模擬一下登陸校驗(yàn),只驗(yàn)證了用戶密碼不為空即通過(guò)校驗(yàn),真實(shí)環(huán)境完善校驗(yàn)用戶和密碼的邏輯。

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;

namespace Demo.Jwt.Controllers
{
  [Route("api/[controller]")]
  [ApiController]
  public class AuthController : ControllerBase
  {
    [AllowAnonymous]
    [HttpGet]
    public IActionResult Get(string userName, string pwd)
    {
      if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(pwd))
      {
        var claims = new[]
        {
          new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
          new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
          new Claim(ClaimTypes.Name, userName)
        };
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(
          issuer: Const.Domain,
          audience: Const.Domain,
          claims: claims,
          expires: DateTime.Now.AddMinutes(30),
          signingCredentials: creds);

        return Ok(new
        {
          token = new JwtSecurityTokenHandler().WriteToken(token)
        });
      }
      else
      {
        return BadRequest(new { message = "username or password is incorrect." });
      }
    }
  }
}

Startup添加JWT驗(yàn)證的相關(guān)配置

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Text;


namespace Demo.Jwt
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
      //添加jwt驗(yàn)證:
      services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
          options.TokenValidationParameters = new TokenValidationParameters
          {
            ValidateIssuer = true,//是否驗(yàn)證Issuer
            ValidateAudience = true,//是否驗(yàn)證Audience
            ValidateLifetime = true,//是否驗(yàn)證失效時(shí)間
            ClockSkew = TimeSpan.FromSeconds(30),
            ValidateIssuerSigningKey = true,//是否驗(yàn)證SecurityKey
            ValidAudience = Const.Domain,//Audience
            ValidIssuer = Const.Domain,//Issuer,這兩項(xiàng)和前面簽發(fā)jwt的設(shè)置一致
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey))//拿到SecurityKey
          };
        });

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
      ///添加jwt驗(yàn)證
      app.UseAuthentication();

      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }

      app.UseMvc(routes =>
      {
        routes.MapRoute(
          name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
      });
    }
  }
}

最后把代碼里面用到的一些相關(guān)常量也粘貼過(guò)來(lái),Const.cs

namespace Demo.Jwt
{
  public class Const
  {
    /// <summary>
    /// 這里為了演示,寫死一個(gè)密鑰。實(shí)際生產(chǎn)環(huán)境可以從配置文件讀取,這個(gè)是用網(wǎng)上工具隨便生成的一個(gè)密鑰
    /// </summary>
    public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";
    public const string Domain = "http://localhost:5000";
  }
}

到這里,已經(jīng)是我們項(xiàng)目的所有代碼了。

如果需要完整的項(xiàng)目代碼,Github地址:https://github.com/sevenTiny/Demo.Jwt

【JWT測(cè)試】

我們找一個(gè)趁手的工具,比如fiddler,然后把我們的web站點(diǎn)運(yùn)行起來(lái)

首先調(diào)用無(wú)權(quán)限的接口:http://localhost:5000/api/value1

正確地返回了數(shù)據(jù),那么接下來(lái)我們測(cè)試JWT的流程

1. 無(wú)權(quán)限

首先我們什么都不加調(diào)用接口:http://localhost:5000/api/value2

返回了狀態(tài)碼401,也就是未經(jīng)授權(quán):訪問(wèn)由于憑據(jù)無(wú)效被拒絕。 說(shuō)明JWT校驗(yàn)生效了,我們的接口收到了保護(hù)。

2.獲取Token

調(diào)用模擬登陸授權(quán)接口:http://localhost:5000/api/Auth?userName=zhangsan&pwd=123

這里的用戶密碼是隨便寫的,因?yàn)槲覀兡M登陸只是校驗(yàn)了下非空,因此寫什么都能通過(guò)

成功得到了響應(yīng)

然后我們得到了一個(gè)xxx.yyy.zzz 格式的 token 值。我們把token復(fù)制出來(lái)

3.在剛才401的接口請(qǐng)求HEADER中添加JWT的參數(shù),把我們的token加上去

再次調(diào)用我們的模擬數(shù)據(jù)接口,但是這次我們加了一個(gè)HEADER:http://localhost:5000/api/value2

把內(nèi)容粘出來(lái)

User-Agent: Fiddler
Host: localhost:5000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOiIxNTYwMzQ1MDIxIiwiZXhwIjoxNTYwMzQ2ODIxLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiemhhbmdzYW4iLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAifQ.x7Slk4ho1hZc8sR8_McVTB6VEYLz_v-5eaHvXtIDS-o

這里需要注意Bearer 后面是有一個(gè)空格的,然后就是我們上一步獲取到的token

嗯,沒(méi)有401了,成功返回了數(shù)據(jù)

4.JWT的Token過(guò)期

我們且倒一杯開水,坐等30分鐘(我們代碼中設(shè)置的過(guò)期時(shí)間),然后再次調(diào)用數(shù)據(jù)接口:http://localhost:5000/api/value2

又變成了401,我們看下詳細(xì)的返回?cái)?shù)據(jù)

這里有標(biāo)注,錯(cuò)誤描述 token過(guò)期,說(shuō)明我們?cè)O(shè)置的token過(guò)期時(shí)間生效了

【結(jié)束】

到這里,我們JWT的簡(jiǎn)介以及asp.net core 集成JWT已經(jīng)完美完成,當(dāng)然了這只是一個(gè)demo,在實(shí)際的應(yīng)用中需要補(bǔ)充和完善的地方還有很多。

如果想要完整項(xiàng)目源碼的,可以參考地址:https://github.com/sevenTiny/Demo.Jwt

如果有幸能幫助到你,高抬貴手點(diǎn)個(gè)star吧~

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • .Net Core Cors中間件的深入講解

    .Net Core Cors中間件的深入講解

    這篇文章主要給大家介紹了關(guān)于.Net Core Cors中間件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Ajax Throws Sys.WebForms.PageRequestManagerErrorException with Response.Redirect的解決方法

    Ajax Throws Sys.WebForms.PageRequestManagerErrorException wi

    注冊(cè)腳本: ScriptManager.RegisterStartupScript(this, typeof(string), "Message", "alert('error message');", true); 即可解決,困惑了我一下午。
    2008-11-11
  • 詳解ASP.NET七大身份驗(yàn)證方式以及解決方案

    詳解ASP.NET七大身份驗(yàn)證方式以及解決方案

    這篇文章主要為大家詳細(xì)介紹了ASP.NET七大身份驗(yàn)證方式以及解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-08-08
  • .NET CORE HttpClient的使用方法

    .NET CORE HttpClient的使用方法

    這篇文章主要給大家介紹了關(guān)于.NET CORE HttpClient的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用.NET CORE具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Asp.Net中的數(shù)據(jù)源概述與配置及實(shí)例代碼

    Asp.Net中的數(shù)據(jù)源概述與配置及實(shí)例代碼

    數(shù)據(jù)綁定分為數(shù)據(jù)源和數(shù)據(jù)綁定控件兩部分,數(shù)據(jù)綁定控件通過(guò)數(shù)據(jù)源來(lái)獲得數(shù)據(jù);接下來(lái)本文將分別介紹下數(shù)據(jù)源/數(shù)據(jù)綁定控件/ObjectDataSource
    2013-02-02
  • aspnetpager重寫url(偽靜態(tài))配置實(shí)例

    aspnetpager重寫url(偽靜態(tài))配置實(shí)例

    這幾天要用到AspNetPager來(lái)做偽靜態(tài)分頁(yè),找了些資料并把修改過(guò)程記錄下來(lái)。
    2013-04-04
  • 使用ajax局部刷新gridview進(jìn)行數(shù)據(jù)綁定示例

    使用ajax局部刷新gridview進(jìn)行數(shù)據(jù)綁定示例

    很多用戶都有這樣需求,比如:點(diǎn)擊按鈕,刷新 GridView 中的數(shù)據(jù),而不是這個(gè)頁(yè)面刷新。使用簡(jiǎn)單的 XMLHttpRequest就可以直接實(shí)現(xiàn)
    2014-02-02
  • LINQ教程之LINQ簡(jiǎn)介

    LINQ教程之LINQ簡(jiǎn)介

    這篇文章介紹了語(yǔ)言集成查詢LINQ,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • asp.net 生成數(shù)字和字母組合的隨機(jī)數(shù)

    asp.net 生成數(shù)字和字母組合的隨機(jī)數(shù)

    asp.net下生成數(shù)字跟字母組合的隨機(jī)數(shù),提高驗(yàn)證安全。
    2009-03-03
  • .Net MVC將Controller數(shù)據(jù)傳遞到View

    .Net MVC將Controller數(shù)據(jù)傳遞到View

    這篇文章介紹了.Net MVC將Controller數(shù)據(jù)傳遞到View的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03

最新評(píng)論

司法| 许昌市| 淮安市| 抚松县| 得荣县| 泽库县| 德令哈市| 武邑县| 盖州市| 黎城县| 乌鲁木齐县| 博罗县| 当雄县| 洞口县| 桑植县| 四子王旗| 克拉玛依市| 公安县| 迁西县| 武胜县| 郯城县| 通道| 双牌县| 女性| 聂拉木县| 马山县| 延寿县| 平乡县| 名山县| 阳曲县| 凤冈县| 廊坊市| 杂多县| 井冈山市| 娱乐| 怀集县| 安康市| 保康县| 蒲江县| 温泉县| 乌拉特前旗|