Spring Security integrate with SSO(Siteminder)

阅读更多
This is the sample to integrate SSO to Java web app with spring security, typical authentication process:


In this case, Web app sever is not proxyed, and recieve request directly, so the user's request arrive to Web app server firstly
Spring Security integrate with SSO(Siteminder)_第1张图片

Core Spring security config:



    
    

    

    
        
        
        
    

    
        
        
    

    
        
        
    

    
        
    

    
        
        
        
        
    

    
        
    




So, first, we need to add a custom LoginUrlAuthenticationEntryPoint to redirect request to SSO when user open home page without login
public class SSOLoginHandler extends LoginUrlAuthenticationEntryPoint
{

    private final Logger logger = LoggerFactory.getLogger(SSOLoginHandler.class);
    private String authProcessingURL;

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
        final AuthenticationException authenticationException) throws IOException, ServletException
    {
        logger.debug("Preparing redirectiion to SSO PROXY...");
//        new DefaultRedirectStrategy().sendRedirect(request, response, this.getLoginFormUrl() + "?ref="
//            + authProcessingURL);
        String SSO_LOGIN_URL= "https://ssoserver.com/sso.jsp";
        new DefaultRedirectStrategy().sendRedirect(request, response,  SSO_LOGIN_URL + "?ref="
            + authProcessingURL);
    }

    public String getAuthProcessingURL()
    {
        return authProcessingURL;
    }

    public void setAuthProcessingURL(final String authProcessingURL)
    {
        this.authProcessingURL = authProcessingURL;
    }



Simplete logout which do some logging items..
public class SSOLogoutHandler extends SimpleUrlLogoutSuccessHandler
{

    private final Logger logger = LoggerFactory.getLogger(SSOLogoutHandler.class);

    @Override
    public void onLogoutSuccess(final HttpServletRequest request, final HttpServletResponse response,
        final Authentication authentication) throws IOException, ServletException
    {

        super.onLogoutSuccess(request, response, authentication);
        logger.debug("Performing an SSO logout at: {}", this.getDefaultTargetUrl());
    }
}



Custom UserDeatailsService to load role and Grant Authority to user
public class CustomUserDetailsService implements UserDetailsService
{
    public static final String DEFAULT_AUTH_PASSWORD = "password";
    
   

    @Override
    public UserDetails loadUserByUsername(String soeid) throws UsernameNotFoundException
    {
        List grantedAuths = new ArrayList();
        grantedAuths.add(new SimpleGrantedAuthority(***Service.queryUserRoleFromDatabase(soeid).toString()));
        
        UserDetails user = new User(soeid, DEFAULT_AUTH_PASSWORD, true, true, true, true, grantedAuths);      
        
        return user;
    }

}


Custom authetication filter to processe the response form SSO server after logicn
public class SSOAuthenticationFilter extends UsernamePasswordAuthenticationFilter
{

    public static final String DEFAULT_AUTH_PASSWORD = "password";
    private final Logger logger = LoggerFactory.getLogger(SSOAuthenticationFilter.class);
    private Cipher cipher;

    public SSOAuthenticationFilter()
    {
        super.setPostOnly(false); // allow a GET request from SSO PROXY
    }

    @Override
    public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticationException
    {
      
        String[] sid = decodeSID(request);
        String soeid = sid[0];

        // token is expired if currentTimeMillis is greater then TIMESTAMP
        if (System.currentTimeMillis() > Long.parseLong(sid[1]))
        {
            logger.error("Authentication rejected for: {}", soeid);
            throw new NonceExpiredException("Authentication token is expired");
        }
        // saving decoded SOEID in a REQUEST to reuse it by obtainUsername()
        request.setAttribute("SSO_USER_SOEID", soeid);

        return super.attemptAuthentication(request, response);
    }

    @Override
    protected String obtainPassword(final HttpServletRequest request)
    {
        return DEFAULT_AUTH_PASSWORD;
    }

    @Override
    protected String obtainUsername(final HttpServletRequest request)
    {
        //SM_USER is coming from SSO after login 
        return (String) request.getAttribute("SM_USER");
    }

    private String[] decodeSID(final HttpServletRequest request)
    {
       .............add SSO server decode strtegy
    }

}



You may say above sample was not my case, what happens we have SSO setup in the proxy server as below?

Spring Security integrate with SSO(Siteminder)_第2张图片

only difference is in the login entry filter, we redirect to the web app authentication filter("/authenticate") as it's pre-logged in
public class SSOLoginHandler extends LoginUrlAuthenticationEntryPoint
{

    private final Logger logger = LoggerFactory.getLogger(SSOLoginHandler.class);
    private String authProcessingURL;

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
        final AuthenticationException authenticationException) throws IOException, ServletException
    {
        logger.debug("Preparing redirectiion to SSO PROXY...");
        new DefaultRedirectStrategy().sendRedirect(request, response, "/authenticate");
    }
  
}

  • Spring Security integrate with SSO(Siteminder)_第3张图片
  • 大小: 142.2 KB
  • Spring Security integrate with SSO(Siteminder)_第4张图片
  • 大小: 16.5 KB
  • 查看图片附件

你可能感兴趣的:(spring,security,SSO,Siteminder)