IT story

System.IdentityModel.Tokens.Jwt를 사용하여 JWT 토큰 디코딩 및 확인

hot-time 2020. 9. 9. 20:16
반응형

System.IdentityModel.Tokens.Jwt를 사용하여 JWT 토큰 디코딩 및 확인


Json 웹 토큰을 디코딩하기 위해 JWT 라이브러리를 사용해 왔으며 Microsoft의 공식 JWT 구현 인 System.IdentityModel.Tokens.Jwt 로 전환하고 싶습니다 .

문서가 매우 드물기 때문에 JWT 라이브러리로 수행 한 작업을 수행하는 방법을 파악하는 데 어려움을 겪고 있습니다. JWT 라이브러리에는 base64로 인코딩 된 JWT를 가져 와서이를 역 직렬화 할 수있는 JSON으로 변환하는 Decode 메서드가 있습니다. System.IdentityModel.Tokens.Jwt를 사용하여 비슷한 작업을하고 싶지만 상당한 양의 파기 후에 방법을 알 수 없습니다.

그만한 가치는 Google의 ID 프레임 워크와 함께 사용하기 위해 쿠키에서 JWT 토큰을 읽고 있습니다.

어떤 도움을 주시면 감사하겠습니다.


패키지 내에는에서 JwtSecurityTokenHandler파생되는 라는 클래스가 있습니다 System.IdentityModel.Tokens.SecurityTokenHandler. WIF에서 이것은 보안 토큰을 역 직렬화하고 직렬화하는 핵심 클래스입니다.

이 클래스에는 ReadToken(String)base64로 인코딩 된 JWT 문자열을 가져와 JWT를 나타내는를 반환 하는 메서드가 있습니다 SecurityToken.

SecurityTokenHandler또한이 ValidateToken(SecurityToken)당신을 소요 방법 SecurityToken과를 만듭니다 ReadOnlyCollection<ClaimsIdentity>. 일반적으로 JWT ClaimsIdentity의 경우 원본 JWT의 속성을 나타내는 클레임 ​​집합이있는 단일 개체 가 포함됩니다 .

JwtSecurityTokenHandler에 대한 몇 가지 추가 오버로드를 정의합니다. ValidateToken특히 ClaimsPrincipal ValidateToken(JwtSecurityToken, TokenValidationParameters)오버로드가 있습니다. TokenValidationParameters인수는 (목록으로 토큰 서명 인증서를 지정할 수 있습니다 X509SecurityTokens). 그것은 또한으로 JWT 걸리는 과부하가 string오히려 이상을 SecurityToken.

이 작업을 수행하는 코드는 다소 복잡하지만 TokenValidationHandler"ADAL-REST 서비스에 대한 기본 앱-브라우저 대화 상자를 통한 ACS로 인증"이라는 개발자 샘플 의 Global.asax.cx 코드 ( 클래스)에서 찾을 수 있습니다.

http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc

또는 JwtSecurityToken클래스에는 컬렉션을 거치지 않고 포함 된 클레임을 가져 오는 속성 SecurityToken과 같이 기본 클래스 에없는 추가 메서드가 있습니다 . 또한 토큰의 원시 JSON을 가져올 수 있는 객체 를 반환 하는 속성 도 있습니다 . 가장 적절한 접근 방식은 시나리오에 따라 다릅니다.ClaimsClaimsIdentityPayloadJwtPayload

SecurityTokenHandler클래스에 대한 일반 (즉, JWT가 아닌 특정) 문서 는 다음과 같습니다.

http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytokenhandler.aspx

애플리케이션에 따라 JWT 핸들러를 다른 핸들러와 똑같이 WIF 파이프 라인으로 구성 할 수 있습니다.

다양한 유형의 응용 분야에서 사용중인 샘플이 3 개 있습니다.

http://code.msdn.microsoft.com/site/search?f%5B0%5D.Type=SearchText&f%5B0%5D.Value=aal&f%5B1%5D.Type=User&f%5B1%5D.Value=Azure% 20AD % 20Developer % 20Experience % 20Team & f % 5B1 % 5D.Text = Azure % 20AD % 20Developer % 20Experience % 20Team

아마도 하나는 귀하의 요구에 적합하거나 적어도 적응할 수 있습니다.


JWT 토큰 디코딩 및 확인을 위해 일부 라이브러리를 사용하는 이유가 궁금합니다.

인코딩 된 JWT 토큰은 다음 의사 코드를 사용하여 생성 할 수 있습니다.

var headers = base64URLencode(myHeaders);
var claims = base64URLencode(myClaims);
var payload = header + "." + claims;

var signature = base64URLencode(HMACSHA256(payload, secret));

var encodedJWT = payload + "." + signature;

특정 라이브러리 없이는 매우 쉽습니다. 다음 코드 사용 :

using System;
using System.Text;
using System.Security.Cryptography;

public class Program
{   
    // More info: https://stormpath.com/blog/jwt-the-right-way/
    public static void Main()
    {           
        var header = "{\"typ\":\"JWT\",\"alg\":\"HS256\"}";
        var claims = "{\"sub\":\"1047986\",\"email\":\"jon.doe@eexample.com\",\"given_name\":\"John\",\"family_name\":\"Doe\",\"primarysid\":\"b521a2af99bfdc65e04010ac1d046ff5\",\"iss\":\"http://example.com\",\"aud\":\"myapp\",\"exp\":1460555281,\"nbf\":1457963281}";

        var b64header = Convert.ToBase64String(Encoding.UTF8.GetBytes(header))
            .Replace('+', '-')
            .Replace('/', '_')
            .Replace("=", "");
        var b64claims = Convert.ToBase64String(Encoding.UTF8.GetBytes(claims))
            .Replace('+', '-')
            .Replace('/', '_')
            .Replace("=", "");

        var payload = b64header + "." + b64claims;
        Console.WriteLine("JWT without sig:    " + payload);

        byte[] key = Convert.FromBase64String("mPorwQB8kMDNQeeYO35KOrMMFn6rFVmbIohBphJPnp4=");
        byte[] message = Encoding.UTF8.GetBytes(payload);

        string sig = Convert.ToBase64String(HashHMAC(key, message))
            .Replace('+', '-')
            .Replace('/', '_')
            .Replace("=", "");

        Console.WriteLine("JWT with signature: " + payload + "." + sig);        
    }

    private static byte[] HashHMAC(byte[] key, byte[] message)
    {
        var hash = new HMACSHA256(key);
        return hash.ComputeHash(message);
    }
}

토큰 디코딩은 위 코드의 역 버전입니다. 서명을 확인하려면 서명 부분을 계산 된 서명과 동일하게 비교해야합니다.

UPDATE: For those how are struggling how to do base64 urlsafe encoding/decoding please see another SO question, and also wiki and RFCs

참고URL : https://stackoverflow.com/questions/18677837/decoding-and-verifying-jwt-token-using-system-identitymodel-tokens-jwt

반응형