...

Source file src/github.com/MicahParks/keyfunc/examples/given/main.go

Documentation: github.com/MicahParks/keyfunc/examples/given

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/golang-jwt/jwt/v4"
     9  
    10  	"github.com/MicahParks/keyfunc"
    11  )
    12  
    13  func main() {
    14  	// Get the JWKS URL.
    15  	//
    16  	// This is a sample JWKS service. Visit https://jwks-service.appspot.com/ and grab a token to test this example.
    17  	jwksURL := "https://jwks-service.appspot.com/.well-known/jwks.json"
    18  
    19  	// Create a context that, when cancelled, ends the JWKS background refresh goroutine.
    20  	ctx, cancel := context.WithCancel(context.Background())
    21  
    22  	// Create the given keys.
    23  	hmacSecret := []byte("example secret")
    24  	const givenKID = "givenKID"
    25  	givenKeys := map[string]keyfunc.GivenKey{
    26  		givenKID: keyfunc.NewGivenHMAC(hmacSecret),
    27  	}
    28  
    29  	// Create the keyfunc options. Use an error handler that logs. Refresh the JWKS when a JWT signed by an unknown KID
    30  	// is found or at the specified interval. Rate limit these refreshes. Timeout the initial JWKS refresh request after
    31  	// 10 seconds. This timeout is also used to create the initial context.Context for keyfunc.Get. Add in some given
    32  	// keys to the JWKS.
    33  	//
    34  	// Do not override keys with the same key ID, `kid`, in the remote JWKS. This is the default behavior.
    35  	//
    36  	// For a more complex example where remote keys are overwritten by given keys, see override_test.go.
    37  	options := keyfunc.Options{
    38  		Ctx:              ctx,
    39  		GivenKeys:        givenKeys,
    40  		GivenKIDOverride: false, // Default value.
    41  		RefreshErrorHandler: func(err error) {
    42  			log.Printf("There was an error with the jwt.Keyfunc\nError: %s", err.Error())
    43  		},
    44  		RefreshInterval:   time.Hour,
    45  		RefreshRateLimit:  time.Minute * 5,
    46  		RefreshTimeout:    time.Second * 10,
    47  		RefreshUnknownKID: true,
    48  	}
    49  
    50  	// Create the JWKS from the resource at the given URL.
    51  	jwks, err := keyfunc.Get(jwksURL, options)
    52  	if err != nil {
    53  		log.Fatalf("Failed to create JWKS from resource at the given URL.\nError: %s", err.Error())
    54  	}
    55  
    56  	// Create a JWT signed by the give HMAC key.
    57  	token := jwt.New(jwt.SigningMethodHS256)
    58  	token.Header["kid"] = givenKID
    59  	jwtB64, err := token.SignedString(hmacSecret)
    60  	if err != nil {
    61  		log.Fatalf("Failed to sign a JWT with the HMAC secret.\nError: %s.", err.Error())
    62  	}
    63  
    64  	// Parse and validate a JWT. This one is signed by the given HMAC key.
    65  	token, err = jwt.Parse(jwtB64, jwks.Keyfunc)
    66  	if err != nil {
    67  		log.Fatalf("Failed to parse the JWT signed by the given HMAC key.\nError: %s.", err.Error())
    68  	}
    69  	if !token.Valid {
    70  		log.Fatalf("The token signed by the given HMAC key is not valid.")
    71  	}
    72  	log.Println("The token signed by the given HMAC key is valid.")
    73  
    74  	// Parse and validate a JWT. This one is signed by a non-given key and is expired.
    75  	jwtB64 = "eyJraWQiOiJlZThkNjI2ZCIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJXZWlkb25nIiwiYXVkIjoiVGFzaHVhbiIsImlzcyI6Imp3a3Mtc2VydmljZS5hcHBzcG90LmNvbSIsImlhdCI6MTYzMTM2OTk1NSwianRpIjoiNDY2M2E5MTAtZWU2MC00NzcwLTgxNjktY2I3NDdiMDljZjU0In0.LwD65d5h6U_2Xco81EClMa_1WIW4xXZl8o4b7WzY_7OgPD2tNlByxvGDzP7bKYA9Gj--1mi4Q4li4CAnKJkaHRYB17baC0H5P9lKMPuA6AnChTzLafY6yf-YadA7DmakCtIl7FNcFQQL2DXmh6gS9J6TluFoCIXj83MqETbDWpL28o3XAD_05UP8VLQzH2XzyqWKi97mOuvz-GsDp9mhBYQUgN3csNXt2v2l-bUPWe19SftNej0cxddyGu06tXUtaS6K0oe0TTbaqc3hmfEiu5G0J8U6ztTUMwXkBvaknE640NPgMQJqBaey0E4u0txYgyvMvvxfwtcOrDRYqYPBnA"
    76  	token, err = jwt.Parse(jwtB64, jwks.Keyfunc)
    77  	if err != nil {
    78  		log.Fatalf("Failed to parse the JWT signed by a non-given key in the remote JWKS.\nError: %s.", err.Error())
    79  	}
    80  	if !token.Valid {
    81  		log.Fatalf("The token signed by a non-given key in the remote JWKS is not valid.")
    82  	}
    83  	log.Println("The token signed by a non-given key in the remote JWKS is valid.")
    84  
    85  	// End the background refresh goroutine when it's no longer needed.
    86  	cancel()
    87  
    88  	// This will be ineffectual because the line above this canceled the parent context.Context.
    89  	// This method call is idempotent similar to context.CancelFunc.
    90  	jwks.EndBackground()
    91  }
    92  

View as plain text