- 浏览: 176755 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
vil:
请问CAS 单点登录加负载均衡后,httpClient tim ...
(转)CAS负载均衡配置 -
bcs2099:
男男女女[flash=200,200][/flash]
学Ext的好网站 -
bcs2099:
不过关
学Ext的好网站 -
qingteng1983:
请问,这个上传组件支持断点续传吗?
利用SWFUpload实现大附件上传 -
yangwn:
LZ,我想请教,hdfs://192.168.4.27:900 ...
编写JAVA代码读取Hadoop存储服务器文件
http://fallenlord.blogbus.com/logs/57175888.html
前阵子改造系统,需要做CAS的Proxy,上网找了很久,找到了一些讲述原理的文章,但几乎没有讲述配置的文章,有讲述配置的也是错误的或是不完整的或是针对2.x版本的,还有很多是直接把代理配置当做普通配置使用-_-
那么,既然网上没有,我就在这里写一下吧
1. 什么情况下需要使用代理
显然这是最需要首先搞清楚的一个问题
假设现在有服务A使用了CAS,我们作为用户zhangsan去访问服务A,这没有什么问题
然后出现了一个新的需求,有服务B也实现了CAS,要求我们仍然只是访问A,但是A会以我们相同的用户(zhangsan)去访问服务B获取我们所需的内容并呈现出来。
此时A就被我们称为代理(Proxy),B被称为后台服务(back-end service)或被代理应用(Proxied Application)
一个简单的应用场景就是Portal,我们只访问Portal,由Portal去各个子系统抓取我们所需的内容并呈现出来
如果有兄弟没有玩过Portal,那么iGoogle也是个很好的场景,你在iGoogle上登录后就可以直接查看到GMail的内容了,这就是用了Proxy技术
2. 代理运转原理
运转原理写起来比较麻烦,这里推荐三篇文章,均是介绍CAS的代理运转原理的:
- 1. 传说中的David Turing写的《剖析CAS Proxy的设计原理 》,它的博客里有很多CAS相关的原创
- 2. 传说中的被open-open.com收录的CAS学习笔记:http://linliangyi2007.iteye.com/blog/165310
- 3. 传说中的CAS官网的Walkthrough:http://www.ja-sig.org/wiki/display/CAS/Proxy+CAS+Walkthrough
相信看完以上三篇神来之笔后,可以对CAS代理这块的原理有个简单的认识
但需要深入理解,显然光靠神来之笔是靠不住的
3. 代理相关配置
OK,直接就到配置了,首先我们需要分为两部分来描述,第一部分是代理应用(Proxying Applicatiion)也就是前端的Portal之类的东东:
<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://www.cas-server.com</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>exceptionOnValidationFailure</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://www.local-app.com</param-value>
</init-param>
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>http://www.local-app.com/cas-proxy/proxyCallback</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxyCallback</param-value>
</init-param>
</filter>
高亮的两个参数配置应该指向实际同一个地址(只是proxyReceptorUrl用相对路径描述,而proxyCallbackUrl用绝对路径 描述),它们将为这个服务提供一个callback的拦截,使得在每次validator去校验ST的时候,CAS服务器都会发起一个回调请求来访问 proxyCallbackUrl的位置(因此这个地址必须是绝对地址且从CAS服务器发起请求可以访问到的),将PGT(及PGTIou)告诉这个代理 应用,而代理应用会保存这个PGT到Session中
这里有个需要特别注意的问题,这个问题在所有的帖子甚至官方的文档中都没有提及,那就是回调的地址,必须在AuthenticationFilter的url-pattern之前单独的配出来:
<filter-mapping>
<filter-name>CAS Validation Filter
</filter-name>
<url-pattern>/proxyCallback
</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
否则callback调用会被AuthenticationFilter给拦截而无法到达ValidationFilter
第二部分是后端服务:
<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://www.cas-server.com</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>exceptionOnValidationFailure</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://www.local-app.com</param-value>
</init-param>
<init-param>
<param-name>acceptAnyProxy</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>http://www.local-app.com/cas-backend/proxyCallback</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxyCallback</param-value>
</init-param>
</filter>
以上高亮代码的acceptAnyProxy是后端服务所必须的(它与allowedProxyChains两个配置二选一),若没有配置acceptAnyProxy或allowedProxyChains,将无法校验代理票据(Proxy Ticket)
而proxyCallbackUrl和proxyReceptorUrl是可选的,如果给出则在校验代理票据(Proxy Ticket)时同时CAS会再次执行回调颁发PGT给此后台服务,使之可以同时成为代理用于代理另一个后台服务。若不配置则CAS不会告诉此应用PGT
4. 如何使用代理
看起来好像大功告成了,但是实际上还有最重要的一点我们还没做,就Server to Server的这个请求要怎么来发的问题
首先,既然要发送请求,一定是我们的代理端已经完成了到CAS的认证,那么我们首先获取到Assertion:
final Assertion assertion = (Assertion) (session == null ? request.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION));
然后从assertion中获取到proxy ticket:
final String proxyTicket = assertion.getPrincipal().getProxyTicketFor(serviceUrl);
最后将proxyTicket以参数的形式绑定到serviceUrl(待访问的backend service地址)之后并发送请求,参数名必须是ticket:
URL url = new URL(serviceUrl + "?ticket=" + proxyTicket);
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
// 业务处理
...
} catch (final Exception ex) {
...
} finally {
if (conn != null) {
conn.disconnect();
}
}
...
这样,当后台服务(back-end service)获取到这条请求后,会到CAS上去校验ticket是否为合法的PT,若合法则允许通过(此时redirectAfterValidation应该为false以避免直接响应一个302 Redirect请求)
5. 代理使用方案的一点点讨论
按照上面的做法,应该说功能都已经实现了,那么现在的问题是什么呢?——性能与压力
这里面有两次请求是我们看起来多余的:
- 1. 从代理端Assertion中获取PT需要发送一次请求给CAS(PT由CAS颁发)
- 2. 从被代理端获取到PT后发送请求给CAS以求校验
这些请求触发频率是每次代理端向被代理端发送请求时,不光消耗了代理端和被代理端的性能,也对CAS产生了多余的压力。
那么如何解决这个问题呢?有两种方案:
- 1. 缓存,在代理和被代理两端将PT缓存起来,这样只有第一次双方需要去访问CAS请求颁发PT和校验PT,以后可以直接使用这个PT即可
- 2. 颁发自己的票据,这与前端Browser-CAS客户端的模式很相似,CAS客户端为浏览器颁发SessionID作为自己的认证标识,从而撇开了CAS服务器,那么这里我们也可以由被代理端向代理端颁发一个唯一的标识来作为自己的认证标识
这两种方法如出一辙,其实本质上没什么区别。在我们的系统改造中,最后使用的是后者,这是由于它本身就存在一个自己的票据的功能
OK,接下来我们看下使用第二种方案的改造细节吧
方案决定了我们只是需要在第一次代理端到被代理端认证的时候发起与CAS的认证,因此我们继承了 org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter 类,实现了自己的ValidationFilter只扩展了它的一个方法:
protected void onSuccessfulValidation(final HttpServletRequest
request, final HttpServletResponse response, final Assertion assertion)
{
// 认证服务地址
final String loginServiceUrl = "http://somewhere.com/loginService
";
// serviceUrl为要发送的目标地址——被代理端上的一个URL
final String proxyTicket = assertion.getPrincipal().getProxyTicketFor(loginServiceUrl);
final String username = assertion.getPrincipal().getName();
// 获取到URLConnection或是HttpClient
URL url = new URL(loginServiceUrl + "?ticket=" + proxyTicket);
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
// 业务处理
// 将响应回来的myticket存储到Session中,以后每次发送请求都将携带这个myticket
// 而被代理端也将myticket存储到Session中,以后每次互相访问都只需校验此值即可
...
} catch (final Exception ex) {
...
} finally {
if (conn != null) {
conn.disconnect();
}
}
...
}
这个方法将在票据第一次被校验成功的时候触发
在被代理端,我们新建一个地址为/loginService的服务,大致逻辑如下:
// 获取CAS票据
String proxyTicket = req.getParameter("ticket");
if (proxyTicket == null) {
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Proxy ticket not specified");
}
try {
// 使用CAS代理票据校验器校验PT
final Cas20ProxyTicketValidator validator = new Cas20ProxyTicketValidator(casServerUrlPrefix);
validator.setAcceptAnyProxy(true);
final String serviceUrl = req.getServerPath() + req.getServicePath();
final Assertion assertion = validator.validate(proxyTicket, serviceUrl);
// 完成认证并从Session中获取myticket
authenticationComponent.setCurrentUser(username);
final String myTicket = authenticationService.getCurrentTicket();
render(myTicket);
} catch (AuthenticationException ex) {
logger.error("Login failed", ex);
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Login failed");
} catch (TicketValidationException ex) {
logger.error("Ticket validate failred.", ex);
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Ticket validate failred");
} finally {
// ...
}
可以看到,我们自己实例化了一个CAS的Validator来完成校验而不是通过那些CAS的Filter,这使得整个后端服务可以无需被CAS Filter拦截(当然,被拦截了也没啥关系)
OK,至此,一个较为完整的CAS代理就完成了,have fun
发表评论
-
(转)CAS负载均衡配置
2010-01-28 09:38 8108http://fallenlord.blogbus.com ... -
获取汉字拼音首字母功能函数
2010-01-18 14:52 963如: System.out.println(HZPY. ... -
JAVA MVC构架详解
2009-12-22 15:04 990整理。。。 -
Web服务端组件事件开发与MVC开发
2009-12-19 11:14 1256本周一起跟.net开 ... -
内存控制效率优化的启示
2009-12-05 10:01 8734 内存控制效率优化的 ... -
记录下载中文附件出现乱码
2009-10-28 14:16 876环境:jsp页面,编码全部用UTF-8 在下载代码中写 ... -
web.xml 中 mime-mapping的使用
2009-10-08 09:58 6099mime-mapping 如果Web应用程序包含一 ... -
从Struts到Spring MVC的应用
2009-09-27 11:42 1479从 Struts 转到 Spring MVC 的应用 ... -
容易被搞晕的——堆和栈
2009-09-23 11:10 771容易被搞晕的——堆和 ... -
Tomcat的配置文件server.xml 中各个域的说明
2009-07-09 15:10 811Tomcat的配置文件server.xml 中各个域的说明 ... -
让CAS支持客户端自定义登陆页面——客户端篇
2009-06-19 17:08 3513客户端即指使用CAS中央认证服务器的应用程序,而不是指用户浏览 ... -
让CAS支持客户端自定义登陆页面——服务器篇
2009-06-19 16:40 2061修改需要基于几个基本原则: 不影响原有统一登陆界面功能 ... -
将页面输出进行压缩
2009-06-15 16:07 885压缩是解决数据冗余的一个好的方法,特别是在网络带宽 ... -
在spring mvc中用 jquery 出现的在IE,firefox乱码问题解决
2009-06-11 19:47 1707由于在开发中大量用GB2312出现此问题,解决方法可以有下方法 ... -
Hibernate中分页查询在SQL Server2005产生的SQL语句
2009-05-26 15:18 1635Hibernate 的分页代码 query.setFi ... -
不要重复 DAO!
2009-04-16 17:03 827http://www.ibm.com/developerwor ... -
jquery异步附件上传
2009-03-30 20:30 4233http://valums.com/wp-content/up ... -
JAVA中不错的处理日期工具单元
2009-02-10 10:54 976/**Revision Information: *@ver ... -
MyEclipse6.5注册码
2009-01-12 13:42 738Subscriber:QQ24785490 Subscrip ... -
Hibernate3.2官方中文参考手册
2009-01-09 16:37 1829如附件:
相关推荐
cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x集成cas4.1.x...
cas4.1.x 集成 mysql,ldap,redis(session和票据),写了简单的两个客户端 democas4.1.x 集成 mysql,ldap,redis(session和票据),写了简单的两个客户端 democas4.1.x 集成 mysql,ldap,redis(session和票据),写了简单...
cas4.1.x集成mysql(同时也集成了ldap,目前被注释了),集成了session放在redis共享,集成了登录票据tgt放在redis共享,同时写了两个简单demo客户端做测试
cas4.1.x集成.zip
予org.jasig.cas.client.util.CommonUtils 加入 public static void disableSSLVerification(){ try { // Create a trust manager that does not validate certificate chains TrustManager[] ...
在Win XP 32 位本机环境,利用CAS 5.1.X,对LDAP、JDBC 认证机制的多种认证模式进行了单点 登录系统(SSO)的配置试验,并采用Java 和Python 两种客户端作了测试,同时给出了配置流程、以 及个人在20 天的配置试验...
casclient.jar,cas 配置中client配置必须的jar包
springboot+cas5.x+shiro+pac4j实现sso集成,请先看我的博客,如果有问题再下载此源码学习,
里面包含了cas-server cas-calient server.xml 密钥库文件 实现了cas服务端通过数据库认证。不懂的朋友可以参考我的博客《用CAS实现SSO(单点登录)+数据库读取》
casServer.keystore
解决普元EOS报错:edu.yale.its.tp.cas.client.IContextInit 下载后需jar到lib里面且单击右键在属性一栏的弹出框内添加该jar包即可解决爆粗
cas4.1.x 集成 mysql,ldap,redis(session和票据),写了简单的两个客户端 demo.zip
单点登陆cas5.3.war放到tomcat直接使用!
cas4.x-execution-rce py版本cas4.x执行反序列化exp,支持带内回显,在4.1.x-4.1.6非硬编码情况下,支持填充oracle攻击。
CAS Service 5.2.x 已经集成mysql数据库连接REST配置,大家只需要针对配制文件进行修改放到容器里就可以使用了。
02 H3C CAS-云容器引擎配置指导 03 H3C CAS 虚拟机快照配置指导 04 H3C CAS-虚拟机防病毒配置指导 05 H3C CAS SR-IOV配置指导 06 H3C CAS vGPU热迁移配置指导 07 H3C CAS 内存管理最佳实践 08 H3C CAS 磁盘...
软件介绍: ...下载后先解压,然后将sso-client-java-7.0.8.jar文件复制到lib里面,鼠标单击右键在属性一栏的弹出框内添加该jar包即可解决解决普元EOS报错问题:edu.yale.its.tp.cas.client.IContextInit
cas6.x需要使用jdk11版本,目前cas5.3.15.1是8的最高版本,但是稳定性cas-5.3.14.war最佳,本次基于jdk8-201编译