You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The keyfunc.OptionsCtx field allows users to pass a context to functions which load JWKS. According to the field's description, this context is used by keyfunc's background refresh. When the context expires or is canceled, the background goroutine will end. As far as I can tell, this is not the case. jwks.ctx and jwks.cancel are overridden at the end of keyfunc.Get, after options have been applied.
package main
import (
"context"
_ "embed""fmt""log""net/http""net/http/httptest""sync/atomic""time""github.com/MicahParks/keyfunc/v2"
)
//go:embed example_jwks.jsonvarjwksJSONstringfuncmain() {
// Create a test server to serve an example JWKS.varcounteruint64server:=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r*http.Request) {
atomic.AddUint64(&counter, 1)
fmt.Printf("JWKS endpoint called %d time(s)\n", counter)
_, err:=w.Write([]byte(jwksJSON))
iferr!=nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}))
deferserver.Close()
jwksURL:=server.URL// Create a context that, when cancelled, *should* end the JWKS background refresh goroutine.ctx, cancel:=context.WithCancel(context.Background())
// Create the keyfunc options. Use the previously created context and refresh JWKS every second.options:= keyfunc.Options{
Ctx: ctx,
RefreshInterval: time.Second,
}
// Create the JWKS from the resource at the given URL.jwks, err:=keyfunc.Get(jwksURL, options)
iferr!=nil {
log.Fatalf("Failed to create JWKS from resource at the given URL.\nError: %s", err.Error())
}
// Sleep for 3s.// Expectation: See 3 JWKS refreshes.time.Sleep(3*time.Second)
fmt.Println("---")
// End the background refresh goroutine.cancel()
// Sleep for 3s.// Expectation: See *no more* JWKS refreshes since the passed context got canceled.time.Sleep(3*time.Second)
fmt.Println("---")
// This will be ineffectual because the line above this canceled the parent context.Context.// This method call is idempotent similar to context.CancelFunc.jwks.EndBackground()
// Sleep for 5s.// Expectation: See *no* JWKS refreshes.time.Sleep(3*time.Second)
fmt.Println("END")
}
Output:
JWKS endpoint called 1 time(s)
JWKS endpoint called 2 time(s)
JWKS endpoint called 3 time(s)
---
JWKS endpoint called 4 time(s)
JWKS endpoint called 5 time(s)
JWKS endpoint called 6 time(s)
---
END
The values might be set to Options.Ctx at this point.
Overriding them causes keyfunc's background refresh goroutine to not end
when Options.Ctx is canceled.
Fix issue: MicahParks#85
The keyfunc.Options
Ctx
field allows users to pass a context to functions which load JWKS. According to the field's description, this context is used by keyfunc's background refresh. When the context expires or is canceled, the background goroutine will end. As far as I can tell, this is not the case.jwks.ctx
andjwks.cancel
are overridden at the end of keyfunc.Get, after options have been applied.Illustration of the unexpected behavior
I've modified the examples/recommended_options program to illustrate the behavior.
Output:
Potential fix:
Output after fix:
The text was updated successfully, but these errors were encountered: