CAS做单点登陆(SSO)——集成Java Web 项目

添加cas-client的jar包

下载cas-client,地址:http://www.ja-sig.org/downloads/cas-clients/当前最新版本是cas-client-3.2.1-release.zip然后解压cas-client-3.2.1-release.zip,在modules拷贝cas-client-core-3.2.1.jar应用的WEB-INF/lib目录中

撰写支持CAS集成的客户化包

除了在web.xml添加CAS内置的filter外(具体看配置web.xml),我们需要撰写自己支持CAS集成的客户化包。大致思路如下:

[java]  view plain  copy
 
  1. @Override  
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  3.       
  4.     HttpServletRequest request = (HttpServletRequest)servletRequest;  
  5.     HttpServletResponse response = (HttpServletResponse)servletResponse;  
  6.       
  7.     HttpSession session = request.getSession();  
  8.     //在session中自定义一个参数,以它来校验是否完成过自动登陆  
  9.     Object user_login = session.getAttribute(AURORA_USER_LOGIN);  
  10.     if (user_login != null){  
  11.         //登陆过,就继续执行其他filter  
  12.         filterChain.doFilter(request, response);  
  13.         return;  
  14.     }  
  15.     //通过CAS的API获得登陆账号  
  16.     String loginName = AssertionHolder.getAssertion().getPrincipal().getName();  
  17.     try {  
  18.         //执行本系统的登陆。跟平常同时校验用户名和密码不同,这里只有用户名。  
  19.         executeLoginProc(request,response,loginName);  
  20.     } catch (Exception e) {  
  21.         logger.log(Level.SEVERE, "executeLoginProc error:", e);  
  22.         return;  
  23.     }  
  24.     //登陆成功  
  25.     session.setAttribute(AURORA_USER_LOGIN, Boolean.TRUE);  
  26.     //跳转到登陆成功后的页面  
  27.     response.sendRedirect(roleSelectPageUrl);  
  28. }  

把这个class打包成一个jar拷贝到应用的WEB-INF/lib目录中

如果有兴趣,还可以简单了解下org.jasig.cas.client.authentication.AuthenticationFilter这个CAS内置filter的功能

[java]  view plain  copy
 
  1. <p>public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  2.     HttpServletRequest request = (HttpServletRequest)servletRequest;  
  3.     HttpServletResponse response = (HttpServletResponse)servletResponse;  
  4.     HttpSession session = request.getSession(false);  
  5.  //检查自定义属性"_const_cas_assertion_"  
  6.     Assertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;</p><p>    if (assertion != null) {  
  7.       //已经成功登陆过CAS  
  8.       filterChain.doFilter(request, response);  
  9.       return;  
  10.     }  
  11.     //拿到url,并检查url参数中的ticket是否有效  
  12.     String serviceUrl = constructServiceUrl(request, response);  
  13.     String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());  
  14.     boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);</p><p>    if ((CommonUtils.isNotBlank(ticket)) || (wasGatewayed)) {  
  15.       //ticket有效  
  16.       filterChain.doFilter(request, response);  
  17.       return;  
  18.     }</p><p>    this.log.debug("no ticket and no assertion found");  
  19.     String modifiedServiceUrl;  
  20.     String modifiedServiceUrl;  
  21.     if (this.gateway) {  
  22.       this.log.debug("setting gateway attribute in session");  
  23.       modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);  
  24.     } else {  
  25.       modifiedServiceUrl = serviceUrl;  
  26.     }</p><p>    if (this.log.isDebugEnabled()) {  
  27.       this.log.debug("Constructed service url: " + modifiedServiceUrl);  
  28.     }</p><p>    String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);</p><p>    if (this.log.isDebugEnabled()) {  
  29.       this.log.debug("redirecting to \"" + urlToRedirectTo + "\"");  
  30.     }  
  31.     //重定向到cas的登陆页面  
  32.     response.sendRedirect(urlToRedirectTo);  
  33.   }  
  34. </p>  


 

修改web.xml

在应用WEB-INF/web.xml添加filter的内容,效果如下所示

