loginServer CAS / josso / LDAP / RBAC / ACL
ddd
LDAP_百度百科
http://baike.baidu.com/view/159263.htm
LDAP 是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP, 这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。
LDAP Tools
ldap browser、Apache Directory Studio或notes ldapsearch工具
login LDAP Server LIst
IBM Directory Server
Lotus Domino Server
iPlanet Directory Server
Sun One Directory Server
Microsoft Active Direcotry
JOSSO 1.8.1 发布
http://www.iteye.com/news/10395
JOSSO 1.8.1 发布。JOSSO 是一个纯Java基于J2EE的单点登陆验证框架,主要用来提供集中式的平台无关的用户验证。新版本JOSSO 添加了Windows 和 Websphere平台原生的单点登录支持,提供开箱即用的以业务为中心的访问管理模式,减少了最后一公里集成和扩展难度,提升了用户使用体验。
其他更新包括:为Windows ASP应用程序提供基于角色的访问控制管理RBAC;WebSphere应用服务器社区版(WASCE)支持;WebLogic 8.1上的应用服务器支持;支持JBoss portal 2.7;更多g更细的实现复杂情况下单点登录的网站扩展;JDK / JRE的1.4向后兼容,以及修复bug等。
更多请访问首页:http://www.josso.org/
下载源代码:https://sourceforge.net/projects/josso/files/
来自:http://www.theserverside.com/news/thread.tss?thread_id=57887
SSO技术,SSO是什么?
http://hi.baidu.com/lincongsky/blog/item/bfd10d2f8104593d1f3089a5.html
什么是单点登陆(SSO)
http://www.shenmeshi.com/Computer/Computer_20081120143355.html
单点登陆的概念
http://thunderbow.iteye.com/blog/170965
一个yale-cas实现单点登录的简单例子实现
http://www.ieee.org.cn/dispbbs.asp?boardID=41&ID=26447
JS-SIG(CAS)学习笔记1
http://cissco.iteye.com/blog/221101
系统环境: Windows XP | SUN JDK1.6U4 | Tomcat6.0.14 | CAS Server 3.1.1 + CAS Client 2.1.1
主机完整名称: Linly
浏览器: FireFox V2.0.0.11
实验步骤:
STEP 1,搭建Java Web服务器环境
安装 JDK + Tomcat 6.0.14 , HTTP端口8080 , HTTPS端口8443
JAVA_HOME = D:\Java\jdk1.6.0_04
CATALINA_HOME = D:\Java\apache-tomcat-6.0.14
安装完毕,启动Tomcat ,在浏览器上 测试 http://Linly:8080/
![](http://linliangyi2007.iteye.com/upload/picture/pic/8412/ba32f1af-7d93-3e62-8025-c6030be36e14.gif)
出现上述界面,表明系统STEP1成功搭建。
STEP 2,使用Java Keytool工具为系统生成HTTPS证书,并为系统注册
(Java Keytool相关资料可参阅:Java keytool 安全证书学习笔记), 在DOS窗体运行以下指令(建议编写一个BAT批处理文件执行)
[quote]
cls
rem please set the env JAVA_HOME before run this bat file
rem delete alia tomcat if it is existed
keytool -delete -alias tomcatsso -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
keytool -delete -alias tomcatsso -storepass changeit
(注释: 清除系统中可能存在的名字为tomcatsso 的同名证书)
rem list all alias in the cacerts
keytool -list -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
(注释: 列出系统证书仓库中存在证书名称列表)
rem generator a key
keytool -genkey -keyalg RSA -alias tomcatsso -dname "cn=linly" -storepass changeit
(注释:指定使用RSA算法,生成别名为tomcatsso的证书,存贮口令为changeit,证书的DN为"cn=linly" ,这个DN必须同当前主机完整名称一致哦,切记!!!) rem export the key
keytool -export -alias tomcatsso -file %java_home%/jre/lib/security/tomcatsso.crt -storepass changeit
(注释: 从keystore中导出别名为tomcatsso的证书,生成文件tomcatsso.crt) rem import into trust cacerts
keytool -import -alias tomcatsso -file %java_home%/jre/lib/security/tomcatsso.crt -keystore %java_home%/jre/lib/security/cacerts -storepass changeit
(注释:将tomcatsso.crt导入jre的可信任证书仓库。注意,安装JDK是有两个jre目录,一个在jdk底下,一个是独立的jre,这里的目录必须同Tomcat使用的jre目录一致,否则后面Tomcat的HTTPS通讯就找不到证书了)
rem list all alias in the cacerts
keytool -list -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
(注释:列出jre可信任证书仓库中证书名单,验证先前的导入是否成功,如果导入成功,应该在列表中能找到tomcatsso这个别名,如下图)[/ quote]
![](http://linliangyi2007.iteye.com/upload/picture/pic/8414/638423f6-375e-3e46-aa9d-dbff289ab02b.gif)
同时,在D:\Java\jdk1.6.0_04\jre\lib\security目录下能找到“tomcatsso.crt”这个文件;在C:\Documents and Settings\Linly目录下能找到“.keystore”文件。
满足上述条件则STEP2部署完成。
STEP 3,配置Tomcat的HTTPS服务
编辑D:\Java\apache-tomcat-6.0.14\conf下的server.xml文件,在connector的配置位置添加以下的配置:
[quote]<Connector protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="C:/Documents and Settings/new/.keystore" keystorePass="changeit"
truststoreFile="D:/Java/jdk1.6.0_04/jre/lib/security/cacerts"
clientAuth="false" sslProtocol="TLS"/>[/quote]
启动Tomcat,访问https://linly:8443/,出现以下界面说明HTTPS配置生效:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8416/7aada184-731a-390e-bcb2-a5c538fdd4bf.gif)
STEP 4,为HelloWorldExample程序配置CAS过滤器
访问http://linly:8080/examples/servlets/servlet/HelloWorldExample,出现以下界面说明应用正常启动:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8418/7beec055-6090-354c-ae06-61776ab4e42c.gif)
编辑D:\Java\apache-tomcat-6.0.14\webapps\examples\WEB-INF下的web.xml文件,添加如下信息:
[quote]<filter>
<filter-name>CAS Filter</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://Linly:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://Linly:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>Linly:8080</param-value>
</init-param>
</filter>
[/quote]
[quote]
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlets/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
[/quote]
拷贝casclient.jar文件到目录D:\Java\apache-tomcat-6.0.14\webapps\examples\WEB-INF\lib下。
由于我们使用的是Tomcat6.0.14,因此,还要拷贝commons-logging-1.0.4.jar到该目录下。
STEP 5,部署JA-SIG(CAS)服务器
拷贝cas.war到D:\Java\apache-tomcat-6.0.14\webapps目录下。启动Tomcat,访问网址http://linly:8080/cas/index.jsp,出现以下画面:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8420/19fcb758-d705-3445-b6d4-9e883dc2f0e5.gif)
输入用户名/密码 :linly/linly(任意两个相同的字窜),点击“登录”,出现以下画面:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8422/2dbb6405-2cd2-3bb6-92bf-2a13404fab37.gif)
表示CAS服务器配置运行成功。
STEP 6,测试JA-SIG(CAS)部署结果
启动Tomcat。
测试使用浏览器登陆以下网址:http://linly:8080/examples/servlets/servlet/HelloWorldExample,页面将弹出以下认证框,点击“确定”
![](http://linliangyi2007.iteye.com/upload/picture/pic/8424/c93c4ce6-b32f-3581-8a24-d26e62bdb8cd.gif)
页面将重定向到JA-SIG的SSO登录认证页面
![](http://linliangyi2007.iteye.com/upload/picture/pic/8426/dfcedb9b-e2e7-308a-8a77-f36b5f4da310.gif)
输入用户名=密码,如:linly/linly,则通过验证,进入应用的入口界面,如下:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8428/819ae74c-e01c-3057-834f-7f1fac2649b5.gif)
细心的用户将发现,此时的URL不再是:
http://linly:8080/examples/servlets/servlet/HelloWorldExample,
URL的尾端带上了一个ticket参数:
http://linly:8080/examples/servlets/servlet/HelloWorldExample?ticket=ST-2-qTcfDrdFb0bWndWgaqZD
到此,JA-SIG(CAS)服务器的初步SSO部署宣告成功。
JS-SIG(CAS)学习笔记2
http://cissco.iteye.com/blog/221102
什么是SSO(Single Sign On)单点登录:
所谓单点登录是指基于用户/会话认证的一个过程,用户只需一次性提供凭证(仅一次登录),就可以访问多个应用。
目前单点登录主要基于Web的多种应用程序,即通过浏览器实现对多个B/S架构应用的统一账户认证。
JA-SIG(CAS)的设计愿景:
简 单的说,CAS(Central Authentication Service – 中心认证服务)的目的就是使分布在一个企业内部各个不同异构系统的认证工作集中在一起,通过一个公用的认证系统统一管理和验证用户的身份。在CAS上认证 的用户将获得CAS颁发的一个证书,使用这个证书,用户可以在承认CAS证书的各个系统上自由穿梭访问,不需要再次的登录认证。打个比方:对于加入欧盟的 国家而言,在他们国家中的公民可以凭借着自己的身份证,在整个欧洲旅行,不用签证。对于企业内部系统而言,CAS就是这个颁发欧盟认证的系统,其它系统都 是加入欧盟的国家,它们要共同遵守和承认CAS的认证规则。
因此CAS的设计愿景就是:
1。实现一个易用的、能跨不同Web应用的单点登录认证中心;
2。实现统一的用户身份和密钥管理,减少多套密码系统造成的管理成本和安全漏洞;
3。降低认证模块在IT系统设计中的耦合度,提供更好的SOA设计和更弹性的安全策略
CAS1.0服务架构实现:
传统的用户认证流程
我们以A公司的员工日志管理系统为例,如下图:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8430/a4e2c08e-2186-3134-b524-5dcfc7c0acba.gif)
使用CAS后的用户认证流程
![](http://linliangyi2007.iteye.com/upload/picture/pic/8432/f9331683-d112-3152-b5b0-7af63754b05c.gif)
示 意图中,CAS相关部分被标示为蓝色。在这个流程中,员工AT向日志系统请求进入主页面,他的浏览器发出的HTTP请求被嵌入在日志系统中的CAS客户端 (HTTP过滤器)拦截,并判断该请求是否带有CAS的证书;如果没有,员工AT将被定位到CAS的统一用户登录界面进行登录认证,成功后,CAS将自动 引导AT返回日志系统的主页面。
CAS的程序逻辑实现
要完成上述的认证业务,CAS需要一个认证中心服务器CAS -Server和嵌入在不同业务系统方的认证客户端CAS-Client的协同。
在CAS1.0协议中,CAS-Server提供的三个验证服务接口(web服务URL):
1. 用户登录URL,形如 https://casserver/cas/servlet/login
2. 用户凭证校验URL,形如 https://casserver/cas/servlet/validate
3. 用户登出URL,形如 https://casserver/cas/servlet/logout
在CAS-Client端,CAS提供了多样化的语言支持,其中用于java的是一个casclient.jar包。目前的版本为2.1.1,其中提供了三种形式的凭证校验:
1. 用于Java Servlets的Filter — edu.yale.its.tp.cas.client.filter.CASFilter
2. 用于JSP页面的CAS Tag Library
3. 通用Java API Object — ServiceTicketValidator / ProxyTicketValidator
通 常,企业应用程序基于浏览器的B/S模式,这种情况下,系统的用户凭证(一个由CAS服务器生成的唯一 id号,也称之为ticket)借助cookie和URL参数方式实现;在B/S环境中,大多情况下,我们只需要配置CAS Filter或者使用CAS Tag Library就可以轻松实现的验证客户端。
如果应用是以普通的C/S模式运行,则需要应用程序自己来 维护这个ticket在上下文环境中的传输和保存了。这时候就需要手工调用ServiceTicketValidator / ProxyTicketValidator对象的方法,向CAS 服务器提交认证,并获取认证结果进行相应的处理。
CAS服务的具体实现
环境假设:用户User要访问业务系统Biz;Biz系统部署在bizserver上;CAS的系统搭建在服务器casserver上。
![点击查看原始大小图片](http://linliangyi2007.iteye.com/upload/picture/pic/8434/b67ef0b8-def6-36fb-93a5-817c761b39f2.gif)
图例说明:
Step1: 用户第一次访问Biz系统主页http://bizserver/index.jsp ;部署在Biz系统上的CASFilter发现用户尚未登录,将用户重定向的CAS登录界面 https://casserver/cas/servlet/login?service=http://bizserver/index.jsp ,同时在重定向的URL上用service参数将用户的目标地址传给CAS服务器。
Step2:用户在CAS的登录页上输入用户名密码登录,CAS服务器认证通过后,生成一个ticket,并带在目标地址的尾部返回客户端的浏览器redirect:http://bizserver/index.jsp?ticket=casticket.
Step3:客户端浏览器获得CAS服务器的认证应答,取得凭证ticket后,使用重定向的链接http://bizserver/index.jsp?ticket=casticket访问Biz服务
Step4: BizServer上的CASFilter再次过滤访问请求,并获得ticket凭证。Filter将使用该凭证通过URL https://casserver/cas/servlet/validate?service= http://bizserver/index.jsp &ticket=casticket 向CAS认证中心确认对应的服务请求和凭证是否有效。根据CAS服务器返回的结果,如果凭证有效,则CASFilter允许用户进入 http://bizserver/index.jsp 所指向的页面;否则,再次重定向到https://casserver/cas/servlet/login?service=http: //bizserver/index.jsp 上要求用户进行认证。
CAS2.0服务架构实现:
CAS2.0的协议主要是针对web应用的SSO功能增强的协议,它在1.0协议基础上扩展了Proxy Authentication(代理认证)能力。那么什么是Proxy Authentication呢?!
代理认证Proxy Authentication
假 设有一下这样的应用场景:用户AT早晨来到公司,他的第一件事就是进入公司的Portal系统浏览一天的新咨询,如股票信息、天气情况、业界新闻。他通过 CAS的身份认证登录了门户系统,看到了他订制的信息。之后,他要访问portal中的邮件信息,看看有没有新的邮件。这时候Portal系统必须访问他 的IMAP服务器,这需要他的私人密码。我们知道Portal是通过CAS对AT进行认证的,因此Portal上没有AT的个人密码信息。这时,我们发 现,Portal需要代表AT的身份向IMAP服务器提交身份认证,而这正是Proxy Authentication的作用。
CAS2.0系统架构中的角色
![](http://linliangyi2007.iteye.com/upload/picture/pic/8436/8981a0de-5d35-3e9c-8e7e-3c48a4cb1189.gif)
CAS2.0系统中的用到的凭证(ticket)
![](http://linliangyi2007.iteye.com/upload/picture/pic/8438/bdd8ec3e-766b-3a0f-bc3f-86113aad7e28.gif)
以上对于CAS2.0协议中用到的5种ticket的说明,乍看起来也许会让你云里雾里的。没关系,下面我们就来详细阐述这5种凭证在实际认证流程中的作用。在阐述具体流程前,我们要先关注一下2.0协议中对客户端配置的需求.
CAS2.0的客户端配置
在 2.0协议中,CAS-Server端的配置与1.0基本一致。但在客户端上,多增加了一个call back URL,该URL用来提供server端向client端传输PGT时使用。因此,除了要配置 edu.yale.its.tp.cas.client.filter.CASFilter作为认证过滤器外,还要配置 edu.yale.its.tp.cas.proxy.ProxyTicketReceptor这个servlet,作为server回传PGT的 call back URL,如下:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8440/e0bb9188-5f6a-3659-810e-52ea0aa0c897.gif)
CAS2.0代理认证流程
以 下的流程图模拟上述的用户AT通过Portal向他的IMAP邮件服务器请求电子邮件的认证过程。在该过程中,充当Service和Proxy两个角色的 Portal使用CAS Filter对访问其自身的用户进行CAS认证;同时Portal要使用ProxyTicketReceptor servlet接收来自CAS server的PGT信息,并使用ProxyTicketValidator对象向CAS获取访问IMAP服务器的Proxy Ticket凭证;最终从IMAP服务器上获取AT用户的mail信息。同样的,这里的IMAP服务器也要接受并认可CAS对其用户的认证管理,同时它自 己也成为二级Proxy,在有需要的情况下,一样可以向它的back-end Service发起Proxy Authentication代理认证请求……
![](http://linliangyi2007.iteye.com/upload/picture/pic/8442/96fec43d-c28e-339d-951b-2cd26160200d.gif)
其中蓝色线表示HTTP或HTTPS的请求;红色线表示应答;黑色线表示来自CAS server端的回调操作。
到此,本章节对JA-SIG(CAS)的整体功能和身份认证业务架构进行初步的讲解,在后续的章节中,我们将对CAS平台的服务端和客户端的编程与应用定制等相关内容的进行介绍。
JS-SIG(CAS)学习笔记3
http://cissco.iteye.com/blog/221104
JA-SIG CAS服务环境搭建,请参考 : JA-SIG(CAS)学习笔记1
JA-SIG CAS业务架构介绍,请参考 : JA-SIG(CAS)学习笔记2
HTTPS所涉及的Java安全证书知识,请参考 : Java keytool 安全证书学习笔记
CAS技术框架
CAS Server
目 前,我们使用的CAS Server 3.1.1的是基于Spring Framework编写的,因此在CAS服务器端的配置管理中,绝大多数是Spring式的Java Bean XML配置。CAS 的服务器提供了一套易于定制的用户认证器接口,用户可以根据自身企业的在线系统的认证方式,来定制自己的认证逻辑。不论是传统的用户名/密码方式,还是基 于安全证书的方式;是基于关系数据库的存储,还是采用LDAP服务器,CAS Server给我们提供了这些常用的验证器模板代码,只要稍作修改,便可灵活使用了。
对于广大的中国企业用户而言,另一个需要定制的功能莫过 于全中文、企业特色的用户身份认证页面了。CAS Server提供了两套系统界面,一套是默认的CAS英文标准页面,另一套则是专门提供给用户来定制修改的。(PS:老外们做事情就是人性化啊~~)那么 对CAS Server端的后续学习,我们将围绕着身份认证模块定制和界面定制这两方面展开。
CAS Client
客 户端我们使用的是CAS Client 2.1.1。虽然在官方网站上已出现了3.1.0版本的下载,但该版本地代码已经完全重写,使用的package和类名同2.1.1大相径庭了,最关键的 是,该版本暂时没有对应的API说明文档。虽然咖啡我对程序版本怀有极大的“喜新厌旧”的心态,但安全起见,还是先2.1.1吧,相信3.1.0的文档耶 鲁大学的大牛们已经在整理了,期待中……
CAS Client2.1.1.jar中的代码是相当精炼的,有兴趣的朋友建议阅读一下源码。Jar包中的代码分成三个大部分
1. edu.yale.its.tp.cas.util 包,其中只有一个工具类 SecureURL.java 用来访问HTTPS URL
2. edu.yale.its.tp.cas.proxy包,用来处理Proxy Authentication代理认证的3个类,其中ProxyTicketReceptor.java是 接收PGT回调的servlet,在下文中我们会提及。
3. edu.yale.its.tp.cas.client包,其中包含了CAS Filter ,Tag Library等主要的认证客户端工具类,我们在后面会进行重点介绍。
针对CAS Client的学习,我们的重点将放在CAS Filter 和ProxyTicketReceptor 的配置以及在Java SE环境下,直接使用 ServiceTicketValidator进行Ticket认证实现上。
CAS服务器端应用
定制适合你的身份认证程序
通过前面的学习,我们了解了CAS具有一个良好而强大的SSO功能框架。接下来,我们要学习如何将实际企业应用中的身份认证同CAS进行整合。
简单的说,要将现有企业应用中的认证集成到CAS Server中,只要实现一个名为AuthenticationHandler的一个认证处理Java接口就行。以下是该接口的源代码:
- public interface AuthenticationHandler {
- /**
- * 该方法决定一个受支持的credentials是否是可用的,
- * 如果可用,该方法返回true,则说明身份认证通过
- */
- boolean authenticate(Credentials credentials) throws AuthenticationException;
- /**
- * 该方法决定一个credentials是否是当前的handle所支持的
- */
- boolean supports(Credentials credentials);
- }
- public interface AuthenticationHandler {
- /**
- * 该方法决定一个受支持的credentials是否是可用的,
- * 如果可用,该方法返回true,则说明身份认证通过
- */
- boolean authenticate(Credentials credentials) throws AuthenticationException;
- /**
- * 该方法决定一个credentials是否是当前的handle所支持的
- */
- boolean supports(Credentials credentials);
- }
public interface AuthenticationHandler {
/**
* 该方法决定一个受支持的credentials是否是可用的,
* 如果可用,该方法返回true,则说明身份认证通过
*/
boolean authenticate(Credentials credentials) throws AuthenticationException;
/**
* 该方法决定一个credentials是否是当前的handle所支持的
*/
boolean supports(Credentials credentials);
}
这里我们要说明一下Credentials这个CAS的概念。所谓Credentials是由外界提供给CAS来证明自身身份的信息,简单的如一 个用户名/密码对就是一个Credentials,或者一个经过某种加密算法生成的密文证书也可以是一个Credentials。在程序的实现 上,Credentials被声明为一个可序列化的接口,仅仅起着标识作用,源代码如下:
- public interface Credentials extends Serializable {
- // marker interface contains no methods
- }
- public interface Credentials extends Serializable {
- // marker interface contains no methods
- }
public interface Credentials extends Serializable {
// marker interface contains no methods
}
CAS的API中,已经为我们提供了一个最常用的实现UsernamePasswordCredentials 用户名/密码凭证,代码如下:
- public class UsernamePasswordCredentials implements Credentials {
- /** Unique ID for serialization. */
- private static final long serialVersionUID = -8343864967200862794L;
- /** The username. */
- private String username;
- /** The password. */
- private String password;
- public final String getPassword() {
- return this .password;
- }
- public final void setPassword( final String password) {
- this .password = password;
- }
- public final String getUsername() {
- return this .username;
- }
- public final void setUsername( final String userName) {
- this .username = userName;
- }
- public String toString() {
- return this .username;
- }
- public boolean equals( final Object obj) {
- if (obj == null || !obj.getClass().equals( this .getClass())) {
- return false ;
- }
- final UsernamePasswordCredentials c = (UsernamePasswordCredentials) obj;
- return this .username.equals(c.getUsername())
- && this .password.equals(c.getPassword());
- }
- public int hashCode() {
- return this .username.hashCode() ^ this .password.hashCode();
- }
- }
- public class UsernamePasswordCredentials implements Credentials {
- /** Unique ID for serialization. */
- private static final long serialVersionUID = -8343864967200862794L;
- /** The username. */
- private String username;
- /** The password. */
- private String password;
- public final String getPassword() {
- return this .password;
- }
- public final void setPassword( final String password) {
- this .password = password;
- }
- public final String getUsername() {
- return this .username;
- }
- public final void setUsername( final String userName) {
- this .username = userName;
- }
- public String toString() {
- return this .username;
- }
- public boolean equals( final Object obj) {
- if (obj == null || !obj.getClass().equals( this .getClass())) {
- return false ;
- }
- final UsernamePasswordCredentials c = (UsernamePasswordCredentials) obj;
- return this .username.equals(c.getUsername())
- && this .password.equals(c.getPassword());
- }
- public int hashCode() {
- return this .username.hashCode() ^ this .password.hashCode();
- }
- }
public class UsernamePasswordCredentials implements Credentials {
/** Unique ID for serialization. */
private static final long serialVersionUID = -8343864967200862794L;
/** The username. */
private String username;
/** The password. */
private String password;
public final String getPassword() {
return this.password;
}
public final void setPassword(final String password) {
this.password = password;
}
public final String getUsername() {
return this.username;
}
public final void setUsername(final String userName) {
this.username = userName;
}
public String toString() {
return this.username;
}
public boolean equals(final Object obj) {
if (obj == null || !obj.getClass().equals(this.getClass())) {
return false;
}
final UsernamePasswordCredentials c = (UsernamePasswordCredentials) obj;
return this.username.equals(c.getUsername())
&& this.password.equals(c.getPassword());
}
public int hashCode() {
return this.username.hashCode() ^ this.password.hashCode();
}
}
很简单不是吗?就是存储一个用户名和密码的java bean而已。
接下来,我们将一个Credentials传给一个 AuthenticationHandler进行认证,首先调用boolean supports(Credentials credentials)方法察看当前传入的Credentials实例,AuthenticationHandler实例现是否支持它?如果支持,再调 用boolean authenticate(Credentials credentials)方法进行认证。由于用户名/密码方式是最常用的认证方法,因此CAS为我们提供了一个现成的基于该方式的抽象认证处理类 AbstractUsernamePasswordAuthenticationHandler。通常我们只需要继承该类,并实现其中的 authenticateUsernamePasswordInternal方法即可。下面我们给出一个Demo的实现类,它的校验逻辑很简单——仅校验 用户名的字符长度是否与密码的相等(这里密码是一个表示长度的整数),如果相等则认为认证通过,请看代码:
- public class UsernameLengthAuthnHandler
- extends AbstractUsernamePasswordAuthenticationHandler {
- protected boolean authenticateUsernamePasswordInternal( UsernamePasswordCredentials credentials) throws AuthenticationException {
- /*
- * 这里我们完全可以用自己的认证逻辑代替,比如将用户名/密码传入一个SQL语句
- * 向数据库验证是否有对应的用户账号,这不是我们最经常干的事么?
- * 只需要将下面的程序替换掉就OK了!!So easy,so simple!
- /
- String username = credentials.getUsername();
- String password = credentials.getPassword();
- String correctPassword = Integer.toString(username.length());
- return correctPassword.equals(password);
- }
- }
- public class UsernameLengthAuthnHandler
- extends AbstractUsernamePasswordAuthenticationHandler {
- protected boolean authenticateUsernamePasswordInternal( UsernamePasswordCredentials credentials) throws AuthenticationException {
- /*
- * 这里我们完全可以用自己的认证逻辑代替,比如将用户名/密码传入一个SQL语句
- * 向数据库验证是否有对应的用户账号,这不是我们最经常干的事么?
- * 只需要将下面的程序替换掉就OK了!!So easy,so simple!
- /
- String username = credentials.getUsername();
- String password = credentials.getPassword();
- String correctPassword = Integer.toString(username.length());
- return correctPassword.equals(password);
- }
- }
public class UsernameLengthAuthnHandler
extends AbstractUsernamePasswordAuthenticationHandler {
protected boolean authenticateUsernamePasswordInternal( UsernamePasswordCredentials credentials) throws AuthenticationException {
/*
* 这里我们完全可以用自己的认证逻辑代替,比如将用户名/密码传入一个SQL语句
* 向数据库验证是否有对应的用户账号,这不是我们最经常干的事么?
* 只需要将下面的程序替换掉就OK了!!So easy,so simple!
/
String username = credentials.getUsername();
String password = credentials.getPassword();
String correctPassword = Integer.toString(username.length());
return correctPassword.equals(password);
}
}
介绍到这里,大家应该清楚如何定制自己的AuthenticationHandler类了吧!这里要附带说明的是,在CAS Server的扩展API中已经提供了大量常用认证形式的实现类,它们同CAS Server的war包一同分发:
cas-server-support-generic-3.1.1.jar ——使用Map记录用户认证信息的实现
cas-server-support-jdbc-3.1.1.jar —— 基于Spring JDBC的数据库实现(我们常用的)
cas-server-support-ldap-3.1.1.jar —— 基于LDAP的用户认证实现
更多其他形式的实现各位看官有兴趣的,可以一一阅读源码。
配置你的身份认证程序
完成了定制认证类的代码编写,接下来就是要让CAS Server来调用它了。在CAS的框架中,对程序的配置都是使用Spring Framework的xml文件,这对于熟悉Spring的程序员而言算驾轻就熟了。
配 置文件位于应用部署目录的WEB-INF子目录下——deployerConfigContext.xml。在bean id=authenticationManager 的 authenticationHandlers属性中配置我们的AuthenticationHandlers:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
。。。
。。。
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />
<!—下面就是系统默认的验证器配置,你可以替换它,或者增加一个新的handler -->
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
</list>
</property>
</bean>
。。。
。。。
</beans>
我们发现authenticationHandlers属性是一个list,在这个list中可以配置多个 AuthenticationHandlers。这些AuthenticationHandlers形成了一个验证器链,所有提交给CAS的 Credentials信息将通过这个验证器链的链式过滤,只要这链中有一个验证器通过了对Credentials的验证,就认为这个 Credentials是合法的。这样的设计使得我们可以很轻松的整合不同验证体系的已有应用到同一个CAS上,比如:A验证器负责校验alpha系统提 交的Credentials,它是基于LDAP服务器的;B验证器负责校验beta系统提交的Credentials,它是一个传统的RDB用户表认 证;C验证器负责校验gamma系统提交的基于RSA证书加密的Credentials。3种完全不同的用户身份认证通过配置就可以统一在同一个CAS服 务内,很好很强大,不是吗!!
定制身份验证登录界面
CAS Server在显示界面层view使用了“主题Theme”的概念。在{project.home}/webapp/WEB-INF/view/jsp /目录下,系统默认提供了两套得UI —— default和simple 。default方案使用了CSS等相对复杂得界面元素,而simple方案提供了最简化的界面表示方式。在整个的CAS Server服务器端,有四个界面是我们必须要实现的:
casConfirmView.jsp —— 确认信息(警告信息)页面
casGenericSuccess.jsp —— 登陆成功提示页面
casLoginView.jsp —— 登录输入页面
casLogoutView.jsp —— SSO登出提示页面
这些都是标准的jsp页面,如何实现他们,完全由您说了算,除了名字不能改。
CAS为view的展示提供了3个级别的定制方式,让我们从最直观简单的开始吧。
1. 采用文件覆盖方式:直接修改default中的页面或者将新写好的四个jsp文件覆盖到default目录中。这种方式最直观和简单,但咖啡建议各位在使用这种方式前将原有目录中的文件备份一下,以备不时之需。
2. 修改UI配置文件,定位UI目录:在CAS Server端/webapp/WEB-INF/classes/ 目录下,有一个名为default_views.properties的属性配置文件,你可以通过修改配置文件中的各个页面文件位置,指向你新UI文件, 来达到修改页面展示的目的。
3. 修改配置文件的配置文件,这话看起来有点别扭,其实一点不难理解。在方法2中的default_views.properties文件是一整套的UI页面 配置。如果我想保存多套的UI页面配置就可以写多个的properties文件来保存这些配置。在CAS Server端/webapp/WEB-INF/目录下有cas-servlet.xml和cas.properties两个文件,cas- servlet.xml使用了cas.properties文件中的cas.viewResolver.basename属性来定义view属性文件的名 字,因此你可以选者直接修改cas-servlet.xml中的viewResolver 下的basenames属性,或者修改cas.properties中的cas.viewResolver.basename属性,指定新的 properties文件名,这样可以轻松的替换全套UI。
CAS客户端配置及API应用
CASFilter的配置
对 于大部分web应用而言,使用CAS集成统一认证是相对简单的事,只要为需要认证的URL配置 edu.yale.its.tp.cas.client.filter.CASFilter认证过滤器。下面我们就针对过滤器的配置进行说明。首先参看一 下Filter的基本配置:
...
<filter>
<filter-name>CAS Filter</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://secure.its.yale.edu/cas/login<;/param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://secure.its.yale.edu/cas/serviceValidate<;/param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>your server name and port (e.g., www.yale.edu:8080)</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/requires-cas-authetication/*</url-pattern>
</filter-mapping>
...
</web-app>
上述配置中的init-param是filter的3个必备的属性,下面这张表则是filter全部属性的详细说明:
![](http://linliangyi2007.iteye.com/upload/picture/pic/8444/fdb2f2cb-9707-3228-8235-7e6658c0016e.gif)
ProxyTicketReceptor的配置
大家还记得在前面我们说过的Proxy Authentication中的call back URL吗?ProxyTicketReceptor是部署在client端的一个servlet,提供server端回传PGT和PGTIOU的。它的xml部署如下:
<web-app>
...
<servlet>
<servlet-name>ProxyTicketReceptor</servlet-name>
<servlet-class>edu.yale.its.tp.cas.proxy.ProxyTicketReceptor</servlet-class>
<init-param>
<param-name>edu.yale.its.tp.cas.proxyUrl</param-name>
<param-value>https://secure.its.yale.edu/cas/proxy<;/param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ProxyTicketReceptor</servlet-name>
<url-pattern>/CasProxyServlet</url-pattern>
</servlet-mapping>
...
</webapp>
这里要说明的是它的参数edu.yale.its.tp.cas.proxyUrl。在服务端通过 ProxyTicketReceptor将PGT和PGTIOU传给客户端后,ProxyTicketReceptor在进行Proxy Authentication的过程中需要向服务端请求一个ProxyTicket(PT),这个proxyUrl就是服务端的请求入口了。(关于 Proxy Authentication的运作原理,参见 JA-SIG(CAS)学习笔记2 )
CAS Client端的API应用 1.用户可以通过以下两种方式的任意一种,从JSP或servlet中获取通过认证的用户名:
或者
String username = (String)session.getAttribute("edu.yale.its.tp.cas.client.filter.user");
2.获得更完整的受认证用户信息对象CASReceipt Java Bean,可以使用以下语句的任一:
或者
CASReceipt receipt = (CASReceipt )session.getAttribute("edu.yale.its.tp.cas.client.filter.receipt");
3.手工编码使用CAS Java Object进行用户验证,使用ServiceTicketValidator或者 ProxyTicketValidator(代理认证模式下),在servlet中对用户身份进行验证。
3-1.ServiceTicketValidator
- import edu.yale.its.tp.cas.client.*;
- ...
- String user = null ;
- String errorCode = null ;
- String errorMessage = null ;
- String xmlResponse = null ;
12款Java 目录服务LDAP开源软件
http://www.oschina.net/project/tag/180/ldap?sort=view&lang=19&os=37
-
LDAP目录服务器 OpenDJ
OpenDJ(Open source Directory services for the Java platform) 是一个全新的 LDAPv3 兼容的目录服务,为企业提供了一个高性能,高可靠性的身份管理。它容易安装,加上Java平台优势,使得 OpenDJ 成为最简单和快速的目录服务器。 选择 OpenDJ 作为企... 更多OpenDJ信息
最近更新: LDAP目录服务器 OpenDJ 2.4 发布 发布于 2年前
-
Spring LDAP
Spring LDAP 是一个用于操作 LDAP 的 Java 框架。它是基于 Spring 的 JdbcTemplate 模式。这个框架能够帮助开发人员简化 looking up,closing contexts,looping through NamingEnumerations,encoding/decoding values与 filters 等操作。... 更多Spring LDAP信息
最近更新: Spring LDAP 1.3.1 发布 发布于 2年前
-
LDAP目录服务器 ApacheDS
ApacheDS (Apache Directory Server)的核心是目录服务,可以保存数据,并对不同类型的数据进行搜索操作。协议的实现在目录服务器顶层工作,提供与数据存储、搜索和检索有关的 Internet 服务。 ApacheDS 最重要的特性可能是利用不同协议公开目录服务的能力.... 更多ApacheDS信息
最近更新: ApacheDS 2.0.0-M11 发布,目录服务软件 发布于 1个月前
-
Apache Directory Studio
Apache Directory Studio 是一个 LDAP 的工具平台,用来连接到任何 LDAP 服务器并进行管理和开发工作。 主要功能:LDAP浏览器、LDIF编辑器、嵌入式 ApacheDS、ACI编辑器。
更多Apache Directory Studio信息
最近更新: Apache Directory Studio 2.0.0-M6 发布 发布于 1个月前
-
开源LDAP浏览器 JXplorer
JXplorer是一款采用Java开发的开源LDAP浏览器。
更多JXplorer信息
-
Apache LDAP API
这是 Apache 组织的一个 LDAP 客户端 API 项目,基于 MINA 网络框架开发。 更多Apache LDAP API信息
最近更新: Apache LDAP API 1.0 M6 发布 发布于 1年前
-
LDAP工具平台 LDAP Studio
LDAP Studio是一个基于Eclipse RCP开发LDAP工具平台。由几个Eclipse(OSGi)插件包括:LDAP Browser Plugin和Schemas Editor Plugin组成,所以LDAP Studio易于通过插件进行扩展。LDAP Studio适用于任何LDAP服务器,但它是专门设计用于Apache Directory Serv...
更多LDAP Studio信息
-
目录管理系统 GANYMEDE
GANYMEDE 是一种便携式,可定制的网络目录管理系统,发布GNU通用公共许可证。它是免费软件。GANYMEDE是用Java编写的,GANYMEDE的客户可以运 行在任何系统的 JDK 5或更高。GANYMEDE服务器的目的是运行在UNIX类型的系统,但可以运行在几乎所有的Java支持的操作...
更多GANYMEDE信息
-
UnboundID LDAP SDK for Java
UnboundID LDAP SDK for Java 是一个快速、综合易用的 LDAP 目录服务的 Java 客户端 API,可读写 LDIF、使用BASE64 和 ASN.1 BER 进行编码解码,支持安全通信等特性,要求 Java 1.5 或者更新版本支持,同时也支持 Android 平台。... 更多UnboundID LDAP SDK for Java信息
-
JNDI Warrior
JNDI Warrior 是一个使用 Swing 界面开发的客户端程序,用来浏览 JNDI 目录。基于 Groovy+Griffon 框架编写。
更多JNDI Warrior信息
-
LDAP目录密码自助服务 PWM
PWM是一个LDAP目录密码自助服务的开源软件。 PWM是有些组织希望“角色自己”密码自助的服务解决方案,是一个理想的候方案,但不希望从头开始。 更多PWM信息
-
LDAP目录管理器 LinID
LinID 提供了简单的环境用于开发即用的 Web 接口,基于 LDAPv3 协议,提供 CRUD、自编辑、委派等。
更多LinID信息
passport
主站生产 :passport 4台was 4台jboss ,jboss优于was ,MYSQL
XX宝生产:passport 4台was 4台jboss,was小流量(有防火墙),mysql
OA 生产:passport ,2台WAS,mysql
end