在最近工作中使用了YALE CAS,在与集群环境整合时遇到不少问题,以下记录了遇到的问题以及解决方案。
YEAL CAS分为server和client两部分,server就是SSO登录的服务器端,它负责验证用户登录信息并生成相应的Ticket,client是各个需要集成到SSO环境中的具体应用它负责从服务端获取凭证再通过凭证从服务器端换取用户信息。下图为一个标准的单点登录流程
在集群环境下可分为client集群或者server+client集群,我使用的是server+client集群,server集群就涉及到了server节点共享Ticket问题,解决方案是使用数据库存储生成的Ticket。YEAL CAS提供了JPA 的实现,能很容易的实现Ticket数据库存储,只需修改一下配置就ok。
打开ticketRegistry.xml文件加入如下内容
<!--数据源--> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/cas" /> <!--spring的jpa支持,这里使用hibernate的jpa实现--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="persistenceUnitName" value="cas-persistence"/> <property name="persistenceXmlLocation" value="classpath:persistence.xml"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="true" /> <property name="showSql" value="true" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop> <prop key="hibernate.hbm2ddl.auto">none</prop> </props> </property> </bean> <!--spring的jpa事物管理--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory" /> <!--注解支持--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--pojo对象注解支持--> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <!--Ticket存储JPA实现--> <bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.JpaTicketRegistry" />
再打开persistence.xml文件加入如下内容
<persistence-unit name="cas-persistence" transaction-type="RESOURCE_LOCAL"> <!--ejb的hibernate实现--> <provider>org.hibernate.ejb.HibernatePersistence</provider> <!--以下内容为Ticket相关的实体对象--> <class>org.jasig.cas.services.AbstractRegisteredService</class> <class>org.jasig.cas.services.RegexRegisteredService</class> <class>org.jasig.cas.services.RegisteredServiceImpl</class> <class>org.jasig.cas.ticket.TicketGrantingTicketImpl</class> <class>org.jasig.cas.ticket.ServiceTicketImpl</class> <class>org.jasig.cas.ticket.registry.support.JpaLockingStrategy$Lock</class> </persistence-unit>在第1次运行时可以将hibernate.hbm2ddl.auto属性设置成create这样会自动生成相关的表。
由于现在server和client在集群环境下运行,所以在client端web.xml的cas相关filter配置中server和client ip地址配置的是转发服务器ip,这就带来一个问题,在注销操作时server无法正确注销真实的client。解决方案是在client第1次重定向到server时多传递一个client的真实ip,server在注销时根据这个ip来发送注销请求。
参考默认的AuthenticationFilter代码实现一个自己的Filter,关键代码如下
String physicalServerName = "http://" + request.getLocalAddr() + ":" + String.valueOf(request.getLocalPort()) + request.getRequestURI(); final String urlToRedirectTo = casServerLoginUrl + (casServerLoginUrl.indexOf("?") != -1 ? "&" : "?") + getServiceParameterName() + "=" + URLEncoder.encode(serviceUrl, "UTF-8") + "&physicalServer=" + URLEncoder.encode(physicalServerName , "UTF-8") + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "");
重定向urlToRedirectTo中在原有的参数基础上增加一个参数physicalServerName内容是当前client的ip+端口+上下文。
对应的server端的处理类有2个,分别是SimpleWebApplicationServiceImpl和CasArgumentExtractor,为了支持这个新加的参数,参考这2个类的代码实现了ClusterWebApplicationServiceImpl和ClusterCasArgumentExtractor类其中关键代码如下
ClusterWebApplicationServiceImpl
private String physicalUrl; private ClusterWebApplicationServiceImpl(final String id, final String originalUrl, final String artifactId, final ResponseType responseType, final HttpClient httpClient, String physicalUrl) { super(id, originalUrl, artifactId, httpClient); this.responseType = responseType; this.physicalUrl = physicalUrl; } public static ClusterWebApplicationServiceImpl createServiceFrom(final HttpServletRequest request, final HttpClient httpClient) { final String targetService = request.getParameter(CONST_PARAM_TARGET_SERVICE); final String method = request.getParameter(CONST_PARAM_METHOD); final String serviceToUse = StringUtils.hasText(targetService) ? targetService : request.getParameter(CONST_PARAM_SERVICE); if (!StringUtils.hasText(serviceToUse)) { return null; } final String id = cleanupUrl(serviceToUse); final String artifactId = request.getParameter(CONST_PARAM_TICKET); String physicalServer = request.getParameter(CONST_PARAM_PHYSICAL_SERVER); return new ClusterWebApplicationServiceImpl(id, serviceToUse, artifactId, "POST".equals(method) ? ResponseType.POST : ResponseType.REDIRECT, httpClient, physicalServer); } public synchronized boolean logOutOfService(final String sessionIdentifier) { if (this.loggedOutAlready) { return true; } LOG.debug("Sending logout request for: " + getId()); final String logoutRequest = "<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"" + GENERATOR.getNewTicketId("LR") + "\" Version=\"2.0\" IssueInstant=\"" + SamlUtils.getCurrentDateAndTime() + "\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">@NOT_USED@</saml:NameID><samlp:SessionIndex>" + sessionIdentifier + "</samlp:SessionIndex></samlp:LogoutRequest>"; this.loggedOutAlready = true; if (this.getHttpClient() != null) { return this.getHttpClient().sendMessageToEndPoint(physicalUrl, logoutRequest, true); } return false; }
其主要内容就是增加了一个变量physicalUrl存放客户锻真实地址,在注销方法logOutOfService中使用该地址发送注销请求。
ClusterCasArgumentExtractor的代码就很简单了内容如下
public class ClusterCasArgumentExtractor extends AbstractSingleSignOutEnabledArgumentExtractor{ @Override protected WebApplicationService extractServiceInternal( HttpServletRequest request) { return ClusterWebApplicationServiceImpl.createServiceFrom(request, getHttpClientIfSingleSignOutEnabled()); } }
最后在配置文件argumentExtractorsConfiguration.xml中替换SimpleWebApplicationServiceImpl以及argumentExtractorsConfiguration.xml中替换CasArgumentExtractor的相关配置。
相关推荐
整合Yale CAS SSO JAVA Client到Java应用中,开发者需要理解CAS的工作原理,包括Ticket Granting Ticket(TGT)和Service Ticket的概念,以及如何在应用程序中配置和调用CAS客户端库。同时,为了保证安全性,需要...
本文将深入探讨如何将Yale CAS与Apache Shiro进行整合,以构建更高效、安全的Web应用。 CAS是由耶鲁大学开发的一个开放源码的单一登录(Single Sign-On, SSO)系统,旨在简化用户身份验证过程,让用户只需一次登录...
《Yale CAS Server的部署及cas-java-client 3.2的应用》 CAS(Central Authentication Service,中央认证服务)是耶鲁大学开发的一个开源的身份验证框架,它为Web应用程序提供了单一登录(Single Sign-On,SSO)...
Yale CAS实现单点登陆的客户端源码和服务端源码,客户端cas-client-3.1.10代码和cas-server-3.4.2.1代码
总的来说,"Yale CAS SSO DotNet Client"为.NET开发者提供了一个方便的工具,使他们能够轻松地在自己的应用中实现与Yale CAS服务器的SSO整合。通过理解和掌握这个客户端库的使用,开发者可以提升他们的应用安全性,...
本篇将详细探讨Yale CAS的最佳实践,包括环境准备、Java环境的SSL配置、证书验证、Tomcat服务器的配置以及针对Tomcat JMX Bug的解决方案。** ### 一、环境准备 在开始配置Yale CAS之前,确保你有以下基础环境: 1. ...
1. 安装和配置Java环境,因为CAS Server是基于Java构建的。 2. 确定和配置应用服务器,如Tomcat或WebLogic,它们将承载CAS Server应用。 3. 准备数据库,如MySQL或Oracle,用于存储用户认证信息和CAS的元数据。 四...
【标题】"Yale CAS服务器端深度定制"主要涉及到的是CAS(Central Authentication Service)系统,这是一个基于Java开发的开源身份验证框架,由耶鲁大学开发并广泛应用于各个机构的单点登录(Single Sign-On,SSO)...
Yale CAS(Central Authentication Service)是由耶鲁大学开发的一个开源的SSO解决方案,它作为一个独立的Web应用程序运行,提供了一个集中式的认证服务。 在Tomcat服务器中集成Yale CAS以实现SSO,首先需要下载CAS...
SSO(Single Sign-On)是一种身份验证机制,允许用户通过一次登录过程访问多个相互关联的应用系统,无需在每个系统之间重复输入凭证...了解和掌握CAS的原理与实施,对于构建和维护复杂IT环境中的用户认证系统至关重要。
Weblogic 使用 YALE CAS 实现 SSO 单点登录的方法 一、Yale CAS 简介 Yale CAS 是耶鲁大学开发的一种开源的单点登录(SSO)解决方案,提供了一个通用的身份验证框架,允许用户使用单个身份验证来访问多个应用程序。...
解决普元EOS报错:edu.yale.its.tp.cas.client.IContextInit 下载后需jar到lib里面且单击右键在属性一栏的弹出框内添加该jar包即可解决爆粗
#### 一、SSO实现原理与CAS的作用 单点登录(Single Sign-On,简称SSO)是一种用户身份验证机制,允许用户在一个安全领域内访问多个应用系统,而无需多次输入身份验证信息。在税务行业信息化发展中,应用整合成为...
软件介绍: ...下载后先解压,然后将sso-client-java-7.0.8.jar文件复制到lib里面,鼠标单击右键在属性一栏的弹出框内添加该jar包即可解决解决普元EOS报错问题:edu.yale.its.tp.cas.client.IContextInit
相比于其他复杂的人脸数据库,如Feret或CAS-PEAL,Yale人脸库提供了更少的类别和图像,这使得它成为初学者和研究者快速理解和实验人脸识别算法的理想选择。同时,由于其小规模,该库也常被用于验证新算法的基本概念...
在IBM WebSphere Application Server(WAS)环境中配置与Central Authentication Service(CAS)实现单点登录(SSO)是一个涉及多个组件和步骤的过程。首先需要了解的是,WAS是一个广泛应用于IBM Tivoli软件产品中的...
《Yale和Extended Yale B人脸数据库:深度学习与计算机视觉中的关键资源》 在计算机视觉领域,人脸识别是一项至关重要的任务,它涉及到大量的数据集来训练和验证算法。Yale和Extended Yale B人脸数据库就是这样的两...