使用Spring Security集成单一登录 [英] Integrate Single Sign On using Spring Security

查看:293
本文介绍了使用Spring Security集成单一登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring Security,我想使用另一个站点作为我的身份验证提供程序之一.我的网站上有一个基于表单的基本登录信息.我想在我的站点上有一个链接,该链接会将用户带到他们将要登录的外部站点,然后该外部站点将向xml响应发回我的数据,我可以验证这些数据来验证是否成功登录.任何帮助将不胜感激!

I'm using Spring Security and I would like to use another site as one of my authentication providers. I have a basic form based login on my site. I want to have a link on my site that takes the user to an external site where they will login and that external site will then post a xml response back to me with data that I can verify to see if there was a successful login. Any help would be greatly appreciated!

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

使用以下指南的示例:

过滤器(未显示我的数据来自xml请求):

filter (not shown my data is coming from xml off the request):

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;

}

}

身份验证提供者:

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配置:

<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)XML登录的AbstractAuthenticationToken子类,我们将其称为XMLAuthenticationToken.

1) Subclass AbstractAuthenticationToken for your XML logins, let's call it XMLAuthenticationToken.

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

2) Subclass AbstractAuthenticationProcessingFilter and add it to the filter chain after UsernamePasswordAuthenticationFilter. It should create a XMLAuthenticationToken based on the data in the XML. You can use UsernamePasswordAuthenticationFilter as an example for the general structure of the filter (that's most likely the filter that you are currently using for your regular Spring Security logins).

<http>
  <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
</http>

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

The filter should set a filterProcessesUrl that is different from the UsernamePasswordFilter. This is the URL the external system will post the XML to. For example:

public XmlAuthenticationFilter() {
    super("/xml_security_check");
}

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

3) Subclass AbstractUserDetailsAuthenticationProvider. Have it look up the user from the UserDetailsService based on the info in the token, and then authenticate it. Use DaoAuthenticationProvider as an example. You will need to register the new provider with the AuthenticationManager.

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

您也许可以摆脱重用UsernamePasswordAuthenticationToken(对于#1,它具有不错的细节"扩展机制)和DaoAuthenticationProvider(或对其进行子类化)的作用.

You might be able to get away with reusing UsernamePasswordAuthenticationToken (for #1, it has a nice "details" extension mechanism) and DaoAuthenticationProvider (or subclassing it) for #3.

这篇关于使用Spring Security集成单一登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