.net使用jwt進行身份認證的流程記錄
目錄
- 什麼是身份認證和鑑權
- jwt工作流程
- token是如何生成的
- jwt三部分
- jwt是如何保證資料不會被篡改的
- .net webapi 的 demo
- 總結
什麼是身份認證和鑑權
舉個例子
假設有這麼一個小區,小區只允許持有通行證的人進入,陌生人如果想直接進入小區會被保安攔住,他必須先辦理通行證才會被允許進入
類比身份認證和鑑權體系
一個人要訪問我的一個機密的介面,我首先需要知道你是誰,搞清楚你是誰的過程就是身份認證,如果我搞不清楚你是誰,那你就是陌生人,身份認證失敗。
身份認證通過,並不一定就允許訪問我的機密的介面,因為身份認證只是讓我知道了你是誰,但是我還不知道你有沒有訪問我介面的許可權,因此還需要進行鑑權。
鑑權就是在身份認證的基礎上來查閱你是否有訪問某介面的許可權,有許可權才允許訪問。
jwt工作流程
在基於jwt策略的身份認證和鑑權體系中
機密的介面只允許有token的人訪問
它的工作流程是這樣的
首先你向授權伺服器請求一個token,伺服器對你進行校驗,校驗成功則給你一個token
之後你每次訪問介面都帶上這個伺服器給的token,以此來證明你經過了校驗並有權訪問這個介面,這樣你才能被放行
token是如何生成的
token是由伺服器生成的,
使用者請求token的時候,拿著自己的一些資訊給伺服器
伺服器有它的金鑰基於一些加密演算法對使用者的資訊進行加密,之後生成一個token給使用者。
jwt三部分
jwt的toke由三部分,header密文,payload密文和簽名
header
header存放兩個資訊
1.宣告加密的演算法
2.宣告型別
像這樣:
{
“alg”: “HS256”,
“typ”: “JWT”
}
payload
存放一些自定義的資訊,例如使用者的個人資訊,例如使用者名稱。
注意:不要存密碼等敏感資訊,因為token可以被解密成明文。
signature
簽名,由伺服器使用它的金鑰對header和payload進行加密後的結果
jwt是如何保證資料不會被篡改的
伺服器對token解密獲得header、payload和signature,再拿著自己的金鑰對header和payload進行加密,看加密結果是否和解密出來的signature相等,如果相等說明資料沒有被篡改,如果不等說明資料已被篡改
由於伺服器的金鑰是不公開的,因此認為簽名不能偽造,也就是說,別人無法通過header、payload來加密得到一個伺服器認可的token
.net webapi 的 demo
為了簡化,這裡只做身份認證,也就是說登入的使用者就有權訪問所有介面了
在Starup.cs中開啟身份認證服務並指定策略為jwt
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,www.cppcns.com ValidateAudience = true,ValidateLifetime = true,ValidateIssuerSigningKey = true,ValidAudience = "xxx",ValidIssuer = "xxx",IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("bc47a26eb9a59406057dddd62d0898f4")),};
});
還需要使用身份認證中介軟體
在需要進行身份認證的介面或控制器上加上特性[Authorize]
還需要實現登入邏輯,準備一個Get介面用於測試
Controller程式碼為:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
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;
namespace JwtTest.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public ActionResult Get()
{
return Ok("ok");
}
[HttpPowww.cppcns.comst]
[AllowAnonymohttp://www.cppcns.comus]
public ActionResult Login([FromBody] LoginViewModel loginViewModel)
{
//驗證使用者名稱密碼是否正確,錯誤則不進行後續操作
{
//驗證邏輯在此省略
}
//驗證成功則繼續執行後面程式碼,來生成token
//claims是關於使用者的一些資訊,這部分資訊將放在payload中,由於token可以被解密,因此不要把密碼放進去
var claims = new Claim[]
{
new Claim(ClaimTypes.Name,loginViewModel.Name)
};
//指定生成token所需要的金鑰
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("bc47a26eb9a59406057dddd62d0898f4"));
//指定數字簽名需要使用的金鑰和演算法
SigningCredentials credentials = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);
//生成token
JwtSecurityToken token = new JwtSecurityToken(issuer: "xxx",audience: "xxx",claims: claims,notBefore: DateTime.Now,//token生效時間
expires: DateTime.Now.AddMinutes(5),//token有效時間
signingCredentials: credentials);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
}
}
進行測試:
不登入直接訪問Get會報401
訪問Login會返回一個token
要想成功訪問Get,需要帶上這個token,如何使請求帶上這個token呢?
可以藉助postman,
輸入Get介面的路徑
將Authorization型別設定為Bearer Token,之後將生成的token貼上到右邊
訪問成功
總結
到此這篇關於.net使用jwt進行身份認證的文章就介紹到這了,更www.cppcns.com多相關.net用jwt身份認證內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!