Open mieubrisse opened 4 years ago
@mieubrisse can you add the working code here since I am wondering how to get it working as well...
Sure:
const (
// Key in the Headers hashmap of the token that points to the key ID
keyIdTokenHeaderKey = "kid"
// Header and footer to attach to base64-encoded key data that we receive from Auth0
pubKeyHeader = "-----BEGIN CERTIFICATE-----"
pubKeyFooter = "-----END CERTIFICATE-----"
)
// Provided by Auth0 via https://auth0.com/docs/tokens/json-web-tokens/json-web-key-sets
var RsaPublicKeyBase64 = map[string]string{
"some-key-id1": "MIIDD......",
"some-key-id2": "MIIDD......",
}
token, err := new(jwt.Parser).ParseWithClaims(
tokenStr,
&auth0_authorizer.Auth0TokenClaims{}, // This is a custom claims object
func(token *jwt.Token) (interface{}, error) {
// IMPORTANT: Validating the algorithm per https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, stacktrace.NewError(
"Expected token algorithm '%v' but got '%v'",
jwt.SigningMethodRS256.Name,
token.Header)
}
untypedKeyId, found := token.Header[keyIdTokenHeaderKey]
if !found {
return nil, stacktrace.NewError("No key ID key '%v' found in token header", keyIdTokenHeaderKey)
}
keyId, ok := untypedKeyId.(string)
if !ok {
return nil, stacktrace.NewError("Found key ID, but value was not a string")
}
keyBase64, found := auth0_constants.RsaPublicKeyBase64[keyId]
if !found {
return nil, stacktrace.NewError("No public RSA key found corresponding to key ID from token '%v'", keyId)
}
keyStr := pubKeyHeader + "\n" + keyBase64 + "\n" + pubKeyFooter
// Since the token is RSA (which we validated at the start of this function), the return type of this function actually has to be rsa.PublicKey!
pubKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(keyStr))
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred parsing the public key base64 for key ID '%v'; this is a code bug", keyId)
}
return pubKey, nil
},
)
The non-obvious parts:
rsa.PublicKey
(I only found this by diving through jwt-go
code)Hi @mieubrisse per #462 this repo has been deprecated and migrated to a new organization: https://github.com/golang-jwt/jwt
As stated in golang-jwt/jwt#7, none if the new maintainers will be copying the original contributions of interest to respect the authors, but will rather encourage them to migrate to the new repo (and also check if their contribution is still applicable)
Regards
Related issue: https://github.com/golang-jwt/jwt/issues/58
The major point of confusion comes from what the key func should be returning, since the examples only have HS256 tokens that return a string (but which errors for the RSA alg). I had to do a decent amount of code-diving to discover that the expected type is actually
rsa.PublicKey
.