在Spring Security中实现自定义身份validation
我想就Spring Security中的问题向您寻求帮助。 我有一个要求,其中我必须根据用户选择的选项validation登录凭据。 选项1将通过第三方服务validation登录用户。 选项2是使用数据库身份validation级别的正常validation。 我该如何实现呢?
一般战略
- 提供
org.springframework.security.authentication.AuthenticationProvider
的自定义实现,该实现将身份validation委派给适当的后端(第三方服务,另一个AuthenticationProvider
等)。 - 将用户选择的选项传递给自定义
AuthenticationProvider
以使其能够选择正确的身份validation后端。 - 将自定义
AuthenticationProvider
配置为默认身份validation提供程序。
第1步:实现
AuthenticationProvider
AuthenticationProvider
是具有单个方法的接口。 因此,自定义实现可能如下所示:
class DelegatingAuthenticationProvider implements AuthenticationProvider { @Autowired private ThirdPartyAuthenticationService service; @Autowired @Qualifier("anotherAuthenticationProvider") private AuthenticationProvider provider; @Override public Authentication authenticate(final Authentication authentication) throws AuthenticationException { // Get the user selection. String selection = (String) authentication.getDetails(); // Take action depending on the selection. Authentication result; if("ThirdParty".equals(selection)) { // Authenticate using "service" and generate a new // Authentication "result" appropriately. } else { // Authenticate using "provider" and generate a new // Authentication "result" appropriately. } return result; } }
第2步:将用户选择传递给
AuthenticationProvider
上面的AuthenticationProvider
实现从Authentication
对象的details
属性中选择用户选择。 据推测,在调用Authentication
之前,必须从HttpServletRequest
选择用户选择并将其添加到Authentication
对象。 这意味着,另一个可以访问Authentication
和HttpServletRequest
对象的组件,在需要实现AuthenticationProvider
之前调用。
Authentication
对象由AbstractAuthenticationProcessingFilter
的实现创建。 此类有一个名为attemptAuthentication
的方法,该方法接受HttpServletRequest
对象并返回Authentication
对象。 因此,这似乎是实施所需内容的良好候选者。 对于基于用户名密码的身份validation,实现类是UsernamePasswordAuthenticationFilter
。 此类返回UsernamePasswordAuthenticationToken
的新实例,该实例是Authentication
的实现。 因此,扩展UsernamePasswordAuthenticationFilter
的类应该足够了。
class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { ... UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password); authentication.setDetails(obtainUserSelection(request)); ... return authentication; } }
obtainUserSelection
是一个私有方法,可以从请求中获取用户选择。
第3步:配置
在Spring Security配置中配置AuthenticationProvider
和filter实现。 具体步骤将根据是使用XML还是Java配置而有所不同。