Skip to content
This repository has been archived by the owner on Apr 5, 2022. It is now read-only.

Adapt token forwarding for JWT tokens #85

Closed
timwebster9 opened this issue Dec 14, 2015 · 17 comments
Closed

Adapt token forwarding for JWT tokens #85

timwebster9 opened this issue Dec 14, 2015 · 17 comments

Comments

@timwebster9
Copy link

As described in this Stack Overflow issue, token forwarding will not occur if JWT tokens are being used. Propose the token-forwarding functionality be adapted for use with JWT.

@dsyer
Copy link
Contributor

dsyer commented Dec 15, 2015

I'm not sure where this feature would live actually (here or Spring Boot). I'll give it some thought.

N.B. You can do this already

String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue()
restTemplate.getOAuth2ClientContext().setAccessToken(new DefaultOAuth2AccessToken(token))

@timwebster9
Copy link
Author

OK I'll try that out....thanks.

@timwebster9
Copy link
Author

This works fine BTW....thanks again.

May I ask a related question? I have added some additional details to the User (an email address) via the usual means (extending UserDetails, etc). I then extended JwtTokenAccessConverter so I could override enhance() to add the email address to the 'additional info' property.

After fowarding the token downstream, I can see during authentication that the additional info is indeed present, but when OAuth2AccessToken is converted to an OAuth2Authentication object the additional info is lost (during DefaultTokenServices.loadAuthentication() ).

Is there another way to access this additional information from the token, or do I need to decode it again? thanks...

@dsyer
Copy link
Contributor

dsyer commented Dec 17, 2015

Not sure I follow completely. If the data is in the JWT then you need to extract it in the token services (i.e. inject the same JwtTokenAccessConverter in the resource server).

@timwebster9
Copy link
Author

I only overrode enhance() on the TokenAccessConverter, which I think is only called when the token is created. This happens in the auth server. The 'additional info' is held in a map inside OAuth2AccessToken.getAdditionalInformation(), so I wouldn't think I needed anything special to then extract this, as it's just a map in a non-custom object.

For example, say I'm in a RestController or some other 'business' object and i want to get that email address from the token. I can get the OAuth2Authentication object like this;

((OAuth2Authentication)SecurityContextHolder.getContext().getAuthentication();

But that object doesn't have the additional information - it was lost when the token was decoded.

Also, I don't want to have to introduce or share dependencies in my downstream services (e.g. my customer UserDetails implementation or the Token services)....I just want to be able to get at that 'additional information' map to get the stuff I put there when the token was created.

EDIT: I say the information was 'lost', but it's still in the encoded token itself - I just don't know how I can get at it without decoding it again....

@dsyer
Copy link
Contributor

dsyer commented Dec 17, 2015

I think all the claims in the JWT are in the additional info map by default. Is that not what you see?

@timwebster9
Copy link
Author

I can see them in the OAuth2AccessToken (in the debugger) during authentication, but it's OAuth2Authentication that gets stored in the SecurityContext, and I can't see them in that. The code that 'translates' the token into the authentication object only takes the principal and the authorities (and maybe a couple of other things), but not the additional info.

@timwebster9
Copy link
Author

I got this to work. Some other people on SO had similar problems so I answered the question (mines the second answer):

http://stackoverflow.com/questions/32000501/how-to-custom-principle-object-with-spring-cloud-security/

@ihrigb
Copy link

ihrigb commented Apr 25, 2016

Are there any updates on this?

@dsyer
Copy link
Contributor

dsyer commented Apr 25, 2016

No, if there were I think you'd see them. Feel free to send code.

@ihrigb
Copy link

ihrigb commented Apr 26, 2016

Do you have some hint on which classes are some interesting ones to look at?

@dsyer
Copy link
Contributor

dsyer commented Apr 26, 2016

There are actually 2 issues being discussed here. If you care about token forwarding look at my first comment which shows you exactly how to do it (and apparently you don't even need to do that if using @LoadBalanced rest templates). If you are looking at the other discussion about custom user details, please open another issue in Spring OAuth or Spring Boot (it's nothing to do with this project, and we shouldn't be mixing up discussion in on issue anyway).

@ihrigb
Copy link

ihrigb commented Apr 26, 2016

I was into the first issue about relay access tokens. Load Balanced RestTemplates are created here org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration. At which point is this rest template made aware of any available accesstokens in the SecurityContext? The RestTemplate in org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration$UserInfoRestTemplateConfiguration is seperate and does not belong to the other one.

@dsyer
Copy link
Contributor

dsyer commented Apr 26, 2016

I don't see how a @LoadBalancedTemplate is actually getting a token relay automatically, it was just someone on stackoverflow who said it had worked for him. I think he was wrong. The code from my first comment would be the way to handle it.

@ihrigb
Copy link

ihrigb commented Apr 26, 2016

OK, I agree, just misunderstood your previous comment. Yes I'd handle it the same way you described it in your first comment.

@dsyer
Copy link
Contributor

dsyer commented Sep 8, 2016

Token relay is now working for JWT tokens via an MVC interceptor (see docs for details).

@szantopeter
Copy link
Contributor

szantopeter commented Apr 25, 2017

@dsyer I think there is a bug that affects the JWT token relay functionality. I created a pull request and opened a new issue #123

Until the issue is fixed a workaround is here

@Configuration
public class WorkaroundConfig extends WebMvcConfigurerAdapter {

    @Autowired
    @Qualifier("tokenRelayRequestInterceptor")
    HandlerInterceptor handlerInterceptor;

    @Override
    public void addInterceptors (InterceptorRegistry registry) {
        registry.addInterceptor(handlerInterceptor);
    }

}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants