New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JwtAccessTokenConverter: Wrong verifier used if jwt.key-uri is not reachable #734

Open
weiserr opened this Issue Apr 1, 2016 · 8 comments

Comments

Projects
None yet
8 participants
@weiserr

weiserr commented Apr 1, 2016

While creating and configuring the JwtAccessTokenConverter in the ResourceServerTokenServicesConfiguration#jwtTokenEnhancer() method the verifier key and verifier will fallback to the default one (created while instanciating the class) if not able to contact the /oauth/token_key URL of the authorization server.

I don't see how this is practical in a productive setup and I am not quite sure on how to interprete the following warning:

Failed to fetch token key (you may need to refresh when the auth server is back)

...shall one restart the application after the url appears to be accessible from machine it runs on?

For me the real benefits of the /oauth/token_key endpoint are / would be the following:

  • not having to configure the public key in every resource server
  • the possibility to change the key-pair at the authoriazation server (e.g. in case the validity of the key-pair expires)
@dsyer

This comment has been minimized.

Member

dsyer commented May 8, 2016

I think it's better to let the app come up and fail later, so you can diagnose what is going on, but I suppose that might be a matter of taste. In a production system the token key endpoint has to be highly available, and I don't think that's a problem we can solve in this library. Maybe you would prefer to fail hard and prevent the app from running at all?

@weiserr

This comment has been minimized.

weiserr commented May 13, 2016

Hi Dave

IMHO letting the application fail fast would be somewhat more comprehensible as falling back to default token validation instead of JWT token validation in a resource server. Right now if the authorization server is not up (e.g. 503/504) the application starts but all calls by clients with a valid JWT token will fail as the JWT is not evaluated anymore (fallback to regular validation).

Are there any means to detect whether the aurization server could be reached and configured at startup as defined in the application.yml like for example:

  • log messages
  • registerable hook / callback / strategy (bean)

Cheers

@arnabmitra

This comment has been minimized.

arnabmitra commented Jun 3, 2016

I would have to agree with @weiserr, it would be nice to have it fail fast rather than falling back to some other alternatives.This would make it much easier to diagnose a problem if it ever that the Auth server was down(Yes there should be bigger problems at this time)

@mrsarm

This comment has been minimized.

mrsarm commented Sep 11, 2016

Regardless what strategy is better, how we can override the default behavior? I'm using Spring Boot 1.4.

@mrsarm

This comment has been minimized.

mrsarm commented Sep 12, 2016

Working around this I saw that you can configure the key in a static way in the property file using the security.oauth2.resource.jwt.key-value. But if you configure both properties key-value and key-uri Spring will get the token from key-value, ignoring the key-uri value. It would more clever in this case try to get the token from key-uri, and if it fails for any reason (404, timeout, ...) then take the value from key-value.

Again, it would be useful if all these behavior can be overwritten.

@damnhandy

This comment has been minimized.

damnhandy commented Feb 14, 2017

I'm glad I'm not the only one seeing this. It is odd that the verifier doesn't fail with a bit more spectacular error. Seeing an invalid token response such as Cannot convert access token to JSON makes it a bit more challenging to diagnose when the issue is is with the verifier. Complicating matters, the log messages are only displayed when debug logging is enabled.

@dsyer while I do agree that the the key should be highly available, but that ignores start up sequencing is also an issue. Even if the token_key URI is HA, the services are always going to be in a funky state if they start up before the authorization server. The way the library works now is that we get what appears to be a bogus public key on startup if the token key can't be reached. This is not helpful with environments like Docker compose where we don't have guaranteed sequencing of when services are available.

What would be more useful is leaving some type of indicator that the token_key URI could not be reached. I'd even go as far to put the resource server is a state that is not functional until the key can be retrieved. We could either have a retry mechanism or the first call to verify the JWT forces a refresh of the token_key. The way it works right now is very confusing.

@walterjs

This comment has been minimized.

walterjs commented Apr 18, 2017

I agree that it doesn't really make sense to have an unusable resource server if the key-uri is not available. I've created a pull request to simply remove the try-catch around the retrieval for your consideration:
spring-projects/spring-boot#8924

@nikhilabhiman

This comment has been minimized.

nikhilabhiman commented Nov 29, 2017

I get the same issue every now and then, It's on-off behavior

{ "error": "invalid_token", "error_description": "Cannot convert access token to JSON" }

It works in the morning when I do fresh checkout of the project, again it fails after doing gradle clean build of the project. Sometimes, it works when I checkout a new branch with the same code copy.? What is the exact root cause for this? When failed with above error, I decode the token, and it's a valid JWT Token. How to troubleshoot this?. I thought it's something to do with gradle cache. After refreshing, sometimes it works and it doesn't. If there was a jar file version issue, how did it work the first time. This happens when I enable @ResourceServer annotation and want to make my resource protected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment