0

I found some solutions to verify Cognito JWT, but the solution using Cognit User Pool, I use the custom provider so I have no User Pool ID, I can not found the way to get https://cognito-idp.us-east-1.amazonaws.com/{{poolId}}/.well-known/jwks.json, finally I found this article have a JWK URL about OpenID so I try to use the URL, not luck, I got the error message.

2020/02/24 19:01:58 failed to parse JWK: failed to extract from map: failed to construct key from map: failed to extract key from map: failed to get required key n: failed to base64 decode key n: illegal base64 data at input byte 64

Below is my code.

package main

import(
    "log"
    "github.com/lestrrat-go/jwx/jwk"
)

func main() {
    set, err := jwk.FetchHTTP("https://cognito-identity.amazonaws.com/.well-known/jwks_uri")
    if err != nil {
      log.Printf("failed to parse JWK: %s", err)
      return
    }

    log.Println(set)
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Shawn OY
  • 13
  • 3
  • Does this answer your question? [Where can I retrieve the public key for an Cognito Identity Pool?](https://stackoverflow.com/questions/54839790/where-can-i-retrieve-the-public-key-for-an-cognito-identity-pool) – Mike Patrick Feb 25 '20 at 18:18
  • No, it's not the point, thanks. – Shawn OY Feb 26 '20 at 11:05
  • I found the issue is the package can not parse base64 and it's fixed. https://github.com/lestrrat-go/jwx/pull/137 – Shawn OY Feb 26 '20 at 11:07

1 Answers1

0

If you switch to github.com/golang-jwt/jwt/v4, you can follow this example.

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/golang-jwt/jwt/v4"

    "github.com/MicahParks/keyfunc"
)

func main() {

    // Get the JWKs URL from your AWS region and userPoolId.
    //
    // See the AWS docs here:
    // https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
    regionID := ""   // TODO Get the region ID for your AWS Cognito instance.
    userPoolID := "" // TODO Get the user pool ID of your AWS Cognito instance.
    jwksURL := fmt.Sprintf("https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json", regionID, userPoolID)

    // Create the keyfunc options. Use an error handler that logs. Refresh the JWKs when a JWT signed by an unknown KID
    // is found or at the specified interval. Rate limit these refreshes. Timeout the initial JWKs refresh request after
    // 10 seconds. This timeout is also used to create the initial context.Context for keyfunc.Get.
    refreshInterval := time.Hour
    refreshRateLimit := time.Minute * 5
    refreshTimeout := time.Second * 10
    refreshUnknownKID := true
    options := keyfunc.Options{
        RefreshErrorHandler: func(err error) {
            log.Printf("There was an error with the jwt.KeyFunc\nError:%s\n", err.Error())
        },
        RefreshInterval:   &refreshInterval,
        RefreshRateLimit:  &refreshRateLimit,
        RefreshTimeout:    &refreshTimeout,
        RefreshUnknownKID: &refreshUnknownKID,
    }

    // Create the JWKs from the resource at the given URL.
    jwks, err := keyfunc.Get(jwksURL, options)
    if err != nil {
        log.Fatalf("Failed to create JWKs from resource at the given URL.\nError:%s\n", err.Error())
    }

    // Get a JWT to parse.
    jwtB64 := "eyJraWQiOiJmNTVkOWE0ZSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJLZXNoYSIsImF1ZCI6IlRhc2h1YW4iLCJpc3MiOiJqd2tzLXNlcnZpY2UuYXBwc3BvdC5jb20iLCJleHAiOjE2MTkwMjUyMTEsImlhdCI6MTYxOTAyNTE3NywianRpIjoiMWY3MTgwNzAtZTBiOC00OGNmLTlmMDItMGE1M2ZiZWNhYWQwIn0.vetsI8W0c4Z-bs2YCVcPb9HsBm1BrMhxTBSQto1koG_lV-2nHwksz8vMuk7J7Q1sMa7WUkXxgthqu9RGVgtGO2xor6Ub0WBhZfIlFeaRGd6ZZKiapb-ASNK7EyRIeX20htRf9MzFGwpWjtrS5NIGvn1a7_x9WcXU9hlnkXaAWBTUJ2H73UbjDdVtlKFZGWM5VGANY4VG7gSMaJqCIKMxRPn2jnYbvPIYz81sjjbd-sc2-ePRjso7Rk6s382YdOm-lDUDl2APE-gqkLWdOJcj68fc6EBIociradX_ADytj-JYEI6v0-zI-8jSckYIGTUF5wjamcDfF5qyKpjsmdrZJA"

    // Parse the JWT.
    token, err := jwt.Parse(jwtB64, jwks.KeyFunc)
    if err != nil {
        log.Fatalf("Failed to parse the JWT.\nError:%s\n", err.Error())
    }

    // Check if the token is valid.
    if !token.Valid {
        log.Fatalf("The token is not valid.")
    }

    log.Println("The token is valid.")
}
Micah Parks
  • 1,504
  • 1
  • 10
  • 22