SSO单点登录

一.实现原理

     SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。简单的说就是在一个多系统共存的环境下,用户在某一系统中登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。

二.实现方式

 方式1:共享session

 1.web.xml



    springSessionRepositoryFilter
    org.springframework.web.filter.DelegatingFilterProxy


    springSessionRepositoryFilter
    /*
     

    sso
    com.capital.bbs.filter.UserSsoLoginVerifyFilter


    sso
    *.jsp


    sso
    *.action


    sso
    *.html

2.添加jar包:  jedis-x.x.x.jar

3.redis.properties

jedis.host=127.0.0.1
jedis.port=7408
jedis.password=123123
jedis.timeout=30000
jedis.pool.maxTotal=200
jedis.pool.minIdle=1
jedis.pool.maxIdle=50
jedis.pool.maxWaitMillis=5000
jedis.pool.testOnBorrow=true
jedis.pool.testOnReturn=true

4.applicationContext_client.xml

xml version="1.0" encoding="UTF-8"?>
xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                       http://cxf.apache.org/transports/http/configuration
                 http://cxf.apache.org/schemas/configuration/http-conf.xsd ">

    resource="classpath:META-INF/cxf/cxf.xml"/>
    resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
    resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    resource="classpath:META-INF/cxf/cxf-extension-xml.xml"/>
    resource="classpath:META-INF/cxf/cxf-extension-http.xml"/>

    <http-conf:conduit name="*.http-conduit">
         <http-conf:client ConnectionTimeout="180000" ReceiveTimeout="300000"/>
    http-conf:conduit>

    
    id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        name="maxTotal" value="${jedis.pool.maxTotal}"/>
        name="maxIdle" value="${jedis.pool.maxIdle}"/>
        name="minIdle" value="${jedis.pool.minIdle}"/>
        name="maxWaitMillis" value="${jedis.pool.maxWaitMillis}"/>
        name="testOnBorrow" value="${jedis.pool.testOnBorrow}"/>
        name="testOnReturn" value="${jedis.pool.testOnReturn}"/>
    

    id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        name="hostName" value="${jedis.host}" />
        name="port" value="${jedis.port}" />
        name="password" value="${jedis.password}" />
        name="timeout" value="${jedis.timeout}" />
        name="poolConfig" ref="jedisPoolConfig" />
        name="usePool" value="true" />
    

    id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        name="connectionFactory" ref="jedisConnectionFactory" />
        name="keySerializer">
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        
        name="valueSerializer">
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        
        name="hashKeySerializer">
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        
        name="hashValueSerializer">
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        
    

    
    id="redisHttpSessionConfiguration"
          class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        name="maxInactiveIntervalInSeconds" value="1800" />
    
    id="defaultCookieSerializer"
          class="org.springframework.session.web.http.DefaultCookieSerializer">
        name="cookieName" value="WEB_SESSION_ID" />
        name="cookiePath" value="/" />
    
    id="cookieHttpSessionStrategy"
          class="org.springframework.session.web.http.CookieHttpSessionStrategy">
        name="cookieSerializer" ref="defaultCookieSerializer" />
    

5.applicationContext_hibernate.xml

xml version="1.0" encoding="UTF-8"?>
xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-2.5.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">


    
    id="propertyConfigurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"   lazy-init="true">
        name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        name="ignoreResourceNotFound" value="true" />
        name="locations">
            
                classpath:/jdbc.properties
                
                classpath:/redis.properties
                
            
        
    

6.UserSsoLoginVerifyFilter过滤器示例:

import com.capital.bbs.common.criteria.UserCriteria;
import com.capital.bbs.common.dto.user.UserDTO;
import com.capital.bbs.manager.user.IUserManager;
import com.capital.common.vo.user.UserVO;
import com.opensymphony.xwork2.ActionContext;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserSsoLoginVerifyFilter extends StrutsPrepareAndExecuteFilter {

    private static final Logger LOGGER = LogManager.getLogger(UserSsoLoginVerifyFilter.class);

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //当前系统登录存放的session
        Object userOid = request.getSession().getAttribute("userOid");
        if (null == userOid) {
            //单点登录,其他相关系统共享存放的session
            UserVO user = (UserVO) ActionContext.getContext().getSession().get("loginUser");
            if (null != user) {
                try {
                    ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
                    IUserManager userManager = (IUserManager) ac.getBean("userManager");
                    UserCriteria userCriteria = new UserCriteria();
                    UserDTO userDTO = new UserDTO();
                    //通过共享session里面的用户名获取用户信息
                    userDTO.setUserName(user.getUserName());
                    userDTO.setUserOid(user.getUserOid());
                    userCriteria.setUser(userDTO);
                    userDTO = userManager.doSsoLogin(userCriteria);
                    if (null != userDTO) {
                        request.getSession().setAttribute("userOid", user.getUserOid());
                    }
                }catch (Exception e){
                    LOGGER.error("单点登录过滤器中查询用户信息失败");
                }
            }
        }
        filterChain.doFilter(request, response);
    }

}

三.约束:

  1.session中所涉及的类型必须是子系统中共同拥有的(即程序集、类型都需要一致),这导致session的使用受到诸多限制;
  2.跨顶级域名的情况完全无法处理。


你可能感兴趣的:(java)