.Net Core が Jwt 認証を使用する方法
ジュットとは何ですか?
JWT は、2 者間で安全な情報を転送するための簡潔で URL セーフな宣言仕様です。オープン標準 (RFC 7519) として、JWT は、通信当事者間で情報を Json オブジェクトの形式で安全に送信するための簡潔で自己完結型のメソッドを定義します。デジタル署名が存在するため、この情報には信頼性があり、HMAC アルゴリズムまたは RSA 公開鍵と秘密鍵のペアを使用して JWT に署名できます。
Jwtの使用シナリオ
- 承認。これは、JWT を使用する最も一般的なシナリオです。ユーザーがログインすると、後続の各リクエストに JWT が含まれるため、ユーザーはそのトークンで許可されたルート、サービス、リソースにアクセスできるようになります。シングル サインオンは、オーバーヘッドがほとんどなく、さまざまなドメイン間で簡単に使用できるため、現在 JWT が広く使用されている機能です。
- 情報交換: JSON Web トークンは、当事者間で情報を安全に転送するための優れた方法です。JWT は署名できるため (公開鍵と秘密鍵のペアを使用するなど)、送信者が本人であることを確信できます。また、ヘッダーとペイロードを用いて署名を計算するため、内容が改ざんされていないことも検証できます。
Jwtの使い方は?
ユーザーが保護されたルートまたはリソースにアクセスしたいときは常に、ユーザー エージェントは、通常はベアラー モードを使用して Authorization ヘッダーで JWT を送信する必要があります。ヘッダーの内容は次のようになります。
Authorization: Bearer <token>
.Net Core 検証認可
- 新しい .Net core webapi プロジェクトを作成する
- appsetting.json でパラメータを構成する
"Jwt": {
"Secret": "your-256-bit-secret",
"Iss": "https://localhost:44390",
"Aud": "api"
}
3. nuget パッケージ Microsoft.AspNetCore.Authentication.JwtBearer をインストールします。.net core バージョンとのバージョン互換性に注意してください。net5 はバージョン 5.0.0 以降をサポートしています。それ以外の場合は、対応する下位バージョンを使用してください。
4. 次のように、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.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-Exired", "true");
}
return Task.CompletedTask;
}
};
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,
};
});
5. 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();});
}
6. jwt トークンを生成し、コントローラー HomeController にトークンを生成する次のメソッドを追加します。
[HttpPost]
public IActionResult get()
{
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));
}
7. 最後に、Swagger で最終結果をデバッグします。
エンディング