中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在.Net Core中利用JWT進行授權

發布時間:2020-12-01 14:54:45 來源:億速云 閱讀:215 作者:Leah 欄目:開發技術

怎么在.Net Core中利用JWT進行授權?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

什么是JWT?

JSON Web令牌(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間安全地傳輸信息作為JSON對象。由于此信息是經過數字簽名的,因此可以被驗證和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對對JWT進行簽名。

盡管可以對JWT進行加密以提供雙方之間的保密性,但我們將重點關注已簽名的令牌。簽名的令牌可以驗證其中包含的聲明的完整性,而加密的令牌則將這些聲明隱藏在其他方的面前。當使用公鑰/私鑰對對令牌進行簽名時,簽名還證明只有持有私鑰的一方才是對其進行簽名的一方。由于缺乏安全性,所以不能把如密碼等敏感信息放在令牌中。

什么時候應該使用JWT?

以下是JSON Web令牌有用的一些情況:

  • 授權:這是使用JWT的最常見方案。一旦用戶登錄,每個后續請求將包括JWT,從而允許用戶訪問該令牌允許的路由,服務和資源。單一登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。

  • 信息交換:JSON Web令牌是在各方之間安全傳輸信息的好方法。因為可以對JWT進行簽名(例如,使用公鑰/私鑰對),所以您可以確定發件人是他們所說的人。此外,由于簽名是使用標頭和有效負載計算的,因此您還可以驗證內容是否未被篡改。

JWT結構是什么?

JSON Web令牌以緊湊的形式由三部分組成,這些部分由點(.)分隔,分別是:

  • 標頭

  • 有效載荷

  • 簽名


因此,JWT通常如下所示。

xxxxx.yyyyy.zzzzz

標頭:通常由兩部分組成,令牌類型和使用的簽名算法。

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

有效載荷:有三種說明類型,預定義聲明、公共聲明和私有聲明。聲明名稱僅是三個字符,因為JWT是緊湊的

  • 預定義聲明:包括iss(發出者), exp(到期時間), sub(主題), aud(受眾)等,是推薦的但是不是強制的可以沒有。

  • 公共聲明:公共聲明,這個部分可以隨便定義,但是要注意和 IANA JSON Web Token 沖突。

  • 私有聲明:這個部分是共享被認定信息中自定義部分。

簽名:要創建簽名部分,您必須獲取編碼的標頭,編碼的有效負載,機密,標頭中指定的算法,并對其進行簽名。

例如,如果要使用HMAC SHA256算法,則將通過以下方式創建簽名:

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

簽名用于驗證消息在此過程中沒有更改,并且對于使用私鑰進行簽名的令牌,它還可以驗證JWT的發送者是它所說的真實身份。

組合在一起如下為輸出是三個由點分隔的Base64-URL字符串:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUyMDAiLCJhdWQiOlsiYXBpIiwiYXBpIl0sIkd1aWQiOiIzM2NhZmJkNS1jZWEyLTRjOWMtYWZlYS01MDYyZjM3YWUyOTAiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOlsic3lzdGVtIiwiYWRtaW4iXSwiZXhwIjoxNjA2NjU2NjI0fQ.
JvDHuowbOnWiyxMIFc9gG5rw1LSSc0xx68L31oRfxS0

如何使用JWT

每當用戶想要訪問受保護的路由或資源時,用戶代理都應發送JWT,通常使用承載模式在Authorization標頭中發送JWT 。標頭的內容應如下所示:

Authorization: Bearer <token>

在某些情況下,這可以是無狀態授權機制。服務器的受保護路由將在Authorization標頭中檢查有效的JWT ,如果存在,則將允許用戶訪問受保護的資源。如果JWT包含必要的數據,則可以減少查詢數據庫中某些操作的需求,盡管這種情況并非總是如此。

如果令牌是在Authorization標頭中發送的,則跨域資源共享(CORS)不會成為問題,因為它不使用cookie。

下圖顯示了如何獲取JWT并將其用于訪問API或資源:

怎么在.Net Core中利用JWT進行授權

  1. 應用程序或客戶端向授權服務器請求授權。這是通過不同的授權流程之一執行的。例如,典型的符合OpenID Connect的Web應用程序將/oauth/authorize使用授權代碼流通過端點。

  2. 授予授權后,授權服務器會將訪問令牌返回給應用程序。

  3. 該應用程序使用訪問令牌來訪問受保護的資源(例如API)。

請注意,使用簽名的令牌,令牌中包含的所有信息都會暴露給用戶或其他方,即使他們無法更改它。這意味著您不應將機密信息放入令牌中。

.net core的JWT驗證授權

我們直接新建一個.net core webapi的項目,我這里版本是3.1的

1. 先使用nuget安裝:Microsoft.AspNetCore.Authentication.JwtBearer。注意版本和.net core版本的兼容。net5的支持5.0.0+的版本,否則就用對應可以用的低版本吧。

2. 在appsettings.json配置文件中寫好我們的 JWT 的配置參數如下:

 "Jwt": {
 "Secret": "your-256-bit-secret",
 "Iss": "https://localhost:44355",
 "Aud": "api"
 }

3. 在Startup.cs的ConfigureServices方法中添加授權認證如下:

var jwtConfig = Configuration.GetSection("Jwt");
//生成密鑰
var symmetricKeyAsBase64 = jwtConfig.GetValue<string>("Secret");
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
var signingKey = new SymmetricSecurityKey(keyByteArray);
//認證參數
services.AddAuthentication("Bearer")
 .AddJwtBearer(o =>
 {
  o.TokenValidationParameters = new TokenValidationParameters
  {
   ValidateIssuerSigningKey = true,//是否驗證簽名,不驗證的畫可以篡改數據,不安全
   IssuerSigningKey = signingKey,//解密的密鑰
   ValidateIssuer = true,//是否驗證發行人,就是驗證載荷中的Iss是否對應ValidIssuer參數
   ValidIssuer = jwtConfig.GetValue<string>("Iss"),//發行人
   ValidateAudience = true,//是否驗證訂閱人,就是驗證載荷中的Aud是否對應ValidAudience參數
   ValidAudience = jwtConfig.GetValue<string>("Aud"),//訂閱人
   ValidateLifetime = true,//是否驗證過期時間,過期了就拒絕訪問
   ClockSkew = TimeSpan.Zero,//這個是緩沖過期時間,也就是說,即使我們配置了過期時間,這里也要考慮進去,過期時間+緩沖,默認好像是7分鐘,你可以直接設置為0
   RequireExpirationTime = true,
  };
 });

在Configure方法中添加 app.UseAuthentication() 和 app.UseAuthorization() 注意位置需要放置的位置:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
 if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}
 app.UseHttpsRedirection();
 app.UseRouting();
 app.UseAuthentication();
 app.UseAuthorization();
 app.UseEndpoints(endpoints =>{ endpoints.MapControllers();});
}

