使用Spring Security集成单点登录

时间:2011-03-19 21:35:10

标签: spring spring-security

我正在使用Spring Security,我想将其他网站用作我的身份验证提供商之一。我在我的网站上有一个基本的表单登录。我希望在我的网站上有一个链接,将用户带到他们将登录的外部站点,然后外部站点将向我发送一个xml响应,其中包含我可以验证的数据以查看是否有成功登录。任何帮助将不胜感激!

  1. 如何将该流程集成到Spring Security中?
  2. 一旦我收到回复,我将如何自动登录用户?
  3. 使用以下指南的示例:

    过滤器(未显示我的数据来自请求的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>
    

1 个答案:

答案 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。让它根据令牌中的信息从UserDetailsS​​ervice查找用户,然后对其进行身份验证。以DaoAuthenticationProvider为例。您需要使用AuthenticationManager注册新的提供程序。

<authentication-manager>
  <authentication-provider user-service-ref='myUserDetailsService'/>
  <authentication-provider ref="xmlAuthenticationProvider" />
</authentication-manager>

你可能能够重复使用UsernamePasswordAuthenticationToken(对于#1,它有一个很好的“详细信息”扩展机制)和DaoAuthenticationProvider(或它的子类化)#3。