我想就Spring Security中的问题向您寻求帮助。 我有一个要求,我必须根据用户选择的选项验证登录凭据。选项1将通过第三方服务验证登录用户。选项2是使用数据库身份验证级别的正常验证。我该如何实现呢?
答案 0 :(得分:10)
一般策略
org.springframework.security.authentication.AuthenticationProvider
的自定义实现,将身份验证委派给相应的后端(第三方服务,另一个AuthenticationProvider
等)。AuthenticationProvider
,使其能够选择正确的身份验证后端。AuthenticationProvider
配置为默认身份验证提供程序。第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
实现从details
对象的Authentication
属性中选择用户选择。据推测,必须从HttpServletRequest
中选择用户并在调用Authentication
之前添加到AuthenticationProvider
对象。这意味着,在调用Authentication
之前,需要调用另一个可以访问HttpServletRequest
和AuthenticationProvider
对象的组件。
Authentication
对象由AbstractAuthenticationProcessingFilter
的实现创建。此类有一个名为attemptAuthentication
的方法,它接受HttpServletRequest
对象并返回Authentication
个对象。因此,这似乎是实施所需内容的良好候选者。对于基于用户名密码的身份验证,实现类为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
和过滤器实现。具体步骤将根据是使用XML还是Java配置而有所不同。