4. 生成jwt令牌,在默認生成的控制器 WeatherForecastController 中添加如下生成令牌的方法:

[HttpPost]
public IActionResult Authenticate()
{
 var jwtConfig = Configuration.GetSection("Jwt");
 //秘鑰,就是標頭,這里用Hmacsha256算法,需要256bit的密鑰
 var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.GetValue<string>("Secret"))), SecurityAlgorithms.HmacSha256);
 //Claim,JwtRegisteredClaimNames中預定義了好多種默認的參數名,也可以像下面的Guid一樣自己定義鍵名.
 //ClaimTypes也預定義了好多類型如role、email、name。Role用于賦予權限,不同的角色可以訪問不同的接口
 //相當于有效載荷
 var claims = new Claim[] {
    new Claim(JwtRegisteredClaimNames.Iss,jwtConfig.GetValue<string>("Iss")),
    new Claim(JwtRegisteredClaimNames.Aud,jwtConfig.GetValue<string>("Aud")),
    new Claim("Guid",Guid.NewGuid().ToString("D")),
    new Claim(ClaimTypes.Role,"system"),
    new Claim(ClaimTypes.Role,"admin"),
 };
 SecurityToken securityToken = new JwtSecurityToken(
  signingCredentials: securityKey,
  expires: DateTime.Now.AddMinutes(2),//過期時間
  claims: claims
 );
 //生成jwt令牌
 return Content(new JwtSecurityTokenHandler().WriteToken(securityToken));
}

5. 使用jwt控制接口的訪問,我們在一個接口上添加一個特性 [Authorize(Roles ="admin")],表示需要有admin這個角色的jwt令牌才能訪問,沒有roles參數的話表示只要是可用的令牌就可以訪問,多個role角色可以疊加多個特性:

[HttpGet]
[Authorize(Roles = "admin")]
[Authorize(Roles = "system")]
public IEnumerable<WeatherForecast> Get()
{
 var rng = new Random();
 return Enumerable.Range(1, 5).Select(index => new WeatherForecast
 {
  Date = DateTime.Now.AddDays(index),
  TemperatureC = rng.Next(-20, 55),
  Summary = Summaries[rng.Next(Summaries.Length)]
 })
 .ToArray();
}

6.測試,然后我們用postman就可以測試了,可以看到非常成功有數據。

怎么在.Net Core中利用JWT進行授權 

怎么在.Net Core中利用JWT進行授權

進階

認證的時候可以添加事件,如下面的認證失敗事件、接收參數事件可以獲取url上的參數作為令牌而不是通過http的請求頭的Authorization。

services.AddAuthentication("Bearer")
 .AddJwtBearer(o =>
 {
  o.Events = new JwtBearerEvents()
  {
   OnMessageReceived = context =>
   {
    context.Token = context.Request.Query["access_token"];
    return Task.CompletedTask;
   },
   OnAuthenticationFailed = context =>
   {
    // 如果過期,則把<是否過期>添加到,返回頭信息中
    if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
    {
     context.Response.Headers.Add("Token-Expired", "true");
    }
    return Task.CompletedTask;
   }
  };
 });

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

弥勒县| 苍溪县| 景东| 安化县| 万山特区| 来宾市| 长沙市| 义马市| 泰宁县| 新疆| 肥东县| 临安市| 镇安县| 武隆县| 福清市| 阿克陶县| 利川市| 泸西县| 保亭| 凤台县| 东丰县| 于都县| 嵩明县| 通海县| 罗江县| 孟州市| 文成县| 伊金霍洛旗| 温宿县| 皋兰县| 洛浦县| 宜昌市| 滨海县| 大名县| 红原县| 双鸭山市| 宁晋县| 清远市| 平顺县| 广宁县| 阳原县|