[html]  view plain  copy
 
  1. <!-- ======================== 单点登录开始 ======================== -->  
  2.     <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置-->  
  3.     <listener>  
  4.         <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
  5.     </listener>  
  6.   
  7.     <!-- 该过滤器用于实现单点登出功能,可选配置。 -->  
  8.     <filter>  
  9.         <filter-name>CAS Single Sign Out Filter</filter-name>  
  10.         <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
  11.     </filter>  
  12.     <filter-mapping>  
  13.         <filter-name>CAS Single Sign Out Filter</filter-name>  
  14.         <url-pattern>/*</url-pattern>  
  15.     </filter-mapping>  
  16.   
  17.     <!-- 该过滤器负责用户的认证工作,必须启用它 -->  
  18.     <filter>  
  19.         <filter-name>CASFilter</filter-name>  
  20.         <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
  21.         <init-param>  
  22.             <param-name>casServerLoginUrl</param-name>  
  23.             <param-value>https://sso.aurora-framework.org:8080/cas/login</param-value>  
  24.             <!--这里的server是服务端的IP-->  
  25.         </init-param>  
  26.         <init-param>  
  27.             <param-name>serverName</param-name>  
  28.             <param-value>https://sso.aurora-framework.org:8080</param-value>  
  29.         </init-param>  
  30.     </filter>  
  31.     <filter-mapping>  
  32.         <filter-name>CASFilter</filter-name>  
  33.         <url-pattern>/*</url-pattern>  
  34.     </filter-mapping>  
  35.   
  36.     <!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->  
  37.     <filter>  
  38.         <filter-name>CAS Validation Filter</filter-name>  
  39.         <filter-class>  
  40.             org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>  
  41.         <init-param>  
  42.             <param-name>casServerUrlPrefix</param-name>  
  43.             <param-value>https://sso.aurora-framework.org:8080/cas</param-value>  
  44.         </init-param>  
  45.         <init-param>  
  46.             <param-name>serverName</param-name>  
  47.             <param-value>https://sso.aurora-framework.org:8080</param-value>  
  48.         </init-param>  
  49.     </filter>  
  50.     <filter-mapping>  
  51.         <filter-name>CAS Validation Filter</filter-name>  
  52.         <url-pattern>/*</url-pattern>  
  53.     </filter-mapping>  
  54.   
  55.     <!--  
  56.         该过滤器负责实现HttpServletRequest请求的包裹,  
  57.         比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。  
  58.     -->  
  59.     <filter>  
  60.         <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
  61.         <filter-class>  
  62.             org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
  63.     </filter>  
  64.     <filter-mapping>  
  65.         <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
  66.         <url-pattern>/*</url-pattern>  
  67.     </filter-mapping>  
  68.   
  69.     <!--  
  70.         该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。  
  71.         比如AssertionHolder.getAssertion().getPrincipal().getName()。  
  72.     -->  
  73.     <filter>  
  74.         <filter-name>CAS Assertion Thread Local Filter</filter-name>  
  75.         <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>  
  76.     </filter>  
  77.     <filter-mapping>  
  78.         <filter-name>CAS Assertion Thread Local Filter</filter-name>  
  79.         <url-pattern>/*</url-pattern>  
  80.     </filter-mapping>  
  81.       
  82.     <!-- 自动根据单点登录的结果设置本系统的用户信息-->  
  83.     <filter>  
  84.         <display-name>AutoSetUserAdapterFilter</display-name>  
  85.         <filter-name>AutoSetUserAdapterFilter</filter-name>  
  86.         <filter-class>aurora.plugin.sso.cas.AutoSetUserFilter</filter-class>  
  87.         <init-param>  
  88.             <param-name>roleSelectPageUrl</param-name>  
  89.             <param-value>https://sso.aurora-framework.org:8080/yourapp/role_select.screen</param-value>  
  90.         </init-param>  
  91.     </filter>  
  92.     <filter-mapping>  
  93.         <filter-name>AutoSetUserAdapterFilter</filter-name>  
  94.         <url-pattern>/*</url-pattern>  
  95.     </filter-mapping>  
  96.     <!-- ======================== 单点登录结束 ======================== -->  

前面几个都是CAS标准配置,最后一个AutoSetUserAdapterFilter(自定义,可以取其他任意名字)才是我们支持cas的客户化程序。其中roleSelectPageUrl是指用户完成单点登录后跳转的页面

本文档撰写时Java web项目和CAS用同一个tomcat,所以都用的https。否则只需要配置CAS的链接为HTTPS,本项目连接用HTTP。

 

修改CAS的认证逻辑

CAS默认的逻辑是用户名和密码一致就可以登陆,现在需要把原web系统的用户名和密码校验挪到CAS中。这里假设原先web系统中有一张sys_user表存储了用户名和MD5散列后的密码。

打开cas/WEB-INF/deployerConfigContext.xml

  1. 注释掉SimpleTestUsernamePasswordAuthenticationHandler这个Handler,并添加
    [html]  view plain  copy
     
    1. <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">  
    2.     <property ref="dataSource" name="dataSource"></property>  
    3.     <property name="sql" value="select t.encrypted_user_password from sys_user t where t.user_name=?"></property>                       
    4.     <property ref="MD5PasswordEncoder" name="passwordEncoder"></property>  
    5. </bean>  


     

  2.  在文件末尾之前加入数据库的链接:

    [html]  view plain  copy
     
    1. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    2.     <property name="driverClassName">  
    3.         <value>oracle.jdbc.driver.OracleDriver</value>  
    4.     </property>  
    5.     <property name="url">  
    6.         <value>jdbc:oracle:thin:@yourIP:1521:yourOracleInstanceId</value>  
    7.     </property>  
    8.     <property name="username">  
    9.         <value>yourName</value>  
    10.     </property>  
    11.     <property name="password">  
    12.         <value>yourPassword</value>  
    13.     </property>  
    14. </bean>  
    15. <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">  
    16.     <constructor-arg index="0">  
    17.         <value>MD5</value>  
    18.     </constructor-arg>  
    19. </bean>  
  3. cas加入jdbc支持
    复制cas-server-3.5.2\modules\cas-server-support-jdbc-3.5.2.jarOracle驱动(这里采用oracle数据)的ojdbc14.jar或者classes12.jar放到cas/WEB-INF/lib目录下。

  4. 重新登陆Web系统

    重启tomcat,在浏览器中输入https://sso.aurora-framework.org:8080/yourapp/,自动跳转到如下页面:

  5. 输入web系统预先定义的用户名和密码,并跳转到自定义(web.xml中定义的)登陆成功后的页面。

猜你喜欢

转载自paynexss.iteye.com/blog/2341165