Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing a Spring OAuth 2 JWT payload inside the Resource Server controller?

I'm going through this tutorial on how to setup spring boot oauth with jwt. It covers decoding the JWT token using Angular, but how do we decode it and get access to custom claims inside the Resource Server controller?

For example with JJWT it can be done like this (Based on this article):

    String subject = "HACKER";
    try {
        Jws jwtClaims = 
            Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);

        subject = claims.getBody().getSubject();

        //OK, we can trust this JWT

    } catch (SignatureException e) {

        //don't trust the JWT!
    }

And Spring has a JWTAccessTokenConverter.decode() method, but the javadoc is lacking, and it is protected.

like image 986
Ole Avatar asked Sep 21 '17 01:09

Ole


People also ask

How does resource server validate access token?

A resource server validates such a token by making a call to the authorisation server's introspection endpoint. The token encodes the entire authorisation in itself and is cryptographically protected against tampering. JSON Web Token (JWT) has become the defacto standard for self-contained tokens.

What is resource server in OAuth2?

In the context of OAuth 2.0, a resource server is an application that protects resources via OAuth tokens. These tokens are issued by an authorization server, typically to a client application. The job of the resource server is to validate the token before serving a resource to the client.

Where is the JWT token store in spring boot?

It is stored in-memory by default.


1 Answers

Here is how I am accessing custom JWT claims in Spring Boot:

1) Get Spring to copy JWT content into Authentication:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends ResourceServerConfigurerAdapter{

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices( createTokenServices() );
    }

    @Bean
    public DefaultTokenServices createTokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore( createTokenStore() );
        return defaultTokenServices;
    }

    @Bean
    public TokenStore createTokenStore() {               
        return new JwtTokenStore( createJwtAccessTokenConverter() );
    }

    @Bean
    public JwtAccessTokenConverter createJwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();     
        converter.setAccessTokenConverter( new JwtConverter() );
        return converter;
    }

    public static class JwtConverter extends DefaultAccessTokenConverter implements JwtAccessTokenConverterConfigurer {

        @Override
        public void configure(JwtAccessTokenConverter converter) {
            converter.setAccessTokenConverter(this);
        }

        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
            OAuth2Authentication auth = super.extractAuthentication(map);
            auth.setDetails(map); //this will get spring to copy JWT content into Authentication
            return auth;
        }
    }
}

2) Access token content anywhere in your code:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();        
Object details = authentication.getDetails();        
if ( details instanceof OAuth2AuthenticationDetails ){
    OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails)details;

    Map<String, Object> decodedDetails = (Map<String, Object>)oAuth2AuthenticationDetails.getDecodedDetails();

    System.out.println( "My custom claim value: " + decodedDetails.get("MyClaim") );
}  
like image 193
tsolakp Avatar answered Oct 17 '22 14:10

tsolakp