我正在使用 Spring Boot 构建 REST Web 服务。身份验证是使用 Spring Security 和 OAuth2 实现的。用户根据 LDAP 服务器进行身份验证。这是我的网络安全配置
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(
SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers("/ristore/**").authenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public RestAuthenticationSuccessHandler mySuccessHandler(){
return new RestAuthenticationSuccessHandler();
}
@Bean
public SimpleUrlAuthenticationFailureHandler myFailureHandler(){
return new SimpleUrlAuthenticationFailureHandler();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
DefaultSpringSecurityContextSource contextSource = getSource();
auth
.ldapAuthentication()
.userDnPatterns("cn={0},ou=institution,ou=people")
.groupSearchBase("ou=groups")
.contextSource(contextSource);
}
}
其他配置在 authserverconfig 中完成,包括 clientdetailservice。
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ristoreclient")
.scopes("read")
.authorizedGrantTypes("password", "refresh_token", "client_credentials")
.secret("ristoresecret")
.accessTokenValiditySeconds(60);
}
}
它适用于初始登录。但是,当我尝试在旧令牌过期时使用刷新令牌获取新访问令牌时,我收到错误“需要 UserDetailsService”。在网上搜索答案后,发现这个帖子有类似的问题:spring-security-oauth2 2.0.7 刷新令牌 UserDetailsService 配置 https://stackoverflow.com/questions/30454480/spring-security-oauth2-2-0-7-refresh-token-userdetailsservice-configuration-us。基本上解决方案是创建一个自定义LdapUserDetailsService
。问题是它是在 xml 配置而不是 java.xml 中设置的。此外,尚不清楚这个类是如何以及在哪里注入的。在这另一case https://github.com/royclarkson/spring-rest-service-oauth/issues/19, userdetailservice 实例被添加到身份验证服务器端点配置中。本文不提供该类的实现。
在我看来,拥有 userdetailservice 的想法是在发出新的访问令牌之前查找并查看该用户是否仍然处于活动状态。矛盾的是,oauth2获取refresh_token的请求只包含以下信息,不包含用户名/密码。
client_id=clientid
client_secret=clientsecret
refresh_token=1/6BMfW9j53gdGImsiyUH5kU5RsR4zwI9lUVX-tqf8JXQ&
grant_type=refresh_token
用于 Spring REST 的 OAuth2 http://www.baeldung.com/spring-security-oauth2-refresh-token-angular-js使用 Zuul 代理作为前端和 Web api 之间的中间层来处理刷新令牌,这使得配置更加复杂。我应该如何在 Spring Boot 中为 oauth2 实现 userdetailsservice 以及应该在哪里注入它?