1. 概述
本教程将展示如何在Spring Security中自定义Authentication Provider ,相比默认实现中使用简单的UserDetailsService
,更具灵活性。
2. Authentication Provider
Spring Security提供了多种执行身份认证的方法 。它们遵循简单的约定 —— AuthenticationProvider处理认证请求 并返回具有完整凭据的经过完全认证的对象 (Authentication)。
最常见和默认是使用DaoAuthenticationProvider
—— 它会从简单的、只读的User DAO
—— UserDetailsService中获取用户信息。UserDetailsService 仅能通过username 查询用户详情。对于大多数方案而言,这已足够。
一些更具体的场景需要访问完整的Authentication请求,以执行认证过程。例如当通过某些第三方服务(如Crowd)进行身份认证时,Authentication请求中的用户名和密码都是必需的。
对于这些更高级的方案,我们需要自定义一个AuthenticationProvider:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
if (shouldAuthenticateAgainstThirdPartySystem()) {
// use the credentials
// and authenticate against the third-party system
return new UsernamePasswordAuthenticationToken(
name, password, new ArrayList<>());
} else {
return null;
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
3. 注册Auth Provider
现在,我们已经定义了AuthenticationProvider,我们需要在XML中配置:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()"/>
<http-basic/>
</http>
<authentication-manager>
<authentication-provider
ref="customAuthenticationProvider" />
</authentication-manager>
4. Java配置
当然也可以使用Java方式配置:
@Configuration
@EnableWebSecurity
@ComponentScan("com.baeldung.security")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider authProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic();
}
}
5. 执行认证
使用curl发送经过认证的请求:
curl --header "Accept:application/json" -i --user user1:user1Pass
http://localhost:8080/spring-security-custom/api/foo/1
使用Basic认证,我们成功得到200响应码:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=B8F0EFA81B78DE968088EBB9AFD85A60; Path=/spring-security-custom/; HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 02 Jun 2013 17:50:40 GMT
6. 总结
在本文中,我们讨论了如何在Spring Security中自定义Authentication Provider 。
本教程完整源代码,可从GitHub上找到。