Jasig cas 单点登录系统Server&Java Client配置

原文地址:http://blog.csdn.net/puma_dong/article/details/11564309

目录(?)[+]

Jasig cas(Central Authentication Service)官方站点:http://www.jasig.org/cas,访问这个站点需要翻墙。

cas官网文档访问地址:https://wiki.jasig.org/display/CASUM/Home。

我下载的是:3.5.2版本。我配置好的cas界面如下:

界面一:


界面二:



下载链接:


已经搞好的Java客户端及服务器端(MySQL)配置下载:http://pan.baidu.com/s/11MRPr ,两个war包,1个jar包:

cas.war,是配置好的cas服务器端:http://192.168.1.10:8080/casclient 。

casclient.war,是cas客户端示例,所谓cas客户端,就是指使用cas进行单点登录的系统:  http://192.168.1.10:8080/cas/login。

cas-client-core-3.2.1-SNAPSHOT.jar:是我在版本3.2.1源码基础上进行修改过的,目的是登录成功后,自动跳转到前一页。

要修改cas.war包中deployerConfigContext.xml里面的数据库连接串及密码查询SQL,jasig日志文件的位置:tomcat所在磁盘:/data/applogs/jasig/目录下,可以通过修改WEB-INFO/class/log4j.xml进行配置。

需要的MySQL数据库privilege建表及数据初始化脚本:create_privilege.sql

使用这个数据库,默认的登录帐户密码:root/root


最新代码Git地址:

cas -server-3.5.2:https://github.com/pumadong/cas-server-3.5.2

cas-client-3.2.1:https://github.com/pumadong/cas-client-3.2.1


Jasig cas服务器端配置:


Jasig cas的功能是认证(单点登录,SSO,Single Sign On),关于系统的授权,由于各个系统可能都不太一样,各个系统自行负责为宜。

Jasig cas的配置非常简单,从官网下载的源码包中,有个module目录,里面有制作好的war包,可以直接使用,当然也可以自行使用maven打包,命令如下:

mvn clean package -Dmaven.test.skip=true -U

把war包改名为cas.war,放到tomcat的webapps目录下,就可以使用了,默认使用的是登陆验证类是测试用的,只要用户名、密码一直就算登陆成功,为了在生产环境使用,我们改为使用MySql数据库验证,步骤如下:


1、简单起见,我们不使用https认证,做如下更改:

WEB-INF\spring-configuration目录下ticketGrantingTicketCookieGenerator.xml和warnCookieGenerator.xml,把p:cookieSecure="true"改为p:cookieSecure="false"

WEB-INF目录下deployerConfigContext.xml中,在如下节点中,增加p:requireSecure="false",

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false" />


2、使用MySql验证

WEB-INF\deployerConfigContext.xml文件中,
对<property name="authenticationHandlers">节点,做如下更改:
<property name="authenticationHandlers">
    <list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
   p:httpClient-ref="httpClient" p:requireSecure="false" />
<bean  class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
   <property name="dataSource" ref="dataSource" />
   <property name="sql" value="select password from p_user where username=?" />
   <property name="passwordEncoder" ref="passwordEncoderBean"/>
</bean>  
    </list>
</property>
根节点,也就是beans节点中,增加如下节点:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>com.mysql.jdbc.Driver</value>
    </property>
    <property name="url">
        <value>jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8</value>
    </property>
    <property name="username"><value>root</value></property>
    <property name="password"><value>root</value></property>
</bean>
<bean id="passwordEncoderBean" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
    <constructor-arg value="MD5" />
</bean>

注意:

同时,需要把cas-server-support-jdbc-3.5.2.jar包放在cas.wab包的WEB-INF目录下,把mysql-connector-java-5.1.24-bin.jar放入Tomcat的WEB-INF/lib目录里。


3、退出时跳转到service页

修改src\main\webapp\WEB-INF\cas-servlet.xml里的logoutController
增加p:followServiceRedirects="true"使支持logout输入service参数为跳转路径。


4、增加免登陆(Remember Me)功能

CAS增加免登陆(Remember Me)功能:

https://wiki.jasig.org/display/CASUM/Remember+Me

http://blog.163.com/wunan_23/blog/static/19556232020111127714418/


Jasig cas客户端配置


1、pom.xml配置

<!-- CAS Client -->
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.1.10</version>
</dependency> 

如果不使用maven的话,直接下载jar包即可。


2、web.xml配置

