欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-14 14:06:40
...

添加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/,自动跳转到如下页面:CAS做单点登陆(SSO)——集成Java Web 项目
            
    
    博客分类: SSO CASSSO 

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

相关标签: CAS SSO