Skip to content

Consider exposing JwtDecoder configuration #25

Open
@jzheaux

Description

Insofar as JwtDecoder was one of the interface hooks identified for integration with libraries other than Nimbus, we probably should make it easier for folks to swap in their own implementation.

For example, in a previous life, I secured a resource server using the Auth0 library. Bringing in Spring Security Resource Server would be a cinch because I could simply write the appropriate JwtDecoder implementation and be on my way.

On the other hand, working in an Auth0 implementation of JwtDecoder is less convenient than it could be:

public class Auth0SecurityConfig extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) {
        http.oauth2().resourceServer();
    }

    protected void configure(AuthenticationManagerBuilder auth) {
        Auth0JwtDecoder decoder = new Auth0JwtDecoder(... auth0 configs ...);
        JwtAuthenticationProvider provider = new JwtAuthenticationProvider(decoder);
        auth.authenticationProvider(provider);
    }
}

The configuration of http is necessary to give me initial bearer token support.

The configuration of auth gives me the authentication provider I need to integrate with my JWT processing library of choice. This configuration will become more complicated, though, as we introduce validators and authority extraction in future PRs. I would then be obligated to configure all of those by hand, potentially opening up more chances for accidental misconfiguration.

We could be more helpful than this, though.

If we exposed JwtDecoder bean configuration, then it would clean up the above code:

public class Auth0SecurityConfig extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) {
        http.oauth2().resourceServer();
    }

    @Bean
    JwtDecoder decoder() {
        return new Auth0JwtDecoder(... auth0 configs ...);
    }
}

without requiring a change to the DSL.

This has some nice advantages. First, it provides an easy configuration point for users to take full control of key management. Second, it provides an easy multi-tenancy configuration point, should different decoding strategies be required. Third, it provides an easy way to fold in a different JWT processing library than Nimbus.

It is easy to do and it gets us out of the way of decoding the token into a JWT.

I will also note here that, while there are certain aspects of the DSL still under debate, it is arguable that something like .authoritiesExtractor() and something like .bearerTokenResolver() and something like .validator() will all be on this DSL to expose various interface points for further configuring the Bearer Token Authentication flow. I believe that .decoder() is in the same class as these other configuration points. I don't formally make this point here because I believe that this portion of the DSL is still in flux, but I submit it just as food for thought.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions