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
二维码