我正在使用Spring Boot 1.4.3.RELEASE并尝试设置我的授权服务器。
当access_token有效时,我在创建令牌或访问资源时没有问题,但是当它过期并且我尝试刷新它时,我收到错误
{
"error": "server_error",
"error_description": "UserDetailsService is required."
}
这是我刷新access_token
的请求http://localhost:11134/oauth/token?grant_type=refresh_token&refresh_token=0d17dfee-1185-480d-af30-ba0f1e47831c&scope=read
refresh_token是正确的
这是我的AuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "security.oauth2.client.";
private static final String PROP_CLIENTID = "client-id";
private static final String PROP_SECRET = "client-secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "access-token-validity-seconds";
private static final String PROP_REFRESH_TOKEN_VALIDITY_SECONDS = "refresh-token-validity-seconds";
private RelaxedPropertyResolver propertyResolver;
@Autowired
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager).userDetailsService(userDetailsService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(propertyResolver.getProperty(PROP_CLIENTID))
.scopes("read", "write", "trust")
.authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_USER.name())
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class))
.refreshTokenValiditySeconds(propertyResolver.getProperty(PROP_REFRESH_TOKEN_VALIDITY_SECONDS, Integer.class));
}
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
}
}
然后这是WebSecurityConfiguration
@Configuration
@EnableWebSecurity
// @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new StandardPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
如果它有趣,那就是CustomUserDetailService
@Component("userDetailsService")
public class CustomUserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
private final Logger log = LoggerFactory.getLogger(UserDetailsService.class);
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(final String login) {
log.debug("Authenticating {}", login);
String lowercaseLogin = login.toLowerCase();
User userFromDatabase;
userFromDatabase = userRepository.findByUsernameCaseInsensitive(lowercaseLogin);
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (Authority authority : userFromDatabase.getAuthorities()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authority.getName());
grantedAuthorities.add(grantedAuthority);
}
return new org.springframework.security.core.userdetails.User(userFromDatabase.getUsername(), userFromDatabase.getPassword(), grantedAuthorities);
}
}