一、概述
单点登录(single sign on , 简称 sso )是目前比较流行的服务于企业业务整合的凯发天生赢家一触即发官网的解决方案之一, sso 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。cas(central authentication service)是一款不错的针对 web 应用的单点登录框架,本文介绍了 cas 的原理、协议、在 tomcat 中的配置和使用,对于采用 cas 实现轻量级单点登录凯发天生赢家一触即发官网的解决方案的入门读者具有一定指导作用。
二、cas介绍
cas 是 yale 大学发起的一个开源项目,旨在为 web 应用系统提供一种可靠的单点登录方法,cas 在 2004 年 12 月正式成为 ja-sig 的一个项目(http://www.jasig.org)。cas 具有以下特点:
1)开源的企业级单点登录凯发天生赢家一触即发官网的解决方案
2)cas server 为需要独立部署的 web 应用
3)cas client 支持非常多的客户端(指web 应用),包括java,.net,php,perl,ruby 等
三、cas原理及协议
从结构上看,cas 包含两个部分: cas server 和 cas client。cas server 需要独立部署,主要负责对用户的认证工作;cas client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 cas server。as 最基本的协议过程:
cas client 与受保护的客户端应用部署在一起,以 filter 方式保护受保护的资源。对于访问受保护资源的每个 web 请求,cas client 会分析该请求的 http 请求中是否包含 service ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 cas server 登录地址,并传递 service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,cas server 随机产生一个相当长度、唯一、不可伪造的 service ticket,并缓存以待将来验证,之后系统自动重定向到 service 所在地址,并为客户端浏览器设置一个 ticket granted cookie(tgc),cas client 在拿到 service 和新产生的 ticket 过后,在第 5,6 步中与 cas server 进行身份合适,以确保 service ticket 的合法性。
在该协议中,所有与 cas 的交互均采用 ssl 协议,确保,st 和 tgc 的安全性。协议工作过程中会有 2 次重定向的过程,但是 cas client 与 cas server 之间进行 ticket 验证的过程对于用户是透明的。
另外,cas 协议中还提供了 proxy (代理)模式,以适应更加高级、复杂的应用场景,具体介绍可以参考 cas 官方网站上的相关文档。
四、cas server配置
1.准备工作
安装配置jdk、安装tomcat7,此处不做详解。
到cas凯发k8网页登录官网下载cas server和client,地址如下:
http://downloads.jasig.org/cas/cas-server-4.0.0-release.zip
http://downloads.jasig.org/cas-clients/cas-client-3.2.1-release.zip
2.部署
1.将下载的cas-server-4.0.0-release.zip解开,把cas-server-4.0.0/modules/cas-server-webapp-4.0.0.war拷贝到 tomcat的webapps目录,并更名为cas.war。
2.修改cas\web-inf\spring-configuration\ticketgrantingticketcookiegenerator.xml文件,将属性p:cookiesecure="true" 变成 p:cookiesecure="false"(这个设置主要是让cas不走ssl协议,详见:让cas不用ssl也可实现跨域)
3.启动tomcat,然后访问:http://localhost:8888/cas,如果能出现正常的cas登录页面,则说明cas server 已经部署成功。如下图:
虽然 cas server 已经部署成功,但这只是一个缺省的实现,在实际使用的时候,还需要根据实际概况做扩展和定制,最主要的是扩展认证 (authentication) 接口和 cas server 的界面。
五、cas client配置
将下载的cas-client-3.2.1-release.zip解开,将cas-client-3.2.1/modules/
cas-client-core-3.2.1.jar,放入你的web项目lib目录中,修改web.xml,添加如下web.xml中单点登录块配置信息:
xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="webapp_id" version="2.5">
<display-name>casclientonedisplay-name>
<welcome-file-list>
<welcome-file>index.htmlwelcome-file>
<welcome-file>index.htmwelcome-file>
<welcome-file>index.jspwelcome-file>
<welcome-file>default.htmlwelcome-file>
<welcome-file>default.htmwelcome-file>
<welcome-file>default.jspwelcome-file>
welcome-file-list>
<listener>
<listener-class>org.jasig.cas.client.session.singlesignouthttpsessionlistenerlistener-class>
listener>
<filter>
<filter-name>cas single sign out filterfilter-name>
<filter-class>org.jasig.cas.client.session.singlesignoutfilterfilter-class>
filter>
<filter-mapping>
<filter-name>cas single sign out filterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>casfilterfilter-name>
<filter-class>org.jasig.cas.client.authentication.authenticationfilterfilter-class>
<init-param>
<param-name>casserverloginurlparam-name>
<param-value>http://localhost:8888/cas/loginparam-value>
init-param>
<init-param>
<param-name>servernameparam-name>
<param-value>http://localhost:8080param-value>
init-param>
filter>
<filter-mapping>
<filter-name>casfilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>cas validation filterfilter-name>
<filter-class>org.jasig.cas.client.validation.cas20proxyreceivingticketvalidationfilterfilter-class>
<init-param>
<param-name>casserverurlprefixparam-name>
<param-value>http://localhost:8888/casparam-value>
init-param>
<init-param>
<param-name>servernameparam-name>
<param-value>http://localhost:8080param-value>
init-param>
filter>
<filter-mapping>
<filter-name>cas validation filterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>cas httpservletrequest wrapper filterfilter-name>
<filter-class>org.jasig.cas.client.util.httpservletrequestwrapperfilterfilter-class>
filter>
<filter-mapping>
<filter-name>cas httpservletrequest wrapper filterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>cas assertion thread local filterfilter-name>
<filter-class>org.jasig.cas.client.util.assertionthreadlocalfilterfilter-class>
filter>
<filter-mapping>
<filter-name>cas assertion thread local filterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
配置完毕后,启动tomcat,然后访问:http://ip:port/webproname/index.jsp,如果系统跳转到cas登录页面,输入用户名/密码(正确的)后,会跳转到http://ip:port/webproname/index.jsp,则说明cas client已经部署成功。
注:到此cas框架已搭建完毕,此种方法未采用ssl协议(需要修改cas),如果想采用ssl协议方式,则在上述配置中需要以下调整:
- 修改cas server所处web容器(本文为tomcat),使其支持ssl协议
- cas server部署时,不需要修改cas\web-inf\spring-configuration\ticketgrantingticketcookiegenerator.xm
- cas client web.xml中配置的cas server相关地址需要将http变更成https
六、jdbc认证方式
1.相关jar包准备
cas-server-4.0.0-release.zip\cas-server-4.0.0\modules\cas-server-support-jdbc-4.0.0.jar及相应的数据库驱动包(这里是mysql驱动mysql-connector-java-5.1.7-bin.jar)复制到cas/web-inf/lib目录下。
2.修改deployerconfigcontext.xml1.
com.mysql.jdbc.driver
jdbc:mysql://localhost:3309/ossm?characterencoding=utf8
root
root
md5
七、客户端获取用户登录信息
cas登录成功默认返回的只有用户名,
java客户端获取:
attributeprincipal principal = (attributeprincipal) request.getuserprincipal();
string username = principal.getname();
而在实际应用中,客户端需要知道更多的用户信息,比如用户的性别,年龄,爱好,地址,用户的分组,角色信息等等,下面介绍如何给客户端返回更多的用户资料和信息:
1.修改cas/web-inf/deployerconfigcontext.xml,注释掉原有的attributerepository及attributerepository的引用信息,添加如下信息:
or
2.修改cas/web-inf/view/jsp/protocol/2.0/casservicevalidationsuccess.jsp,添加下方标红部分:1.
<cas:serviceresponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationsuccess>
<cas:user>${fn:escapexml(assertion.primaryauthentication.principal.id)}cas:user>
<%-- 返回更多用户信息配置 by goma --%>
"${fn:length(assertion.chainedauthentications[fn:length(assertion.chainedauthentications)-1].principal.attributes) > 0}">
"attr" items="${assertion.chainedauthentications[fn:length(assertion.chainedauthentications)-1].principal.attributes}">
${fn:escapexml(attr.value)}
<c:if test="${not empty pgtiou}">
<cas:proxygrantingticket>${pgtiou}cas:proxygrantingticket>
c:if>
<c:if test="${fn:length(assertion.chainedauthentications) > 1}">
<cas:proxies>
<c:foreach var="proxy" items="${assertion.chainedauthentications}" varstatus="loopstatus" begin="0" end="${fn:length(assertion.chainedauthentications)-2}" step="1">
<cas:proxy>${fn:escapexml(proxy.principal.id)}cas:proxy>
c:foreach>
cas:proxies>
c:if>
cas:authenticationsuccess>
cas:serviceresponse>
3.客户端取值3.
attributeprincipal principal = (attributeprincipal) request.getuserprincipal();
string username = principal.getname();
map attributes = principal.getattributes();
string email = attributes .get("email") "";
八、界面定制
cas 提供了一套默认的页面,在目录cas/web-inf/view/jsp/default下。在部署 cas 之前,我们可能需要定制一套新的cas server页面,添加一些个性化的内容。最简单的方法就是拷贝一份 default文件到“ 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,重命名为as/web-inf/classes/ newui_views.properties,并修改其中所有的值到相应新页面。最后是更新cas/web-inf/cas-servlet.xml文件中的 viewresolver,将protocol_views更改为newui_views。
九、其他功能扩展
增加验证码、密码有效期、限制用户登录之类的功能这里不做描述,如果需要请自行查找。