JWT 토큰을 디코딩하는 방법은 무엇입니까?


103

이 라이브러리가 어떻게 작동하는지 이해할 수 없습니다. 제발 도와 주 시겠어요?

다음은 내 간단한 코드입니다.

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

        var jsonToken = handler.ReadToken(stream);
    }

이것은 오류입니다.

문자열은 Base64UrlEncodedHeader.Base64UrlEndcodedPayload.OPTIONAL, Base64UrlEncodedSignature '형식의 압축 JSON 형식이어야합니다.

jwt.io 웹 사이트 에서 스트림을 복사하면 정상적으로 작동합니다. :)


1
jwt, io 사이트에서 디코딩하지만 서명이 없으므로 유효하지 않습니다.
Crowcoder


1
이 중복 된 질문입니다 ...하지만 버전 라이브러리의 사용자가 사용하기 때문에 답변이 다른 당신이 맞아요을 @MichaelFreidgeim
Cooxkie

답변:


179

해결책을 찾았지만 결과를 전송하는 것을 잊었습니다.

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

다음을 사용하여 클레임을받을 수 있습니다.

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

2
먼저 tokenS.Claims를 클레임 목록으로 캐스팅해야했습니다. ((List<Claim>)tokenS.Claims).ForEach(a => Console.WriteLine(a.Type.ToString() + " " + a.Value));
Rinaldi Segecin

12
다음을 수행 할 수도 있습니다. handler.ReadJwtToken (tokenJwtReponse.access_token);
Thabiso Mofokeng

14
이것이 분명해야하는데 미안하지만 어디 tokenJwtReponse.access_token에서 왔습니까?
Jeff Stapleton

4
tokenJwtReponse.access_token의 출처는 어디입니까?
3iL

4
다른 사람들이 이미 질문했듯이 "tokenJwtReponse.access_token"은 어디에서 왔습니까? 대답에는 정의 나 선언이 없기 때문에 많은 사람들이 대답을 쓸모없고 무의미하게 만듭니다.
Zeek2

35

new JwtSecurityTokenHandler().ReadToken("") 반환합니다 SecurityToken

new JwtSecurityTokenHandler().ReadJwtToken("") 반환합니다 JwtSecurityToken

사용하는 방법을 변경하면 위의 답변에서 캐스트를 피할 수 있습니다.


16

암호화 토큰을 생성하는 데 사용 된 비밀 문자열이 필요합니다. 이 코드는 나를 위해 작동합니다.

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

나중에 매개 변수 handler.ReadToken(token) as SecurityToken로 재 할당 할 때 왜 전화 out합니까? ValidateToken실패하고 원래 값이 유지 될 가능성이 있습니까?
krillgar

오른쪽 krillgar는 SecurityToken에 nesessary 캐스트 아니다
파투 밀라노

ValidateToken은 만료를 확인합니까? 아니면 디코딩 후 본인 확인을해야합니까?
computrius

9

.net 코어 jwt 패키지를 사용하여 클레임을 사용할 수 있습니다.

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

그런 다음 콘텐츠 추출

 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

cooxkie 응답 및 dpix 응답을 확장 하면 jwt 토큰 (예 : AD FS에서받은 access_token)을 읽을 때 jwt 토큰의 클레임을 "context.AuthenticationTicket.Identity"의 클레임과 병합 할 수 있습니다. jwt 토큰과 동일한 클레임 집합이 있습니다.

설명하기 위해 OpenID Connect를 사용하는 인증 코드 흐름에서 사용자가 인증 된 후 인증 컨텍스트를 제공하는 SecurityTokenValidated 이벤트를 처리 한 다음이를 사용하여 access_token을 jwt 토큰으로 읽은 다음 " access_token에있는 토큰을 사용자 ID의 일부로받은 표준 클레임 목록과 병합합니다.

    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);
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.