使用 CAS 在 Tomcat 中实现单点登录(二)

本文详述如何使用CAS在Tomcat上实现单点登录(SSO),涉及部署依赖包、数据库驱动、CAS Server界面定制、客户端应用配置以及信任关系建立。通过定制页面和配置CAS Filter,确保多个应用间共享登录状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.部署依赖包

在以上配置完成以后,需要拷贝几个依赖的包到 cas应用下,包括:

  • cas-server-support-jdbc-3.1.1.jar拷贝到 %CATALINA_HOME%/webapps/cas/ WEB-INF/lib目录。
  • 数据库驱动,由于这里使用 DB2,将 %DB2_HOME%/java 目录下的 db2java.zip(更名为 db2java.jar, db2jcc.jar, db2jcc_license_cu.jar 拷贝到 %CATALINA_HOME%/webapps/cas/WEB-INF/lib目录。对于其他数据库,同样将相应数据库驱动程序拷贝到该目录。
  • DataStore依赖于 commons-collections-3.2.jar, commons-dbcp-1.2.1.jar, commons-pool-1.3.jar,需要到 apache 网站的 Commons项目下载以上 3个包放进 %CATALINA_HOME%/webapps/cas/WEB-INF/lib目录。

扩展 CAS Server界面

CAS提供了 2套默认的页面,分别为“ default”和“ simple”,分别在目录“ cas/WEB-INF/view/jsp/default”和“cas/WEB-INF/view/jsp/simple”下。其中 default是一个稍微复杂一些的页面,使用 CSS,而 simple则是能让 CAS正常工作的最简化的页面。

在部署 CAS之前,我们可能需要定制一套新的 CAS Server页面,添加一些个性化的内容。最简单的方法就是拷贝一份 default simple文件到“ cas/WEB-INF/view/jsp”目录下,比如命名为 newUI,接下来是实现和修改必要的页面,有 4个页面是必须的:

  • casConfirmView.jsp:当用户选择了“ warn”时会看到的确认界面
  • casGenericSuccess.jsp:在用户成功通过认证而没有目的Service时会看到的界面
  • casLoginView.jsp:当需要用户提供认证信息时会出现的界面
  • casLogoutView.jsp:当用户结束 CAS单点登录系统会话时出现的界面

CAS的页面采用 Spring框架编写,对于不熟悉 Spring的使用者,在修改之前需要熟悉该框架。

页面定制完过后,还需要做一些配置从而让 CAS找到新的页面,拷贝“ cas/WEB-INF/classes/default_views.properties”,重命名为“cas/WEB-INF/classes/ newUI_views.properties”,并修改其中所有的值到相应新页面。最后是更新“cas/WEB-INF/cas-servlet.xml”文件中的 viewResolver,将其修改为如清单 9中的内容。

清单 9.指定 CAS页面

<beanid="viewResolver"
    class="org.springframework.web.servlet.view.ResourceBundleViewResolver"p:order="0">
    <property name="basenames">
        <list>
           <value>${cas.viewResolver.basename}</value>
            <value>newUI_views</value>
        </list>
    </property>
</bean>

回页首

部署客户端应用

单点登录的目的是为了让多个相关联的应用使用相同的登录过程,本文在讲解过程中构造 2个简单的应用,分别以 casTest1 casTest2来作为示例,它们均只有一个页面,显示欢迎信息和当前登录用户名。这 2个应用使用同一套登录信息,并且只有登录过的用户才能访问,通过本文的配置,实现单点登录,即只需登录一次就可以访问这两个应用。

CAS Server建立信任关系

假设 CASServer单独部署在一台机器 A,而客户端应用部署在机器 B上,由于客户端应用与 CAS Server的通信采用 SSL,因此,需要在 A B JRE之间建立信任关系。

首先与 A机器一样,要生成 B机器上的证书,配置Tomcat SSL协议。其次,下载http://blogs.sun.com/andreas/entry/no_more_unable_to_find InstallCert.java,运行“ java InstallCert compA:8443 ”命令,并且在接下来出现的询问中输入 1。这样,就将 A添加到了 B trust store中。如果多个客户端应用分别部署在不同机器上,那么每个机器都需要与 CAS Server所在机器建立信任关系。

配置 CAS Filter

准备好应用casTest1 casTest2过后,分别部署在 B C机器上,由于 casTest1casTest2B C完全等同,我们以 casTest1 B机器上的配置做介绍,假设 A B的域名分别为 domainA domainB

cas-client-java-2.1.1.zip改名为 cas-client-java-2.1.1.jar并拷贝到casTest1/WEB-INF/lib目录下,修改 web.xml文件,添加 CAS Filter,如清单 10所示:

清单 10.添加 CAS Filter

<web-app>
  ...
  <filter>
    <filter-name>CASFilter</filter-name>
   <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
      <param-value>
https://domainA:8443/cas/login</param-value>
    </init-param>
    <init-param>
     <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
      <param-value>
https://domainA:8443/cas/serviceValidate</param-value>
    </init-param>
    <init-param>
     <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
     <param-value>domainB:8080</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CASFilter</filter-name>
   <url-pattern>/protected-pattern/*</url-pattern>
  </filter-mapping>
  ...
</web-app>

对于所有访问满足casTest1/protected-pattern/路径的资源时,都要求到 CAS Server登录,如果需要整个 casTest1均受保护,可以将 url-pattern指定为“/*”。

从清单 10可以看到,我们可以为 CASFilter指定一些参数,并且有些是必须的,表格 1 表格 2 中分别是必需和可选的参数:

表格 1. CASFilter必需的参数

参数名

作用

edu.yale.its.tp.cas.client.filter.loginUrl

指定 CAS提供登录页面的 URL

edu.yale.its.tp.cas.client.filter.validateUrl

指定 CAS提供 service ticket proxy ticket验证服务的 URL

edu.yale.its.tp.cas.client.filter.serverName

指定客户端的域名和端口,是指客户端应用所在机器而不是 CAS Server所在机器,该参数或 serviceUrl至少有一个必须指定

edu.yale.its.tp.cas.client.filter.serviceUrl

该参数指定过后将覆盖 serverName参数,成为登录成功过后重定向的目的地址

表格 2. CASFilter可选参数

参数名

作用

edu.yale.its.tp.cas.client.filter.proxyCallbackUrl

用于当前应用需要作为其他服务的代理(proxy)时获取 Proxy Granting Ticket的地址

edu.yale.its.tp.cas.client.filter.authorizedProxy

用于允许当前应用从代理处获取 proxy tickets,该参数接受以空格分隔开的多个 proxy URLs,但实际使用只需要一个成功即可。当指定该参数过后,需要修改 validateUrl proxyValidate,而不再是 serviceValidate

edu.yale.its.tp.cas.client.filter.renew

如果指定为 true,那么受保护的资源每次被访问时均要求用户重新进行验证,而不管之前是否已经通过

edu.yale.its.tp.cas.client.filter.wrapRequest

如果指定为 true,那么 CASFilter将重新包装 HttpRequest,并且使 getRemoteUser()方法返回当前登录用户的用户名

edu.yale.its.tp.cas.client.filter.gateway

指定 gateway属性

传递登录用户名

CAS在登录成功过后,会给浏览器回传 Cookie,设置新的到的 Service Ticket。但客户端应用拥有各自的 Session,我们要怎么在各个应用中获取当前登录用户的用户名呢?CAS Client Filter已经做好了处理,在登录成功后,就可以直接从 Session的属性中获取,如清单 11所示:

清单 11. Java中通过 Session获取登录用户名

//以下两者都可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute("edu.yale.its.tp.cas.client.filter.user");

JSTL中获取用户名的方法如清单12所示:

清单 12.通过 JSTL获取登录用户名

<c:outvalue="${sessionScope[CAS:'edu.yale.its.tp.cas.client.filter.user']}"/>

另外,CAS提供了一个CASFilterRequestWrapper类,该类继承自HttpServletRequestWrapper,主要是重写了getRemoteUser()方法,只要在前面配置 CASFilter的时候为其设置“ edu.yale.its.tp.cas.client.filter.wrapRequest”参数为 true,就可以通过getRemoteUser()方法来获取登录用户名,具体方法如清单 13所示:

清单 13.通过CASFilterRequestWrapper获取登录用户名

CASFilterRequestWrapper  reqWrapper=newCASFilterRequestWrapper(request);
out.println("The logon user:" + reqWrapper.getRemoteUser());

回页首

效果

casTest1 casTest2中,都有一个简单Servlet作为欢迎页面 WelcomPage,且该页面必须登录过后才能访问,页面代码如清单 14所示:

清单 14. WelcomePage页面代码

public class WelcomePage extendsHttpServlet {
  public void doGet(HttpServletRequestrequest, HttpServletResponse response)
  throws IOException, ServletException
  {
   response.setContentType("text/html");
    PrintWriter out =response.getWriter();
   out.println("<html>");
   out.println("<head>");
   out.println("<title>Welcome to casTest2 sampleSystem!</title>");
   out.println("</head>");
   out.println("<body>");
    out.println("<h1>Welcometo casTest1 sample System!</h1>");
    CASFilterRequestWrapper  reqWrapper=new CASFilterRequestWrapper(request);
    out.println("<p>The logonuser:" + reqWrapper.getRemoteUser() + "</p>");
    HttpSession session=request.getSession();
    out.println("<p>The logonuser:" +
                  session.getAttribute(CASFilter.CAS_FILTER_USER)  + "</p>");
    out.println("<p>The logonuser:" +
        session.getAttribute("edu.yale.its.tp.cas.client.filter.user")+ "</p>");
   out.println("</body>");
   out.println("</html>");
    }
}

在上面所有配置结束过后,分别在 A B C上启动 cas casTest1 casTest2,按照下面步骤来访问 casTest1 casTest2

  1. 打开浏览器,访问 http://domainB:8080/casTest1/WelcomePage ,浏览器会弹出安全提示,接受后即转到 CAS 的登录页面,如图 2所示:

2. CAS登录页面


  1. 登录成功后,再重定向到 casTest1 WelcomePage页面,如 所示:

3.登录后访问 casTest1的效果


可以看到 中地址栏里的地址多出了一个 ticket 参数,这就是 CAS 分配给当前应用的ST(Service Ticket)。

  1. 再在同一个浏览器的地址栏中输入 http://domainC:8080/casTest2/WelcomePage ,系统不再提示用户登录,而直接出现如图 4 所示的页面,并且显示在 casTest1中已经登录过的用户。

4. casTest1中登录过后访问 casTest2的效果


  1. 重新打开一个浏览器窗口,先输入 http://domainC:8080/casTest2/WelcomePage ,系统要求登录,在登录成功过后,正确显示 casTest2 的页面。之后再在地址栏重新输入 http://domainB:8080/casTest1/WelcomePage ,会直接显示 casTest1 的页面而无需再次登录。



      原文参考:http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值