JWT Token kodu nasıl çözülür?


109

Bu kütüphanenin nasıl çalıştığını anlamıyorum. Bana yardım edebilir misiniz, lütfen ?

İşte benim basit kodum:

public void TestJwtSecurityTokenHandler()
    {
        var stream =
            "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJJU1MiLCJzY29wZSI6Imh0dHBzOi8vbGFyaW0uZG5zY2UuZG91YW5lL2NpZWxzZXJ2aWNlL3dzIiwiYXVkIjoiaHR0cHM6Ly9kb3VhbmUuZmluYW5jZXMuZ291di5mci9vYXV0aDIvdjEiLCJpYXQiOiJcL0RhdGUoMTQ2ODM2MjU5Mzc4NClcLyJ9";
        var handler = new JwtSecurityTokenHandler();

        var jsonToken = handler.ReadToken(stream);
    }

Bu hata:

Dizenin, şu biçimde olan kompakt JSON biçiminde olması gerekir: Base64UrlEncodedHeader.Base64UrlEndcodedPayload.OPTIONAL, Base64UrlEncodedSignature '.

Akışı jwt.io web sitesinde kopyalarsanız, sorunsuz çalışır :)


1
jwt, io sitesi şifresini çözer, ancak imza olmadığı için geçersizdir.
Crowcoder


1
@MichaelFreidgeim haklısın bu yinelenen soru ... ama kullandığınız sürüm kitaplığı nedeniyle cevaplar farklı
Cooxkie

Yanıtlar:


186

Çözümü buldum, sadece sonucu yayınlamayı unuttum:

var stream ="[encoded jwt]";  
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = handler.ReadToken(stream) as JwtSecurityToken;

Şunu kullanarak Talep alabilirim:

var jti = tokenS.Claims.First(claim => claim.Type == "jti").Value;

2
Önce bir Talep Listesi olarak tokenS.C Claims'i yayınlamam gerekiyordu. ((List<Claim>)tokenS.Claims).ForEach(a => Console.WriteLine(a.Type.ToString() + " " + a.Value));
Rinaldi Segecin

12
Ayrıca şunları da yapabilirsiniz: handler.ReadJwtToken (tokenJwtReponse.access_token);
Thabiso Mofokeng

15
Bunun açık olması gerekiyorsa üzgünüm ama nereden tokenJwtReponse.access_tokengeliyor?
Jeff Stapleton

4
TokenJwtReponse.access_token nereden geliyor?
3iL

5
Başkalarının zaten sorguladığı gibi: "tokenJwtReponse.access_token" nereden geliyor? Yanıtı çoğumuz için yararsız ve anlamsız kılan yanıtta bunun bir tanımı veya beyanı yoktur.
Zeek2

36

new JwtSecurityTokenHandler().ReadToken("") dönecek SecurityToken

new JwtSecurityTokenHandler().ReadJwtToken("") dönecek JwtSecurityToken

Sadece kullandığınız yöntemi değiştirirseniz, yukarıdaki cevapta alçıdan kaçınabilirsiniz.


17

Şifreleme belirteci oluşturmak için kullanılan gizli dizeye ihtiyacınız var. Bu kod benim için çalışıyor:

protected string GetName(string token)
    {
        string secret = "this is a string used for encrypt and decrypt token"; 
        var key = Encoding.ASCII.GetBytes(secret);
        var handler = new JwtSecurityTokenHandler();
        var validations = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
        var claims = handler.ValidateToken(token, validations, out var tokenSecure);
        return claims.Identity.Name;
    }

Daha sonra parametreniz handler.ReadToken(token) as SecurityTokenolarak atarken neden ararsınız out? ValidateTokenBaşarısız olma ve orijinal değerin korunma olasılığı var mı ?
krillgar

Sağ krillgar, SecurityToken'ın kadrosunda yer almıyor
Pato Milán

ValidateToken son kullanma tarihini kontrol ediyor mu? Yoksa kodu çözüldükten sonra bunu kendim doğrulamam mı gerekiyor?
computrius

9

.Net core jwt paketlerini kullanarak, Talepler mevcuttur:

[Route("api/[controller]")]
[ApiController]
[Authorize(Policy = "Bearer")]
public class AbstractController: ControllerBase
{
    protected string UserId()
    {
        var principal = HttpContext.User;
        if (principal?.Claims != null)
        {
            foreach (var claim in principal.Claims)
            {
               log.Debug($"CLAIM TYPE: {claim.Type}; CLAIM VALUE: {claim.Value}");
            }

        }
        return principal?.Claims?.SingleOrDefault(p => p.Type == "username")?.Value;
    }
}

8
  var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
  var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  var claims = new[]
  {
      new Claim(JwtRegisteredClaimNames.Email, model.UserName),
      new Claim(JwtRegisteredClaimNames.NameId, model.Id.ToString()),
  };
  var token = new JwtSecurityToken(_config["Jwt:Issuer"],
      _config["Jwt:Issuer"],
      claims,
      expires: DateTime.Now.AddMinutes(30),
      signingCredentials: creds);

Ardından içeriği çıkarın

 var handler = new JwtSecurityTokenHandler();
 string authHeader = Request.Headers["Authorization"];
 authHeader = authHeader.Replace("Bearer ", "");
 var jsonToken = handler.ReadToken(authHeader);
 var tokenS = handler.ReadToken(authHeader) as JwtSecurityToken;
 var id = tokenS.Claims.First(claim => claim.Type == "nameid").Value;

3

Üzerinde genişletme cooxkie cevap ve DPix okumakta olduğunuz zaman, cevap bir jwt jeton, siz "context.AuthenticationTicket.Identity" dan iddialarla jwt belirteç iddiaları birleştirebilirsiniz (örneğin AD FS alınan bir access_token gibi) o olmayabilir jwt belirteci ile aynı talep kümesine sahiptir.

Açıklamak için, OpenID Connect kullanan bir Kimlik Doğrulama Kodu akışında, bir kullanıcı kimlik doğrulaması yapıldıktan sonra, size bir kimlik doğrulama bağlamı sağlayan SecurityTokenValidated olayını işleyebilir , ardından access_token'ı jwt belirteci olarak okumak için kullanabilirsiniz, sonra bunu yapabilirsiniz " erişim belirtecindeki "belirteçleri" kullanıcı kimliğinin bir parçası olarak alınan standart talep listesiyle birleştirin:

    private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> context)
    {
        //get the current user identity
        ClaimsIdentity claimsIdentity = (ClaimsIdentity)context.AuthenticationTicket.Identity;

        /*read access token from the current context*/
        string access_token = context.ProtocolMessage.AccessToken;

        JwtSecurityTokenHandler hand = new JwtSecurityTokenHandler();
        //read the token as recommended by Coxkie and dpix
        var tokenS = hand.ReadJwtToken(access_token);
        //here, you read the claims from the access token which might have 
        //additional claims needed by your application
        foreach (var claim in tokenS.Claims)
        {
            if (!claimsIdentity.HasClaim(claim.Type, claim.Value))
                claimsIdentity.AddClaim(claim);
        }

        return Task.FromResult(0);
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.