web-dev-qa-db-ja.com

Asp.NET CoreでJWTトークンを破棄/無効化できますか?

ASP.NET CoreおよびASP.NET Core Identityを使用してJWTトークンを生成します。

クライアント側では、私の反応(SPA)アプリがAPIを呼び出してトークンを作成し、サブリクエストにAuthorization: BearertokenFromApiを含めます。

ログアウトしたい場合、どうすればすぐにサーバー側でトークンを期限切れにできますか?

現在、クライアント側でbearトークンを削除するだけで、次のリクエストに含まれませんか?

参照https://blogs.msdn.Microsoft.com/webdev/2017/04/06/jwt-validation-and- authorization-in-asp-net-core /


Startup.csConfigureセクションのコード

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = "MySite",
        ValidAudience = "MySite",
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE")),
        ValidateLifetime = true
    }
});

トークンを作成するためのAPI

[HttpPost("Token")]
public async Task<IActionResult> CreateToken([FromBody] LoginModel model)
{
    try
    {
        var user = await userManager.FindByNameAsync(model.Email);
        if (passwordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success)
        {

            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Email, user.Email)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE"));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                "MySite",
                "MySite",
                claims,
                expires: DateTime.UtcNow.AddMinutes(45),
                signingCredentials: creds);

            return Ok(new
            {
                Token = new JwtSecurityTokenHandler().WriteToken(token),
                Expiration = token.ValidTo,
            });
        }
        return BadRequest();
    }
    catch (Exception ex)
    {
        logger.LogError(ex.ToString());
        return StatusCode((int)HttpStatusCode.InternalServerError);
    }
}
11
Hung Quach

あなたはそれを簡単に期限切れにすることはできず、それの利点のいくつかを失うことなく、またはソリューションを著しく複雑にすることはありません。

最善の策は、アクセストークンの時間を十分に短く(<= 5分)、更新トークンを長時間実行することです。

しかし、本当にすぐに無効にしたい場合は、いくつかのものが必要になります。

  1. トークンの有効期限と同じ長さの期間でトークンが作成されたら、トークンのIDをキャッシュします(アクセストークンと更新トークンの両方)
  2. [ファーム/複数インスタンスの場合] redisなどの分散キャッシュにキャッシュする必要がある
  3. [ファーム/複数インスタンスの場合]メッセージバスを介して(つまり、Redis、RabbitMQ、またはAzure Message Busを使用して)アプリケーションのすべてのインスタンスに伝達する必要があるため、ローカルメモリキャッシュに格納できます(そのため、検証するたびにネットワーク呼び出しを行う)
  4. 認証時に、IDがまだキャッシュ内にあるかどうかを検証する必要があります。そうでない場合は、承認を拒否します(401)
  5. ユーザーがログアウトしたら、キャッシュからアイテムを削除する必要があります。
  6. [ファーム/複数インスタンスの場合]分散キャッシュからアイテムを削除し、すべてのインスタンスにメッセージを送信して、ローカルキャッシュから削除できるようにします

メッセージバス/分散キャッシュを必要としない他のソリューションでは、リクエストごとに認証サーバーに接続する必要があり、JWTトークンの主な利点が失われます。

JWTの主な利点は、JWTが自己完結型であり、Webサービスが検証するために別のサービスを呼び出す必要がないことです。これは、署名を検証することにより(ユーザーは署名を無効にしないとトークンを変更できないため)、トークンの有効期限/オーディエンスによってローカルで検証できます。

12
Tseng