16

I'm quite new to Spring Oauth and Spring Security. I'm trying to use the client_credentials flow in my project. For now i managed to user my own CustomDetailsService in order to fetch client_id and password (secret) from a database that already exists in my system. The only problem is that I cannot change the password encoder in DaoAuthenticationProvider that is used by AuthorizationServer - it is set by default to PlaintextPasswordEncoder. I wasn't able to configure it the way, that it would use for example SHAPasswordEncoder. It always uses the plaintext encoder. I probably don't understand the flow well enough, as I am a newbie in Spring.

Here's some code of mine (with not working configuration of DaoAuthenticationProvider):

SecurityConfig.java

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final String RESOURCE_ID = "restservice";

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/register/**");

}

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

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(daoAuthenticationProvider());
}

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(userDetailsService());
    daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
    return daoAuthenticationProvider;
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new ShaPasswordEncoder();
}

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private MyCustomClientDetailsService myCustomClientDetailsService;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints.tokenStore(tokenStore());
    }

    @Bean
    public ResourceServerTokenServices defaultTokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setSupportRefreshToken(true);
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(myCustomClientDetailsService);
    }

    @Bean
    public MyCustomClientDetailsService detailsService() {
        return new MyCustomClientDetailsService();
    }
}

@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    ...
}
}

And the custom ClientDetailsService class:

public class MyCustomClientDetailsService implements ClientDetailsService {

@Autowired
private UserService userService;

@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {

    User fan = userService.getFan(clientId);

    if (fan == null) {
        throw new NoSuchClientException("No client with requested id: " + clientId);
    } 

    BaseClientDetails details = new BaseClientDetails(clientId, restservice, "write", "client_credentials", "USER");

    details.setClientSecret(fan.getEncodedPassword()); 

    return details;
}
}

The encodedPassword that is taken from my UserService is always a bad Credential, as DaoAuthenticationProvider has a PlaintextPasswordEncoder set by default.

What am i missing there? Is it possible to set the password encoder in the DaoAuthenticationProvider that is used for checking the credentials here? Or do I have to write my own AuthenticationProvider, that would check it the way i want?

gajos
  • 897
  • 2
  • 10
  • 21

2 Answers2

25

The solution I found to the problem is to override configure on AuthorizationServerConfigurerAdapter

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.passwordEncoder(passwordEncoder);
}
Leon
  • 12,013
  • 5
  • 36
  • 59
  • 2
    Note that I also had to set it in the `configure(AuthenticationManagerBuilder auth)` override of `WebSecurityConfigurerAdapter` subclass like this: `auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder)` otherwise only the client_secret was encoded, but not the users' password. – Wim Deblauwe Feb 04 '16 at 19:46
  • Thanks for the solution. Been looking into it for weeks – Salar Ahmadi Apr 16 '21 at 20:09
-1

If you just want to configure spring authentication with another pass encoder then use this configuration.

<bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>

 <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="authenticationService">
       <password-encoder ref ="encoder" /> 

          <!--   <user-service>
                <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
            </user-service> -->
        </authentication-provider>
    </authentication-manager>

Note:- During create user you need to encrypt userpassword with this same password Encoder class.

Wim Deblauwe
  • 25,113
  • 20
  • 133
  • 211
Sunil Khokhar
  • 370
  • 1
  • 5
  • Am I not doing the same thing but using the Java based configuration. I am setting the authenticationProvider: auth.authenticationProvider(daoAuthenticationProvider()); that is previously configured to use SHAPasswordEncoder. Or am I wrong about this? – gajos Sep 24 '14 at 11:02
  • you can configure with any passwordEncoder. just remember that user password should be encrypted using same passwordEncoder class encode method. – Sunil Khokhar Sep 24 '14 at 11:33
  • in XML Configuration we can refer another passwordEncoder , – Sunil Khokhar Sep 24 '14 at 11:38
  • But the problem is that I try to set the encoder in DaoAuthenticationProvider, but it isn't set at all - i debugged it. I am aware that i need to use the same encoder during creating user but it is not the problem here. – gajos Sep 24 '14 at 12:07