2017-04-18 54 views
8

JWT'yi kullanan asp.net çekirdeğini kullanarak bir web API uygulaması aşamasındayım. Öğrenmeye çalıştığım gibi IdentityServer4 gibi üçüncü taraf bir çözüm kullanmıyorum.JWT Yenileme Jetonları asp.net core web api'de (3. taraf) nasıl uygulanır?

Çalışmak için JWT yapılandırmasını aldım, ancak JWT'nin süresi dolduğunda yenileme jetonlarını nasıl uygulayacağımı anladım.

Aşağıda, Configure yöntemimde startup.cs içinde bulunan bazı örnek kodlar yer almaktadır.

app.UseJwtBearerAuthentication(new JwtBearerOptions() 
{ 
    AuthenticationScheme = "Jwt", 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    TokenValidationParameters = new TokenValidationParameters() 
    { 
     ValidAudience = Configuration["Tokens:Audience"], 
     ValidIssuer = Configuration["Tokens:Issuer"], 
     ValidateIssuerSigningKey = true, 
     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])), 
     ValidateLifetime = true, 
     ClockSkew = TimeSpan.Zero 
    } 
}); 

Aşağıda, JWT'yi oluşturmak için kullanılan Denetleyici yöntemi verilmiştir. Test amaçları için son kullanma tarihi 30 saniyeye ayarlıyorum.

[Route("Token")] 
    [HttpPost] 
    public async Task<IActionResult> CreateToken([FromBody] CredentialViewModel model) 
    { 
     try 
     { 
      var user = await _userManager.FindByNameAsync(model.Username); 

      if (user != null) 
      { 
       if (_hasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success) 
       { 
        var userClaims = await _userManager.GetClaimsAsync(user); 

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

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwt.Key)); 
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 

        var token = new JwtSecurityToken(
          issuer: _jwt.Issuer, 
          audience: _jwt.Audience, 
          claims: claims, 
          expires: DateTime.UtcNow.AddSeconds(30), 
          signingCredentials: creds 
         ); 

        return Ok(new 
        { 
         access_token = new JwtSecurityTokenHandler().WriteToken(token), 
         expiration = token.ValidTo 
        }); 
       } 
      } 
     } 
     catch (Exception) 
     { 

     } 

     return BadRequest("Failed to generate token."); 
    } 

Bazı yönlendirme için çok minnettar olurdum.

+0

kodu belirteçleri yenilemez erişim belirteçleri kimlik doğrulaması için de uygundur: Aşağıdaki

mutlu yolu için sözde kodudur. Erişim belirteçleri oluşturduğunuz kodu paylaşabilir misiniz? – naslund

+0

Elbette, JWT'leri oluşturmak için kullanılan kodu ekledim. – DJDJ

cevap

7

Her şeyden önce bir yenileme belirteci oluşturmanız ve bir yerde kalmanız gerekir. Bunun nedeni, gerekirse onu geçersiz hale getirebilmenizdir. Bir erişim belirteci olarak aynı kalıbı takip edecekseniz - tüm verilerin belirtecin içinde yer alması durumunda - yanlış ellerde biten bir belirteç, yenileme belirtecinin kullanım ömrü boyunca yeni erişim belirteçleri oluşturmak için kullanılabilir. gerçekten uzun bir zaman olabilir.

Peki, hangi halinin devam etmesi gerekiyor? Kolay tahmin edilemeyen bazı türlerin benzersiz bir tanımlayıcısına ihtiyacınız var, bir GUID gayet başarılı olacak. Yeni bir erişim belirteci, büyük olasılıkla bir kullanıcı adı verebilmek için verilere de ihtiyacınız var. Bir kullanıcı adına sahip olmak için daha sonra VerifyHashedPassword (...) parçasını atlayabilirsin, ancak geri kalan kısmı için aynı mantığı takip et.

Bir yenileme belirteci edinmek için normalde "offline_access" alanını kullanırsınız; bu, belirteç isteği yaparken modelinizde (CredentialViewModel) sağladığınız bir şeydir. Normal erişim belirteci isteğinin tersine, şimdi kullanıcı adınızı ve şifrenizi sağlamanız gerekmez, bunun yerine yenileme belirteci yerine. Yenileme jetonu ile istek alırken, kalıcı tanımlayıcıyı arar ve bulunan kullanıcı için bir belirteç yayınlarsınız. Yayınladığınız

[Route("Token")] 
[HttpPost] 
public async Task<IActionResult> CreateToken([FromBody] CredentialViewModel model) 
{ 
    if (model.GrantType is "refresh_token") 
    { 
     // Lookup which user is tied to model.RefreshToken 
     // Generate access token from the username (no password check required) 
     // Return the token (access + expiration) 
    } 
    else if (model.GrantType is "password") 
    { 
     if (model.Scopes contains "offline_access") 
     { 
      // Generate access token 
      // Generate refresh token (random GUID + model.username) 
      // Persist refresh token 
      // Return the complete token (access + refresh + expiration) 
     } 
     else 
     { 
      // Generate access token 
      // Return the token (access + expiration) 
     } 
    } 
} 
+0

Girişiniz için teşekkür ederiz! – DJDJ