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


102

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

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

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

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



다음은 Google 인증서를 가져오고 토큰을 확인하는 방법에 대한 실제 답변입니다.- stackoverflow.com
questions

답변:


148

패키지 내에는에서 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-Native App to REST 서비스-Authentication with ACS via Browser Dialog"라는 개발자 샘플 의 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

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


3
답변 해 주셔서 감사합니다. 그렇다면 ClaimsIdentity가 있으면 공개 키에 대해 어떻게 확인할 수 있습니까? 특히 공개 키 ( gstatic.com/authtoolkit/cert/gitkit_cert.pem ) 에 대해 Google ID 도구 키트 JWT를 확인하려고합니다
w.brian

4
내 대답을 업데이트했습니다. 이에 대한 전체 소스를 넣을 수는 없지만 적절한 개발자 샘플의 방향을 알려주었습니다. 도움이되기를 바랍니다.
Mike Goodwin

4
@ w.brian-저도 똑같이하려고합니다. 해독 할 수있는 토큰과 확인하려는 공개 키가 있지만 이러한 샘플을 살펴 보더라도 어떻게 수행하는지 확인하기가 어렵습니다. 어떤 코드가 실제로 도움이되었는지에 대한 포인터가 있습니까? 감사.
Barguast

27

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

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

업데이트 : base64 urlsafe 인코딩 / 디코딩을 수행하는 방법에 어려움을 겪고있는 사람들은 다른 SO 질문 과 wiki 및 RFC 를 참조하십시오.


2
좋은 대답입니다. : 여기 HMAC 기반 서명을 표시하기 때문에, 그것은 HMAC 검증을 구현하는 라이브러리의 몇 가지 중요한 취약점을 알고 있어야 이해 할 수 있지만 여기 Auth0 사이트에 설명 된대로 auth0.com/blog/2015/03/31/...
Sudhanshu 미 슈라

2
이것이 최선의 답이라고 생각합니다. 영업 이익은 구체적으로 어떤 명확한 예를 들어이 문서 주소 .. JWT에 정보를 요청
webworm

15
이 답변은 설명하고하는 방법을 보여줍니다 EN 코드 JWT 질문에 대해 매우 명확 때 코딩. 이것은 좋은 대답 일 수 있지만 완전히 다른 질문에 대한 대답 입니다.
Deltics

2
@Deltics 토큰을 디코딩하기 위해 인코딩 알고리즘을 다시 작성하는 데 컴퓨터 과학 학위조차도 필요하지 않다고 생각합니다. 어떻게 인코딩을 이해한다면 - 어떻게 디코딩에 대한 이해
Regfor

33
"답변"의 개념은 누군가가 어떤 종류의 역의도 퍼즐을 풀 것을 기대하여 퍼즐을 던지는 것이 아니라 질문에 답하는 것입니다. Bedsides, 인코딩 방법을 안다는 것은 단순히 키를 사용하여 자신의 서명을 서명하는 것과는 달리 타사 토큰을 처리하고 서명을 확인하기 위해 키를 검색하는 것도 포함 할 수 있으므로 디코딩 방법도 알고 있다는 의미 는 아닙니다 . 어떤 경우에도 않는 대답 하지 실제로는 정의에 의해 질문에 대답은 하지 은 " 더 좋은 일에 비해"대답 하지 내가 응답 한에 관찰되는가.
Deltics
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.