使用Spring Security集成单点登录

c12*_*c12 17 spring spring-security

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

  1. 您如何将该流程集成到Spring Security中?
  2. 一旦我收到回复,我将如何自动登录用户?

使用以下指导的示例:

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

}
Run Code Online (Sandbox Code Playgroud)

}

认证提供者:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

bean配置:

<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>
Run Code Online (Sandbox Code Playgroud)

sou*_*ica 8

一般方法是:

1)您的XML登录的子类AbstractAuthenticationToken,我们称之为XMLAuthenticationToken.

2)Subclass AbstractAuthenticationProcessingFilter并在UsernamePasswordAuthenticationFilter之后将其添加到过滤器链中.它应该基于XML中的数据创建XMLAuthenticationToken.您可以使用UsernamePasswordAuthenticationFilter作为过滤器的一般结构的示例(这很可能是您当前用于常规Spring Security登录的过滤器).

<http>
  <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
</http>
Run Code Online (Sandbox Code Playgroud)

过滤器应设置与UsernamePasswordFilter不同的filterProcessesUrl.这是外部系统将XML发布到的URL.例如:

public XmlAuthenticationFilter() {
    super("/xml_security_check");
}
Run Code Online (Sandbox Code Playgroud)

3)Subclass AbstractUserDetailsAuthenticationProvider.让它根据令牌中的信息从UserDetailsS​​ervice查找用户,然后对其进行身份验证.以DaoAuthenticationProvider为例.您需要使用AuthenticationManager注册新的提供程序.

<authentication-manager>
  <authentication-provider user-service-ref='myUserDetailsService'/>
  <authentication-provider ref="xmlAuthenticationProvider" />
</authentication-manager>
Run Code Online (Sandbox Code Playgroud)

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