我正在使用Spring Security,我想将其他网站用作我的身份验证提供商之一。我在我的网站上有一个基本的表单登录。我希望在我的网站上有一个链接,将用户带到他们将登录的外部站点,然后外部站点将向我发送一个xml响应,其中包含我可以验证的数据以查看是否有成功登录。任何帮助将不胜感激!
使用以下指南的示例:
过滤器(未显示我的数据来自请求的xml):
public class XMLAuthenticationFilter extends AbstractAuthenticationProcessingFilter{
public XMLAuthenticationFilter() {
super("/xml_security_check");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException,
IOException, ServletException {
GrantedAuthority[] grantedAuthorities = new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_USER")};
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("userid", "pwd", grantedAuthorities);
request.getSession();
token.setDetails(new WebAuthenticationDetails(request));
Authentication authenticatedUser = super.getAuthenticationManager().authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
return authenticatedUser;
}
}
Auth Provider:
public class XMLAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{
private UserManager userManager;
@Override
protected void additionalAuthenticationChecks(UserDetails user, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
}
@Override
protected UserDetails retrieveUser(String userName, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
UserDetails user = userManager.getUser(userName);
if(user == null){
Users newDCUser = new Users();
newDCUser.setUserId(userName);
newDCUser.setRawPassword((String) token.getCredentials());
newDCUser.setFailedLoginAttempts(0);
newDCUser.setBeginEffectiveDate(new Date());
newDCUser.setEndEffectiveDate(getEffectiveDate());
userManager.saveUser(newDCUser);
}
return userManager.loadUserByUsername(userName);
}
private Date getEffectiveDate(){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 10);
return calendar.getTime();
}
public UserManager getUserManager() {
return userManager;
}
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
}
bean config:
<bean id="xmlAuthenticationFilter" class="com.dc.api.service.impl.XMLAuthenticationFilter">
<property name="authenticationManager" ref="am" />
</bean>
<bean id="xmlAuthenticationProvider" class="com.dc.api.service.impl.XMLAuthenticationProvider">
<property name="userManager" ref="userManager"/>
</bean>
答案 0 :(得分:8)
一般方法是:
1)您的XML登录的子类AbstractAuthenticationToken,我们称之为XMLAuthenticationToken。
2)Subclass AbstractAuthenticationProcessingFilter并在UsernamePasswordAuthenticationFilter之后将其添加到过滤器链。它应该基于XML中的数据创建XMLAuthenticationToken。您可以使用UsernamePasswordAuthenticationFilter作为过滤器的一般结构的示例(这很可能是您当前用于常规Spring Security登录的过滤器)。
<http>
<custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
</http>
过滤器应设置与UsernamePasswordFilter不同的filterProcessesUrl。这是外部系统将XML发布到的URL。例如:
public XmlAuthenticationFilter() {
super("/xml_security_check");
}
3)Subclass AbstractUserDetailsAuthenticationProvider。让它根据令牌中的信息从UserDetailsService查找用户,然后对其进行身份验证。以DaoAuthenticationProvider为例。您需要使用AuthenticationManager注册新的提供程序。
<authentication-manager>
<authentication-provider user-service-ref='myUserDetailsService'/>
<authentication-provider ref="xmlAuthenticationProvider" />
</authentication-manager>
你可能能够重复使用UsernamePasswordAuthenticationToken(对于#1,它有一个很好的“详细信息”扩展机制)和DaoAuthenticationProvider(或它的子类化)#3。