天天看點

.NetCore的Toekn驗證(附源碼)

先簡單說下JSON Web Token, 然後使用.NET Core内置的JWT驗證機制.

Demo Source Code

AspNetCore JwtBearer Source Code

JSON Web Token

是什麼

  1. JSON Web Token(JWT)是一個開放标準(RFC 7519),它定義了一種緊湊且獨立的方式,用于在各方之間作為JSON對象安全地傳輸資訊。

    資料格式為: Header.Payload.Signature

  2. 生成JWT Token

    JWT的資料簽名(Signature)是對Payload中的資料, 按照Header中指定的加密算法, 加上Server端的密鑰進行簽名生成的.

    • Signature = Payload + Algorithm(Header) + Security(私有)
    • 通過簽名反推出密鑰的可能性很小, 并且密鑰是Server端私有的, 可以定期更換

使用

JWT多用來驗證請求的有效性

下面是簡單的使用流程

  1. 使用者post{username, password}到server, 請求token, server生成後傳回token
  2. 得到token後, client端儲存token: cookie/sessionStorage/localStorage
  3. 以後每當發起請求, 将token放到請求頭: headers: { ‘Authorization’:

    token

    },
  4. server收到請求後, 會根據密鑰及token中的payload生成新的signature并與token的中signature進行對比, 二者一緻則驗證通過

優勢

  1. token的自驗證性,減輕了服務端壓力

    server通過JWT的header, payload和signature就可以驗證使用者, 不需要再去查詢資料庫

  2. JWT不僅可以用于認證,也可以用于交換資訊。有效使用JWT,可以降低伺服器查詢資料庫的次數

    JWT的payload中可以存儲使用者名, 權限, 過期時間等非安全資訊, 解析token本身就可以取得

  3. JWT的自驗證性, 非常适合單頁面程式, 多點登入
  4. 通過将token放在請求頭并使用https通路, 防範跨站腳本攻擊(xss)和跨站攻擊(csrf)
  5. 通過生成refresh token驗證access token的實效性, 控制access token的有效時間, 解決無法回收token通路權限的問題

劣勢

  1. 因為自驗證性, 無法及時回收通路權限, token一旦被分發, 就會一直有效, 可以通過減少生效時間使用

.NET Core的JWT驗證機制

.NET Core的JWT驗證機制基于authentication中間件, 注入JWT服務後, 需要authenrize的請求都會使用token驗證

Demo Source Code

AspNetCore JwtBearer Source Code

  1. 注入内置的JWT service
public void ConfigureServices(IServiceCollection services)
{
	  
	services.AddAuthentication(x =>
		{
			x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
			x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
		})
		.AddJwtBearer(x =>
		{
			x.RequireHttpsMetadata = false;
			x.TokenValidationParameters = new TokenValidationParameters
			{
				ValidateIssuerSigningKey = true,
				IssuerSigningKey = new SymmetricSecurityKey("your secret key"),
				ValidateIssuer = false,
				ValidateAudience = false
			};
		});
}		
           
  1. 生成有效的token
var tokenDescriptor = new SecurityTokenDescriptor
	{
		Subject = new ClaimsIdentity(new[]
		{
			new Claim("your token payload")
		}),
		// token的有效時間
		Expires = DateTime.UtcNow.AddMinutes(),
		SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
			SecurityAlgorithms.HmacSha256Signature)
	};
           

var tokenHandler = new JwtSecurityTokenHandler();

result = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));

4. 通過屬性标簽[Authorize]添加token驗證的請求

[Authorize]支援class級别和接口級别的指定

[Authorize]
public class RepairController : ControllerBase
[Authorize]
[HttpGet("data")]
public ActionResult Get()
           

繼續閱讀