Java – spring security oauth2 refresh token – IllegalStateException, userdetailsservice is required
•
Java
I am new to spring security and use oauth2 authentication and authorization to develop spring rest API Everything is OK, but when I request to refresh the token, the error I get is –
Note: I use a custom authentication provider to authenticate user credentials in the database
This is my code:
Web security configuration adapter:
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private CustomAuthenticationProvider authProvider;
@Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
Custom authentication provider
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
Ss_admin_service ss_admin_service = new Ss_admin_service();
Ss_admin ss_admin = new Ss_admin();
ss_admin.setA_password(password);
ss_admin.setA_username(username);
ss_admin_service.doLogin(ss_admin);
if(!ss_admin_service.doLogin(ss_admin)) {
throw new BadCredentialsException("Invalid username/password");
}
return new UsernamePasswordAuthenticationToken(username,password,(Collection<? extends GrantedAuthority>) new ArrayList<>());
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Authorization server configuration
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM="MY_OAUTH_REALM";
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password","authorization_code","refresh_token","implicit")
.authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
.scopes("read","write","trust")
.secret("secret")
.accessTokenValiditySeconds(10).//Access token is only valid for 10 sec for testing.
refreshTokenValiditySeconds(10);//Refresh token is only valid for 10 sec for testing.
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM+"/client");
}
}
Resource server configuration
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "SPRING_REST_API";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable()
.requestMatchers().antMatchers("/admin/**")
.and().authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
Solution
You can try to inject clientdetailsservice into authorization server config and configure it as follows;
Authorization server configuration
.....
@Autowired
private ClientDetailsService clientDetailsService;
......
......
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码
