Spring Security: Custom UserDetailsService not being called (using Auth0 authentication)

Joakim :

I'm new to the Spring framework, so I apologize in advance for any gaping holes in my understanding.

I'm using Auth0 to secure my API, which works perfectly. My setup & config is the same as the suggested setup in the Auth0 documentation:

// SecurityConfig.java
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // auth0 config vars here

    @Override
    protected void configure(HttpSecurity http) {
        JwtWebSecurityConfigurer
                .forRS256(apiAudience, issuer)
                .configure(http)
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/api/public").permitAll()
                .antMatchers(HttpMethod.GET, "/api/private").authenticated();
    }
}

With this setup, the spring security principal is being set to the userId (sub) from the jwt token: auth0|5b2b.... However, instead of just the userId, I want it set to the matching user (from my database). My question is how to do that.

What I've tried

I've tried implementing a custom database-backed UserDetailsService that I copied from this tutorial. However, it's not getting called regardless of how I try to add it to my conf. I've tried adding it several different ways with no effect:

// SecurityConfig.java (changes only)

    // My custom userDetailsService, overriding the loadUserByUsername
    // method from Spring Framework's UserDetailsService.
    @Autowired
    private MyUserDetailsService userDetailsService;

    protected void configure(HttpSecurity http) {
        http.userDetailsService(userDetailsService);  // Option 1
        http.authenticationProvider(authenticationProvider());  // Option 2
        JwtWebSecurityConfigurer
                [...]  // The rest unchanged from above
    }

    @Override  // Option 3 & 4: Override the following method
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());  // Option 3
        auth.userDetailsService(userDetailsService);  // Option 4
    }

    @Bean  // Needed for Options 2 or 4
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        return authProvider;
    }

Unfortunately none of the similar "userDetails not being called" questions have helped me due to me needing to combine it with Auth0 authentication.

I'm not positive that I'm on the right path with this. It seems strange to me that I can't find any documentation from Auth0 on this extremely common use case, so maybe I'm missing something obvious.

PS: Not sure if relevant, but the following is always logged during init.

Jun 27, 2018 11:25:22 AM com.test.UserRepository initDao
INFO: No authentication manager set. Reauthentication of users when changing passwords will not be performed.

EDIT 1:

Based on Ashish451's answer, I tried copying his CustomUserDetailsService, and added the following to my SecurityConfig:

@Autowired
private CustomUserDetailsService userService;

@Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

@Autowired
public void configureGlobal( AuthenticationManagerBuilder auth ) throws Exception {
    auth.userDetailsService( userService );
}

Unfortunately with those changes, CustomUserDetailsService is still not being called.

EDIT 2:

Output when adding the logging method suggested by @Norberto Ritzmann:

Jul 04, 2018 3:49:22 PM com.test.repositories.UserRepositoryImpl initDao
INFO: No authentication manager set. Reauthentication of users when changing passwords will not be performed.
Jul 04, 2018 3:49:22 PM com.test.runner.JettyRunner testUserDetailsImpl
INFO: UserDetailsService implementation: com.test.services.CustomUserDetailsService
Joakim :

I ended up asking Auth0 support about this, and they say that it's currently not possible to modify the principal without modifying the library source.

They provide an alternative approach, however, which is to use a JWT validation library (e.g. https://github.com/auth0/java-jwt) instead of their Spring Security API SDK.

My solution will be to modify my code to work with just the token as principal.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=37016&siteId=1