golang-jwt / jwt

Go implementation of JSON Web Tokens (JWT).
https://golang-jwt.github.io/jwt/
MIT License
6.98k stars 335 forks source link

Let KeyFunc take Context as parameter #362

Closed EmilioMirasola closed 1 week ago

EmilioMirasola commented 10 months ago

I'm currently facing an issue where our company has an authorization server where users are authenticated. This server signs tokens using private/public key pairs ans distribute keys in JWK format.

When my particular ressource server needs to fetch the public keys, we would like to trace our requests to the authorization server. To trace the requests we need the context to be passed to the keyfunc. Otherwise we can't provide the request with the traceId.

Currently, we have made a workaround where we new up a transient scoped struct in which we pass in our context (among other dependencies like a key cache) into. This struct then implements type Keyfunc func(*Token) (interface{}, error), and from the implementation it is then possible to get the context of the current request.

It would be great if KeyFunc could take a context as an argument, so we can trace requests to our authorization server without having to wrap the KeyFunc implementation in a struct.

oxisto commented 10 months ago

Unfortunately, that is not possible without breaking the API compatibility. Your approach sounds a little bit like I would do that also. I would probably use an anonymous function that binds the a ctx coming from an outer scope into it and then execute the actual key func in it

func doMiddlewareStuff(ctx context.Context) {
  jwt.ParseWithClaims(..., func(*Token) (interface{}, error) {
    // I can just access ctx here 
    key, err := doSomebackendCallWith(ctx)
    return key
 } 
}
EmilioMirasola commented 10 months ago

Yeah I know about the API compatibility. It could be a feature for new major version.

I didn't think about the above solution. It actually might be what I would do instead. I'd love to abstract it away from my middleware scope, but maybe I have to do it like this 😊

MicahParks commented 7 months ago

@EmilioMirasola I would encourage you to take a look at:

These packages can help you keep a local, auto-refreshing, cache of JWK. The keyfunc package specifically is designed to work with the github.com/golang-jwt/jwt project. The auto-refreshing portion is a background goroutine that will exit if the context.Context in the options ends.