cas 代理认证配置
注:本文转自http://www.ichatter.net/2013/03/21/385/
CAS(Central Authentication Service)框架是一个开源的单点登陆框架。最近公司要将几个产品实现单点登陆,同事在负责技术筛选时选择了CAS,并已实现了单点登陆功能,但是在配置代理功能时,遇到了诸多问题,目前虽然代理勉强可用,但问题重重,比如系统A在后台需要访问系统B的功能,在此情景中,系统A就相当于代理应用,而系统B是被代理的应用。
问题如下:
1.系统A作为代理,不能向被代理应用系统B发送POST方式的HTTP请求。
2.系统A向系统B发送GET请求时,不能以URL附加的方式传参数(形如 http://myhost.com:8080/myapp?name=abc),只能以RESTFUL风格传参数(形如:http://myhost.com:8080/myapp/abc)。
3.测试期间,应用服务器重启后,偶尔出现系统A代理失效的情况,此时需要注销用户,重新登陆。 如上种种,极大地限制了CAS单点登陆的灵活性及稳定性。据了解,同事在实现代理功能时,稍微走了偏门。
其大概实现方式如下:
1.在CAS验证服务器后台用户表中增加一个字段castgc,当用户验证通过时,可用于保存cookie数据tgc(Ticket Granting Cookie)。
2.当用户浏览器访问系统A时,被重定向至CAS服务器进行验证,正确输入帐密后通过验证,服务器后台保存castgc字段值至用户表中,同时CAS客户端系统A将此castgc保存至session中,以备代理时使用。
3.系统A以代理身份访问系统B时,会从session中取出castgc,放入请求头(request.setHeader(“Cookie”,castgc);)。然后系统B接收到此请求,会拿着此Cookie到CAS服务器验证,验证通过后,便重定向至系统B,让其响应代理即系统A,整个请求处理即告完成。
OK,回到主题,我将借鉴网上的部分资料并以最接近官方的方式和最少的配置实现CAS代理功能。在开始之前,我们先给本地机器做些小小的改动,找到本地系统中的文件C:\WINDOWS\system32\drivers\etc\hosts,在末尾加上:
###########
127.0.0.1 cas-server.test.com
127.0.0.1 cas-client1.test.com
127.0.0.1 cas-client2.test.com
###########
目的是为了让我们便于区别cas服务端与各个客户端的url,同时加深理解。
开始步骤如下:
1.下载CAS服务端和客户端的最新版本:
CAS服务端:http://downloads.jasig.org/cas/cas-server-3.5.2-release.zip
CAS客户端:http://downloads.jasig.org/cas-clients/cas-client-3.2.1-release.zip
2.部署服务端:
首先将它们全部解压。先看服务端,解压后的目录中找到cas-server-3.5.2\modules\cas-server-webapp-3.5.2.war,这就是打包后的服务端程序,把它拷出来重命名为cas-server,直接丢进tomcat中就可以在运行时被自动解压并访问了。(注意访问的URL,就是前面配置过的) 由于本文不使用https方式访问,为了使http方式的单点登陆功能生效,必须对工程中的文件\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml做一点修改,将其中的p:cookieSecure=”true”改为p:cookieSecure=”false”,即可实现http单点登陆。但还要再配置\WEB-INF\deployerConfigContext.xml,在
<bean
class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" />
中增一个属性 p:requireSecure=”false”,否则后面的代理票据无法生成,也就无法实现代理功能。
3.构建客户端工程cas-client1:
客户端的工程也很简单,用eclipse创建一个Dynamic Web Project,命名为cas-client1,然后做点改动。
a.将解压后目录中的\cas-client-3.2.1\modules\cas-client-core-3.2.1.jar拷到cas-client1工程的lib目录下。
b.将官方的4个filter拷到工程的web.xml文件中,参考官方文档:https://wiki.jasig.org/display/CASC/Configuring+the+Jasig+CAS+Client+for+Java+in+the+web.xml,并自己加上对应的filter-mapping(完整配置见文后示例),并将其中的所有filter配置中init-param对应的url进行相应的修改,如:
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://cas-server.test.com:8080/cas-server/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://cas-client1.test.com:8080</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://cas-server.test.com:8080/cas-server/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://cas-client1.test.com:8080</param-value>
</init-param>
</filter>
其中要注意的是,官方声明:Proxy Authentication If you are using proxy validation, you should map the validation filter before the authentication filter.也就是说前面配置的4个filter,其中validation filter必须在authentication filter之前先被映射。如下:
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
c.如上是官方文档中的配置,除此之外,我们要实现代理,还要在validation filter中加入两个参数,如下:
<init-param>
<param-name>proxyCallbackUrl</param-name>
<!-- 特别注意,此地址必须是能从单点登录服务器访问到的地址,因为单点服务器会回调此URL -->
<param-value>http://cas-client1.test.com:8080/cas-client1/proxyCallback</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxyCallback</param-value>
</init-param>
加入filter-mapping供后面的被代理应用cas-client2回调时使用,如下:
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/proxyCallback</url-pattern>
</filter-mapping>
d.写一个自定义的servlet,并配置到web.xml中。核心代码如下:
public class HelloWorldExample extends HttpServlet { private static final long serialVersionUID = 1L; @Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// ........
HttpSession session = request.getSession();
final Assertion assertion = (Assertion) (session == null ? request
.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session
.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION));
// 被代理应用的URL
String serviceUrl = "http://cas-client2.test.com:8080/cas-client2/HelloWorldExample";
final String proxyTicket = assertion.getPrincipal().getProxyTicketFor(
serviceUrl);
URL url = new URL(serviceUrl + "?ticket=" + proxyTicket);// 不需要cookie,只需传入代理票据
HttpURLConnection conn = null; conn = (HttpURLConnection) url.openConnection();
// conn.setRequestMethod("POST");//使用POST方式
conn.setDoOutput(true);
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(),
"UTF-8");
osw.write("name=阿J小虫abc");// 传参
osw.close(); // 业务处理
// ........
}
}
web.xml加入如下:
<!-- my filter -->
<servlet>
<servlet-name>HelloWorldExample</servlet-name>
<servlet-class>HelloWorldExample</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldExample</servlet-name>
<url-pattern>/HelloWorldExample</url-pattern>
</servlet-mapping>
到此为止,我们的第一个客户端工程cas-client1构建完毕,将它与cas-server一起部署到tomcat并运行,即可看到单点登陆的效果(用户名和密码相同即可通过验证)。
4.构建客户端工程cas-client2:
将cas-client1复制出来重命名为cas-client2。具体来讲,作为被代理应用,它主要是用来从cas-client1获取请求参数name=阿J小虫,然后响应代理(输出数据)。
代码块如下:
String name = request.getParameter("name");
if (name != null)
System.out
.println(new String(name.getBytes("iso-8859-1"), "utf-8"));
PrintWriter out = response.getWriter();
out.print("congratulation!you got it from cas-client2!");
另外,被代理应用也可以作为第三个客户端的代理应用,但在此不作考虑,所以可以注释掉validation filter中的参数proxyCallbackUrl和proxyReceptorUrl,并加入另外两个参数redirectAfterValidation和acceptAnyProxy,如下:
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://cas-server.test.com:8080/cas-server/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://cas-client2.test.com:8080</param-value>
</init-param>
<!-- <init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>http://cas-client2.test.com:8080/cas-client2/proxyCallback </param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxyCallback</param-value>
</init-param> -->
<init-param>
<!-- redirectAfterValidation must be false, otherwise the request params
from proxying app could not be received -->
<param-name>redirectAfterValidation</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>acceptAnyProxy</param-name>
<param-value>true</param-value>
</init-param>
</filter>
最后记得将拷过来的web.xml文件中的相关url改成与cas-client2对应的。与cas-server和cas-client1一同部署,登陆cas-client1代理程序时,后台成功实现对cas-client2的访问并获取返回数据。
注意事项:
1.当用eclipse进行调试时,如把断点设置在获取响应之前,可能会出现异常,如下:
三月 21, 2013 3:00:30 下午
org.jasig.cas.client.validation.AbstractTicketValidationFilter doFilter
WARNING: org.jasig.cas.client.validation.TicketValidationException:
未能够识别出目标 'ST-2-cMeR2w5xzryNeSuh3jx9-cas01.example.org'票根
一开始我也以为票根有问题,此时,只要取消断点重新登陆一下就能顺利响应了,至于为什么设置断点就报错,可能是网络的响应被断点中断从而延时了导致的。
2.被代理应用cas-client2中的validation filter参数redirectAfterValidation必须设置为false,否则接收不到代理传过来的请求参数,如name=阿J小虫。还有参数acceptAnyProxy与allowedProxyChains二选一,如果配置acceptAnyProxy,必须为true,本文示例使用此参数。
cas 代理认证配置的更多相关文章
- No.2 CAS之SPNEGO+LDAP认证配置
1.概述 本文先配置了SPNEGO认证,就是如果用户操作系统如果登陆了公司的Windows域,用户浏览器访问应用服务即可免登录. 然后如果不在域里的员工,用LDAP认证方式,输账号密码登陆. 参考文档 ...
- jfinal集成cas单点认证实践
本示例jfinal集成cas单点认证,采用获取到登录用户session信息后,在本地站点备份一份session信息,主要做以下几个步骤: 1.站点引入响应jar包: 2.在web.xml中配置对应过滤 ...
- Liferay7.0与cas单点登录配置
1.简介 Liferay7.0支持多种登录方式,包括:常规的.opensso.cas.ntlm.ldap.openid.Facebook.Google等. 其中, (1) 常规:则是默认Lif ...
- cas的客户端配置
知识点:cas的客户端配置 一:cas客户端配置 二:cas认证流程原理(图) 参考:https://www.cnblogs.com/suiyueqiannian/p/9359597.html 源码: ...
- 企业IT管理员IE11升级指南【15】—— 代理自动配置脚本
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- Nginx反向代理的配置
Chapter: Nginx基本操作释疑 1. Nginx的端口修改问题 2. Nginx 301重定向的配置 3. Windows下配置Nginx使之支持PHP 4. Linux下配置Nginx使之 ...
- 【转】Nginx服务器的反向代理proxy_pass配置方法讲解
[转]Nginx服务器的反向代理proxy_pass配置方法讲解 转自:http://www.jb51.net/article/78746.htm 就普通的反向代理来讲Nginx的配置还是比较简单的, ...
- nginx用户认证配置( Basic HTTP authentication)
ngx_http_auth_basic_module模块实现让访问着,只有输入正确的用户密码才允许访问web内容.web上的一些内容不想被其他人知道,但是又想让部分人看到.nginx的http aut ...
- nginx反向代理的配置优化
作者:守住每一天 blog:liuyu.blog.51cto.combbs:bbs.linuxtone.orgmsn:liuyubj520#hotmail.comemail:liuyu105#gmai ...
随机推荐
- cordova crosswalk android 7.0 问题
带有crosswalk的cordova app 在Android7.0会闪退问题,为什么要crosswalk,我的回答是,还tmd不是要兼容5.0以下系统(4.4,4.2,4.0),这里省略100 ...
- PMS5003ST+Arduino Nano 串口读取数据
先上代码: 库文件是在guihub上的大神写的https://github.com/jbanaszczyk,我拿来小改下用以支持5003ST #include <Arduino.h> #i ...
- 玩转Node.js单元测试
代码部署之前,进行一定的单元测试是十分必要的,这样能够有效并且持续保证代码质量.而实践表明,高质量的单元测试还可以帮助我们完善自己的代码.这篇博客将通过一些简单的测试案例,介绍几款Node.js测试模 ...
- 富文本,NSAttributedString,当需要改变的内容有相同的时候的解决方法
在开发的过程中可能会遇到富文本展示,例如:一行文本,前面是题后面是答案,题和答案用不同的颜色字体,但是答案的内容在题总也有,这时候用平常的方法就会展示错误,因为把题中的内容改变了颜色二实际答案却没有改 ...
- 实验楼-3-Linux用户及用户组
获得自己用户名 $ who am i $ whoami pts/0 : 伪终端/序号 root操作:sudo Firstly,知道当前登录用户的密码:Secondly,当前用户在sudo用户组 添加新 ...
- 日期控件My97DatePicker的使用
一. 简介 1. 简介 目前的版本是:4.8 2. 注意事项 My97DatePicker目录是一个整体,不可破坏里面的目录结构,也不可对里面的文件改名,可以改目录名 My97DatePicker.h ...
- 区分 点操作符+属性名 和 getAttribute()
在用DOM操作控制HTML时,很多初学者会把 点操作符+属性名 与getAttribute("属性名") 混淆,误以为这两种方法是等价的. 实际上, 通过getAttribute( ...
- oracle server config
安装oracle数据库软件 database/runInstaller; ##执行该程序开始安装 创建数据库 在oracle用户的图形界面oracle用户中 新开启一个终端,直接输入命令dbca会弹出 ...
- Meta http-equiv属性详解
http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...
- Intellj IDEA 简易教程
Intellj IDEA 简易教程 目录 JDK 安装测试 IDEA 安装测试 调试 单元测试 重构 Git Android 其他 参考资料 Java开发IDE(Integrated Developm ...