<!-- ======================== 单点登录开始 ======================== -->
<!-- 说明:这种客户端的配置方式是不需要Spring支持的 -->
<!-- 参考资料:http://blog.csdn.net/yaoweijq/article/details/6003187 -->
<listener>  
      <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>   
</listener>  
<filter>  
<filter-name>CAS Single Sign Out Filter</filter-name>   
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>   
</filter>  
<filter-mapping>  
   <filter-name>CAS Single Sign Out Filter</filter-name>   
   <url-pattern>/*</url-pattern>   
</filter-mapping>  
<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://localhost:8080/cas/login</param-value>   
   </init-param>  
   <init-param>  
       <param-name>serverName</param-name>   
       <param-value>http://localhost:8080</param-value>   
   </init-param>
</filter> 
<filter-mapping>  
   <filter-name>CAS Authentication Filter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>  
<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://localhost:8080/cas</param-value>   
   </init-param>  
   <init-param>  
       <param-name>serverName</param-name>   
       <param-value>http://localhost:8080</param-value>   
   </init-param>
</filter>  
<filter-mapping>  
   <filter-name>CAS Validation Filter</filter-name>   
   <url-pattern>/*</url-pattern>   
</filter-mapping>
<!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 -->
  <filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>CAS Assertion Thread Local Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ======================== 单点登录结束 ======================== -->


3、单点退出

单点退出的原理,可以总结为一句话:

A客户端退出,调用cas服务器的logout,cas server会向所有相关的接入CAS的系统发送消息,这些接入CAS的系统监听到消息后,触发session失效。

注意:我们的接入CAS的系统必须是cas服务器可以访问到的,如果我们使用:http://localhost:8080/picture的形式访问站点,则是无法实现单点登出的,因为cas服务器访问不到我们的localhost,必须改成:http://ip地址:8080/picture的形式,让CAS可以访问到我们的系统。

参考:

http://www.blogjava.net/xmatthew/archive/2008/07/09/213808.html

http://blog.csdn.net/yuwenruli/article/details/6607669


更改单点登录界面


WEB-INF\view\jsp\default\ui

登陆界面:casLoginView.jsp

登陆成功:casGenericSuccess.jsp

登出界面:casLogoutView.jsp

cas是支持国际化的,关于页面中显示的提示信息的存储位置class/*.properties,默认是en,为了让比较简单的中文化,我把en做了个备份,然后把zh_CN拷贝成en。

在properties文件中, 对于非英文的字符,采用16进制存储,关于unicode字符和16进制字符的转换,提供如下两个函数:

  1. //把中文字符串转换为十六进制Unicode编码字符串  
  2. public static String stringToUnicode(String s) {  
  3.     String str = "";  
  4.     for (int i = 0; i < s.length(); i++) {  
  5.         int ch = (int) s.charAt(i);  
  6.         if (ch > 255)  
  7.             str += "\\u" + Integer.toHexString(ch);  
  8.         else  
  9.             str += "\\" + Integer.toHexString(ch);  
  10.     }  
  11.     return str;  
  12. }  
  13.   
  14. //把十六进制Unicode编码字符串转换为中文字符串  
  15. public static String unicodeToString(String str) {  
  16.     Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");     
  17.     Matcher matcher = pattern.matcher(str);  
  18.     char ch;  
  19.     while (matcher.find()) {  
  20.         ch = (char) Integer.parseInt(matcher.group(2), 16);  
  21.         str = str.replace(matcher.group(1), ch + "");     
  22.     }  
  23.     return str;  
  24. }  

也可以更改cas-servlet.xml文件中关于本地化的配置,把:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>  修改为:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.FixedLocaleResolver"/> 

这个本地化解析器返回一个固定的本地化信息。默认值为当前JVM的locale。

另外,我在修改一个CAS界面时,运行过程中每次刷新页面都报一个警告:WARN:oejh.HttpGenerator:Ignoring extra content,并且点击页面的submit按钮,大于在第3或者第5次的时候,页面就reload了,后来用排除法(逐渐缩小代码范围)找出问题,我的新界面的login_soft.css中,有关于图片的css:background: url(../../img/bg-white-lock.png) repeat; 但是对应的目录下没有相应图片,导致了如上的两个问题。把图片都拷贝到相应目录后,问题解决。为什么会这样,原因尚不明,估计与CAS的WebFlow相关代码有关,不深入继续研究了大笑


关于log4j.xml


logger的默认additivity值是true,代表日志继续抛出到root进行处理,此时会被root里面所有appender处理;
logger设置additivity的值为false,代表日志被此节点的appender吃掉,不继续抛出;
root里面的<level value="ERROR" />只对空的logger节点才生效,比如:
<logger name="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" additivity="true" />


关于源码


服务器端源码(版本:cas-server-3.5.2),实际上我们没有必要对服务器端源码做更改,需要的配置直接修改xml就可以了:

inspektrThrottledSubmissionContext.xml中:应该是spring-beans-3.1.xsd,不能是spring-beans.xsd,否则ref="local"会报错:
cvc-complex-type.3.2.2: Attribute 'local' is not allowed to appear in element 'ref'.

cas-server-webapp项目里面,测试下面的很多xml都是格式不正确(其实可以直接在Eclipse里面把Validate关掉),报如下错误:
The markup in the document following the root element must be well-formed.

avax.servlet.jsp.PageContext cannot be resolved to a type,错误,参考:

以上错误不影响源码编译。

注意,因为我们计划用MySQL进行验证,需要引入JDBC,所以在cas-server-webapp项目的pom.xml中,增加依赖,如下:
    <dependency>
       <groupId>org.jasig.cas</groupId>
       <artifactId>cas-server-support-jdbc</artifactId>
       <version>${project.version}</version>
  </dependency>  

客户端源码(版本:cas-client-3.2.1),修改其中的cas-client-core:
  1. //修改类:org.jasig.cas.client.util.AbstractCasFilter的constructServiceUrl,修改后内容如下:  
  2. //return CommonUtils.constructServiceUrl(request, response, this.service, this.serverName, this.artifactParameterName, this.encodeServiceUrl);   
  3. String currentPage = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()   
  4.     + request.getRequestURI()  
  5.     + (CommonUtils.isNotBlank(request.getQueryString()) ? ("?"+request.getQueryString()) : "");  
  6. String ticket = request.getParameter("ticket");  
  7. //http://192.168.1.200:8080/cas/serviceValidate?ticket=ST-74-bJsAKJivCfkABMWLgViu-cas01.example.org&service=http%3A%2F%2Flocalhost%3A8080%2Fauthority%2Fcontroller%2Fmain.do%3Fticket%3DST-74-bJsAKJivCfkABMWLgViu-cas01.example.org  
  8. //去掉参数中所有ticket相关的部分  
  9. currentPage = currentPage.replace("%3Fticket%3D"+ticket, "");  
  10. currentPage = currentPage.replace("&ticket="+ticket, "");  
  11. currentPage = currentPage.replace("?ticket="+ticket, "");  
  12. currentPage = currentPage.replace("&service=""?service");  
  13. return currentPage;  
  14. //或者修改类:org.jasig.cas.client.util.CommonUtils的constructServiceUrl,修改后被替换后的内容如下:  
  15. if (CommonUtils.isBlank(serverName)) {  
  16.     buffer.append(request.getRequestURL());  
  17. }else{  
  18.     if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) {  
  19.     buffer.append(request.isSecure() ? "https://" : "http://");  
  20.     }else{  
  21.     buffer.append(serverName);  
  22.     }  
  23.     buffer.append(request.getRequestURI());  
  24. }  
目的是,让客户端登陆后,自动跳转到认证前的页面,这样,我们就不需要配置cas.service.url(认证成功的返回页面)参数了,也更合理。

工作原理


如果session有效,则认证通过;
如果session无效,一般是别的系统单点登录,本系统第一次访问,则ticket认证,并session生成;
如果单点退出, 调用cas server的logout,则cas server对所有相关单点发送session失效消息,单点监听此消息并触发session过期;
可以看到,绝大多数认证都是通过session进行的,所以对于后台系统来说,不会有任何性能问题。


参考文章:

http://www.docin.com/p-370942269.html

http://blog.sina.com.cn/s/blog_56d8ea900100l44r.html

http://www.doc88.com/p-183734738161.html

http://wenku.baidu.com/view/5c64b1f19e31433239689318.html

http://www.blogjava.net/tufanshu/archive/2011/01/21/343290.html

http://blog.csdn.net/rishengcsdn/article/details/10379321  (oracle)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java 可以通过使用 java.util.concurrent 包中的 AtomicReference 类来实现 compare-and-swap (CAS) 算法。AtomicReference 类是一个原子性的引用类型,允许您在线程安全的方式更新和读取数据。 以下是实现单点登录的代码示例: ``` import java.util.concurrent.atomic.AtomicReference; public class SingleSignOn { private static final AtomicReference<String> SSO_TOKEN = new AtomicReference<>(); public static String getToken() { return SSO_TOKEN.get(); } public static boolean login(String username, String password) { // 实际上需要使用用户名和密码进行验证 if (username.equals("admin") && password.equals("password")) { String token = generateToken(username); return SSO_TOKEN.compareAndSet(null, token); } return false; } private static String generateToken(String username) { return username + System.currentTimeMillis(); } } ``` 在上面的代码中,我们使用了 AtomicReference 类来维护单点登录令牌。如果令牌为空,则说明用户尚未登录,可以通过使用 compareAndSet 方法来尝试登录。如果登录成功,则令牌将被设置为生成的令牌值;否则,令牌将保持不变。 希望这段代码对您有所帮助! ### 回答2: CAS(Central Authentication Service)是一种单点登录(SSO)协议,用于集中管理多个应用系统的用户身份认证。下面是用Java实现CAS单点登录的简要流程: 1. 配置CAS服务端: 首先,在服务器上搭建CAS服务端。一般使用Java开发的CAS服务器有一些成熟的开源实现,如Apereo CASJasig CAS等。配置CAS服务端包括定义认证源(如数据库、LDAP等)、配置认证策略、绑定或生成SSL证书,以确保安全性。 2. 配置应用系统: 在需要实现CAS单点登录的应用系统中,配置CAS客户端。CAS客户端可以使用Java CAS客户端或其他遵循CAS协议的客户端库。配置CAS客户端主要包括指定CAS服务端地址、配置回调URL和授权过滤规则。 3. 用户认证: 当用户访问某个应用系统时,该系统会检测用户是否已经登录。如果未登录,则会重定向至CAS服务端登录页面。 4. CAS服务端认证: 用户在CAS服务端登录页面输入用户名和密码后,CAS服务端会对用户进行认证。认证成功后,CAS服务端会生成一个全局的授权票据(Ticket),并重定向至应用系统的回调URL,并将授权票据作为参数传递给该URL。 5. 应用系统认证: 应用系统接收到来自CAS服务端的回调请求后,会通过与CAS服务端的通信,验证授权票据的有效性。验证成功后,将在应用系统中建立本地会话,并标记该用户已登录。 6. 单点登出: CAS单点登录还支持单点登出功能。用户在任何一个应用系统中登出后,会通知CAS服务端登出,CAS服务端再通知其他已经登录的应用系统进行登出操作。 通过以上流程,就可以实现CAS单点登录。此外,CAS还提供了一些其他的功能,如多因素认证、代理认证等,以满足不同场景的需求。 ### 回答3: CAS(Central Authentication Service)是一种单点登录协议,用于实现在多个应用程序之间的用户身份认证和授权。下面是使用Java实现CAS单点登录的步骤: 1. 搭建CAS Server 首先,需要搭建一个CAS Server作为用户认证和授权的中心。可以使用开源的CAS Server,例如Apereo CASJasig CAS。搭建CAS Server需要配置认证源和授权策略,并生成CAS的服务端证书。 2. 配置CAS Client 每个应用程序都需要配置CAS Client以与CAS Server进行通信。首先,需要引入CAS ClientJava库,然后在应用程序的配置文件中配置CAS Client的相关参数,如CAS Server的地址、服务端证书等。 3. 实现登录功能 当用户访问应用程序时,应用程序会将用户重定向到CAS Server的登录页面。用户在CAS Server上进行身份认证后,CAS Server会生成一个CAS Ticket,并将其包含在重定向URL中返回给应用程序。 4. 验证CAS Ticket 应用程序在接收到CAS Ticket后,通过发送POST请求到CAS Server的验证接口来验证CAS Ticket的有效性。CAS Server会验证Ticket的签名和有效期,并返回验证结果给应用程序。 5. 维护登录状态 如果验证结果为有效,应用程序会保存用户的登录状态。可以使用会话管理技术(如Session)来维护用户的登录状态,并在需要时使用会话中的用户信息进行权限控制。 6. 单点注销 当用户注销时,应用程序发送注销请求到CAS Server的注销接口。CAS Server会销毁用户的会话和Token信息,并向所有已登录的应用程序发送注销通知,以保证单点注销的效果。 通过以上步骤,就可以实现基于JavaCAS单点登录。使用CAS协议,可以实现用户只需登录一次,即可进行多个应用程序的访问和授权,提高了用户体验和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值