Wie dekodiere ich JWT Token?


101

Ich verstehe nicht, wie diese Bibliothek funktioniert. Kannst du mir bitte helfen ?

Hier ist mein einfacher Code:

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

        var jsonToken = handler.ReadToken(stream);
    }

Dies ist der Fehler:

Die Zeichenfolge muss im kompakten JSON-Format vorliegen: Base64UrlEncodedHeader.Base64UrlEndcodedPayload.OPTIONAL, Base64UrlEncodedSignature '.

Wenn Sie den Stream auf der Website jwt.io kopieren , funktioniert er einwandfrei :)


1
Die Website jwt, io dekodiert es, aber es gibt keine Signatur, sodass es ungültig ist.
Crowcoder


1
@ MichaelFreidgeim Sie haben Recht, es ist doppelte Frage ... aber die Antworten sind aufgrund der von Ihnen verwendeten
Versionsbibliothek

Antworten:


174

Ich habe die Lösung gefunden, ich habe nur vergessen, das Ergebnis zu besetzen:

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

Ich kann Ansprüche erhalten mit:

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

2
Ich musste zuerst tokenS.Claims als Liste der Ansprüche wirken. ((List<Claim>)tokenS.Claims).ForEach(a => Console.WriteLine(a.Type.ToString() + " " + a.Value));
Rinaldi Segecin

12
Sie können auch Folgendes tun: handler.ReadJwtToken (tokenJwtReponse.access_token);
Thabiso Mofokeng

13
Entschuldigung, wenn dies offensichtlich sein sollte, aber woher kommt tokenJwtReponse.access_tokenes?
Jeff Stapleton

3
Woher kommt tokenJwtReponse.access_token?
3.

4
Wie andere bereits gefragt haben: Woher kommt "tokenJwtReponse.access_token"? Die Antwort enthält keine Definition oder Erklärung dafür, was die Antwort für viele von uns nutzlos und bedeutungslos macht.
Zeek2

33

new JwtSecurityTokenHandler().ReadToken("") wird a zurückgeben SecurityToken

new JwtSecurityTokenHandler().ReadJwtToken("") wird a zurückgeben JwtSecurityToken

Wenn Sie nur die von Ihnen verwendete Methode ändern, können Sie die Besetzung in der obigen Antwort vermeiden


16

Sie benötigen die geheime Zeichenfolge, mit der das Verschlüsselungstoken generiert wurde. Dieser Code funktioniert für mich:

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;
    }

Warum rufen Sie auf, handler.ReadToken(token) as SecurityTokenwenn Sie es später als outParameter neu zuweisen? Gibt es eine Möglichkeit, die ValidateTokenfehlschlägt und der ursprüngliche Wert bleibt?
Krillgar

Richtiger Krillgar ist nicht unbedingt die Besetzung von SecurityToken
Pato Milán

Überprüft ValidateToken den Ablauf? Oder muss ich das selbst validieren, nachdem es dekodiert wurde?
Computrius

9

Unter Verwendung von .net Core-JWT-Paketen sind die Ansprüche verfügbar:

[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;
    }
}

6
  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);

Dann extrahieren Sie den Inhalt

 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

Die Ausweitung auf cooxkie Antwort und DPix Antwort, wenn Sie lesen gerade ein jwt Token (wie ein access_token von AD FS empfangen wird ), können Sie die Ansprüche in der jwt Token verschmelzen mit den Ansprüchen von „context.AuthenticationTicket.Identity“ Das könnte nicht haben die gleichen Ansprüche wie das JWT-Token.

Zur Veranschaulichung: In einem Authentifizierungscode-Fluss mit OpenID Connect können Sie nach der Authentifizierung eines Benutzers das Ereignis SecurityTokenValidated behandeln , das Ihnen einen Authentifizierungskontext bereitstellt. Anschließend können Sie das access_token als JWT-Token lesen und dann " Zusammenführen von "Token, die sich im access_token befinden, mit der Standardliste der Ansprüche, die als Teil der Benutzeridentität empfangen wurden:

    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);
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.