How to verify a JWT Token from AWS Cognito in Go?

喜欢而已 提交于 2020-04-13 07:16:04

问题


How can I validate and get info from a JWT received from Amazon Cognito?

I have setup Google authentication in Cognito, and set the redirect uri to to hit API Gateway, I then receive a code which I POST to this endpoint:

https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

To receive the JWT token, in a RS256 format. I am now struggling to validate, and parse the token in Golang. I’ve tried to parse it using jwt-go, but it appears to support HMAC instead by default and read somewhere that they recommend using frontend validation instead. I tried a few other packages and had similar problems.

I came across this answer here: Go Language and Verify JWT but assume the code is outdated as that just says panic: unable to find key.

jwt.io can easily decode the key, and probably verify too. I’m not sure where the public/secret keys are as Amazon generated the token, but from what I understand I need to use a JWK URL to validate too? I’ve found a few AWS specific solutions, but they all seem to be hundreds of lines long. Surely it isn’t that complicated in Golang is it?


回答1:


Public keys for Amazon Cognito

As you already guessed, you'll need the public key in order to verify the JWT token.

https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html#amazon-cognito-user-pools-using-tokens-step-2

Download and store the corresponding public JSON Web Key (JWK) for your user pool. It is available as part of a JSON Web Key Set (JWKS). You can locate it at https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

Parse keys and verify token

That JSON file structure is documented in the web, so you could potentially parse that manually, generate the public keys, etc.

But it'd probably be easier to just use a library, for example this one: https://github.com/lestrrat-go/jwx

And then jwt-go to deal with the JWT part: https://github.com/dgrijalva/jwt-go

You can then:

1) Download and parse the public keys JSON using the first library

keySet, err := jwk.Fetch(THE_COGNITO_URL_DESCRIBED_ABOVE)

2) When parsing the token with jwt-go, use the "kid" field from the JWT header to find the right key to use

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    if _, ok := token.Method.(*jwt.SigningMethodRS256); !ok {
        return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
    }
    kid, ok := token.Header["kid"].(string)
    if !ok {
        return nil, errors.New("kid header not found")
    }
    keys := keySet.LookupKeyID(kid);
    if len(keys) == 0 {
         return nil, fmt.Errorf("key %v not found", kid)
    }
    return keys[0].Materialize()        
})


来源:https://stackoverflow.com/questions/56905995/how-to-verify-a-jwt-token-from-aws-cognito-in-go

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!