如何为 Spring Security 编写认证提供者
1. 概述
本教程将会展示如何创建一个Spring Security 的认证提供者,来获得比标准场景下使用的简单的UserDetailsService 更多的灵活性。
2. 认证提供者
Spring Security 对执行认证提供了多样的选择 – 所有选择都基于一个约定 – 即一个 Authentication 请求由一个 AuthenticationProvider 来处理并且返回一个被完全认证的、具有所有凭证的对象。
标准的、最常用的实现是 DaoAuthenticationProvider – 它获取用户详细信息是通过一个简单的只读的用户DAO,即 UserDetailsService 。当我们想要获取完整的用户实体时,UserDetailsService 却仅能访问用户名 – 然而在大部分情况下,这已经足够了。
更多用户自定义的情境下,为了完成认证过程,将需要访问完整的Authentication 请求 – 例如,当针对一些外部、第三方的服务(比如Crowd)进行认证时 – 来自于认证请求中的 username 和 password 都是必须的。
对这些更高级的场景,我们将需要定义一个自定义的认证提供者:
@Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String name = authentication.getName(); String password = authentication.getCredentials().toString(); // use the credentials to try to authenticate against the third party system if (authenticatedAgainstThirdPartySystem()) { List<GrantedAuthority> grantedAuths = new ArrayList<>(); return new UsernamePasswordAuthenticationToken(name, password, grantedAuths); } else { return null; } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
注意,返回的Authentication 对象中,授权信息是空的 – 这是因为应用不同,权限信息必然也不同。
3. 安全配置——注册认证提供者
现在认证提供者已经定义好了,我们需要在XML安全配置中指定它,使用可用的命名空间支持:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security" xsi:schemaLocation=" http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <http use-expressions="true"> ... <http-basic/> </http> <authentication-manager> <authentication-provider ref="customAuthenticationProvider" /> </authentication-manager> </beans:beans>
4. 认证过程
触发一个认证过程没什么不同的,甚至不用定制认证提供者。我们已经用基本认证建立了我们的安全配置,所以我们可以用一个简单的curl命令来发送一个认证请求:
curl --header "Accept:application/json" -i --user user1:user1Pass http://localhost:8080/spring-security-custom/api/foo/1之后我们从服务器获得了期望的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
5. 总结
在这篇文章中我们讨论了一个为Spring安全定制的认证提供者示例。在github项目中可以找到这个实现——这是一个基本的Eclipse项目,所以你可以很轻松的导入和运行它。