- 浏览: 43676 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
ty1989:
楼主,你的demo搞定了吗?能不能分享下搞定后的源码
zuul网关的oauth2应用demo,请大神帮我改写(源码参见附件) -
qinshang007:
你好,为什么每次注释掉serviceRegistryDao b ...
cas使用配置 -
jeve:
看似不错,得多看源码
springside
单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,它是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
CAS 具有以下特点:
●开源的企业级单点登录解决方案。
●CAS Server 为需要独立部署的 Web 应用。
从结构体系看, CAS 包含两部分:
CAS Server
CAS Server 负责完成对用户的认证工作, CAS Server 需要独立部署,有不止一种 CAS Server 的实现, Yale CAS Server 和 ESUP CAS Server 都是很不错的选择。
CAS Server 会处理用户名 / 密码等凭证 (Credentials) ,它可能会到数据库检索一条用户帐号信息,也可能在 XML 文件中检索用户密码,对这种方式, CAS 均提供一种灵活但同一的接口 / 实现分离的方式, CAS 究竟是用何种认证方式,跟 CAS 协议是分离的,也就是,这个认证的实现细节可以自己定制和扩展。
CAS Client
CAS Client 负责部署在客户端(注意,我是指 Web 应用),原则上, CAS Client 的部署意味着,当有对本地 Web 应用的受保护资源的访问请求,并且需要对请求方进行身份认证, Web 应用不再接受任何的用户名密码等类似的 Credentials ,而是重定向到 CAS Server 进行认证。
目前, CAS Client 支持(某些在完善中)非常多的客户端,包括 Java 、 .Net 、 ISAPI 、 Php 、 Perl 、 uPortal 、 Acegi 、 Ruby 、 VBScript 等客户端,几乎可以这样说, CAS 协议能够适合任何语言编写的客户端应用。
CAS 是通过 TGT(Ticket Granting Ticket) 来获取 ST(Service Ticket) ,通过 ST 来访问服务,而 CAS 也有对应 TGT , ST 的实体,而且他们在保护 TGT 的方法上虽然有所区别,但是,最终都可以实现这样一个目的——免去多次登录的麻烦。
客户端流程
1. 第一次访问http://localhost:8080/a,
CLIENT:没票据且SESSION中没有消息所以跳转至CAS
CAS:拿不到TGC故要求用户登录
2. 认证成功后回跳
CAS:通过TGT生成ST发给客户端,客户端保存TGC,并重定向到http://localhost:8080/a
CLIENT:带有票据所以不跳转只是后台发给CAS验证票据(浏览器中无法看到这一过程)
认证成功后,CAS服务器创建一个很长的、随机生成的字符串,称为“Ticket”。随后,CAS将这个ticket和成功登录的用户,以及服务联系在一起。这个ticket是一次性使用的一种凭证,它只对登录成功的用户及其服务使用一次。使用过以后立刻失效。
3. 第一次访问http://localhost:8080/b
CLIENT:没票据且SESSION中没有消息所以跳转至CAS
CAS:从客户端取出TGC,如果TGC有效则给用户ST并后台验证ST,从而SSO。
用户进入应用B时,首先仍然会重定向到CAS服务器。不过此时CAS服务器不再要求用户输 入用户名和密码,而是首先自动寻找Cookie,根据Cookie中保存的信息,进行登录。然后,CAS同样给出新的ticket重定向应用B给cas验证(流程同应用A验证方式),如果验证成功则应用B创建session记录CASReceipt信息到session中,以后凭此session登录应用B。
4. 再次访问http://localhost:8080/a
CLIENT:没票据但是SESSION中有消息故不跳转也不用发CAS验证票据,允许用户访问
1环境搭建:
需要的文件
JDK 的下载地址: http://java.sun.com
TOMCAT的下载地址:[url=http://tomcat.apache.org/]http://tomcat.apache.org/[/url]
客户端
下载网址 http://downloads.jasig.org/cas-clients/
软件版本 casclient-3.2
服务器
下载网址 http://www.jasig.org/cas/download
软件版本 cas server-3.4.5
1.2服务器部署
解压此文件夹 cas server-3.4.5
找到cas-server-3.4.5\modules\cas-server-webapp-3.4.5.war
把此文件夹复制到tomcat服务器下webapps里面
修改文件cas-server-webapp-3.4.5.war 为 cas.war
1.3使用http协议的设置 默认设置是使用https协议,如果想使用http协议,需要按以下配置使用
在cas-server-webapp中的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml文件中有如下配置
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false" //默认为true,使用https,如果只需要http,修改为false即可
p:cookieMaxAge="-1"
p:cookieName="CASTGC"
p:cookiePath="/cas" />
/WEB-INF/deployerConfigContext.xml 文件
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>
参数p:cookieSecure="true",同理为HTTPS验证相关,TRUE为采用HTTPS验证,与deployerConfigContext.xml的参数保持一致。
参数p:cookieMaxAge="-1",简单说是COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的IE窗口有效,IE关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在3600秒内,打开任意IE窗口,都不需要验证。
1.4 使用jdbc数据源进行用户认证需要修改cas的authenticationHandlers方式,在文件/WEB-INF/deployerConfigContext.xml有如下配置:
<property name="authenticationHandlers">
<list>
<!--下面的是最初设置 用户名和密码如果一样就可以登录 如果改用数据源验证下面的将注释-->
<!--<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />-->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="select password from tb_user where user_name=? " />
//用户密码编码方式
<property name="passwordEncoder" ref="passwordEncoderBean"/>
</bean>
</list>
</property>
该属性中的list只要用一个认证通过即可,建议将红色部分放在第一位,如果确认只用jdbc一种方式,其他认证方式均可删除。另外需要在在文件中添加datasoure和passordEncoder两个bean,如下
<!—数据源-->
<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/mypro?characterEncoding=utf-8</value>
</property>
<property name="username"><value>root</value></property>
<property name="password"><value></value></property>
</bean>
<!—密码-- >
<bean id="passwordEncoderBean" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-arg value="MD5" />
</bean>
1.5 让cas server提供更多的用户数据共客户端使用有时候,客户端希望获取到用户名以外的其他字段。我们可以这样来配置
配置文件:
/WEB-INF/deployerConfigContext.xml
<property name="credentialsToPrincipalResolvers">
<list>
<!--<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />-->
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<!--为认证过的用户的Principal添加属性 -- >
<property name="attributeRepository" >
<ref local="attributeRepository"/>
</property>
</bean>
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
修改该文件中默认的 attributeRepositorybean配置
<!-- 在这里配置获取更多用户的信息 -->
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1" value="select user_Id , password,EMAIL, FINDPASSWORDACTIVE from tb_user where {0} " />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="user_name"/>
<!-- 这里必须这么写,系统会自己匹配,貌似和where语句后面的用户名字段的拼写没有什么关系 要获取的属性在这里配置-->
</map>
</property>
<property name="resultAttributeMapping">
<map>
<!—下面是要返回的数据 记得select 里面 都要有此字段-- >
<entry key="user_name" value="username"/>
<entry key="User_ID" value="userid"/>
<entry key="password" value="password"/>
<entry key="FINDPASSWORDACTIVE" value="FINDPASSWORDACTIVE"/>
<entry key="EMAIL" value="EMAIL"/>
<entry key="QUESTION" value="QUESTION"/>
</map>
</property>
</bean>
备注:网上有很多的关于这个的配置,但是如果您使用的是提供的版本或是高于这个版本,就应该象上面这样配置,无用质疑。
修改该xml文件中最后一个默认的serviceRegistryDao bean中的属性全部注释掉,或者删除,这个bean中的RegisteredServiceImpl的ignoreAttributes属性将决定是否添加attributes属性内容,默认为false:不添加,只有去掉这个配置,cas server才会将获取的用户的附加属性添加到认证用的Principal的attributes中去.
<bean
id="serviceRegistryDao"
class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<!— 下面需要注释 如果不注释客户端将获取不到其他的数据
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="0" />
<property name="name" value="HTTP" />
<property name="description" value="Only Allows HTTP Urls" />
<property name="serviceId" value="http://**" />
</bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="1" />
<property name="name" value="HTTPS" />
<property name="description" value="Only Allows HTTPS Urls" />
<property name="serviceId" value="https://**" />
</bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="2" />
<property name="name" value="IMAPS" />
<property name="description" value="Only Allows HTTPS Urls" />
<property name="serviceId" value="imaps://**" />
</bean>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="3" />
<property name="name" value="IMAP" />
<property name="description" value="Only Allows IMAP Urls" />
<property name="serviceId" value="imap://**" />
</bean>
</list>
</property>-->
</bean>
修改WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp文件,红色字体是增加部分。如果不增加此部分客户端也将获取不到其他的数据
如下:
<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>
<c:if test="${not empty pgtIou}">
<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
</c:if>
<c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
<cas:proxies>
<c:forEach var="proxy" items="${assertion.chainedAuthentications}"
varStatus="loopStatus" begin="0"
end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
<cas: proxy>${fn: escapeXml( proxy.principal.id)}</cas:proxy>
</c:forEach>
</cas:proxies>
</c:if>
<c:if
test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)
>
0}">
<cas:attributes>
<c:forEach
var="attr"
items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"
varStatus="loopStatus"
begin="0"
end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}"
step="1">
<cas: ${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas: ${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
</c:if>
</cas:authenticationSuccess>
</cas:serviceResponse>
1.6 客户端登录
如果客户端第一次没有登录系统的话,将会跳转到CAS服务器验证。
在web.xml里面增加
<!--该过滤器负责用户的认证工作,必须启用它—- >
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<!-- CAS login 服务地址-->
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://192.168.16.197:8080/cas/login</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
<!-- 客户端应用服务地址-->
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080/x431</param-value>
</init-param>
</filter>
<!--负责Ticket校验,必须启用-->
<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://192.168.16.197:8080/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!--
该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
-->
<filter>
<filter-name>CAS HttpServletRequest WrapperFilter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!--
该过滤器使得开发者可以通过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 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>
<filter-mapping>
<filter-name>CAS HttpServletRequest WrapperFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.7 客户端登出
在web.xml里面增加
<!-- 改过滤器用于实现单点登出功能,可选配置-- >
<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>
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
页面增加
<a href="http://192.168.16.197:8080/cas/logout?service=http://192.168.16.232:8080/x431">退出</a><br/>
如果想让客户端退出后返回到登录界面,在服务器 WEB-INF\cas-servlet.xml
增加红色部分
WEB-INF\cas-servlet.xml
<bean id="logoutController" class="org.jasig.cas.web.LogoutController"
p:centralAuthenticationService-ref="centralAuthenticationService"
p:logoutView="casLogoutView"
p:warnCookieGenerator-ref="warnCookieGenerator"
p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator"
p:followServiceRedirects="true"/>
1.8 客户端获取数据
<%@page import="org.jasig.cas.client.authentication.AttributePrincipal" %>
<%@page import="java.util.*" %>
<%
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
String loginName = principal.getName();
out.println("loginName "+loginName);
Map<String, Object> attributes = principal.getAttributes();
out.println("<br>");
if(attributes != null) {
out.println(attributes.get("userid"));
out.println("<br>");
out.println("password"+attributes.get("password"));
out.println("<br>");
out.println("EMAIL"+attributes.get("EMAIL"));
out.println("<br>");
out.println("FINDPASSWORDACTIVE"+attributes.get("FINDPASSWORDACTIVE"));
out.println("<br>");
}
%>
源码:
数据库:
CREATE TABLE `t_admin_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `email` varchar(255) DEFAULT NULL, `login_name` varchar(255) NOT NULL, `name` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `login_name` (`login_name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; INSERT INTO `t_admin_user` VALUES (1,'test@163.com','user','name','123456'); /*!40000 ALTER TABLE `t_admin_user` ENABLE KEYS */; UNLOCK TABLES;
服务器端代码:
需要引入相关jia包
war包lib目录
cas-server-core-3.4.5.jar
cas-server-support-generic-3.4.5.jar
cas-server-support-jdbc-3.4.5.jar
cas-server-support-ldap-3.4.5.jar
commons-dbcp-1.3.jar
commons-pool-1.5.4.jar
mysql-connector-java-5.1.14.jar
配置
deployerConfigContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- | deployerConfigContext.xml centralizes into one file some of the declarative configuration that | all CAS deployers will need to modify. | | This file declares some of the Spring-managed JavaBeans that make up a CAS deployment. | The beans declared in this file are instantiated at context initialization time by the Spring | ContextLoaderListener declared in web.xml. It finds this file because this | file is among those declared in the context parameter "contextConfigLocation". | | By far the most common change you will need to make in this file is to change the last bean | declaration to replace the default SimpleTestUsernamePasswordAuthenticationHandler with | one implementing your approach for authenticating usernames and passwords. +--> <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" xmlns:sec="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- | This bean declares our AuthenticationManager. The CentralAuthenticationService service bean | declared in applicationContext.xml picks up this AuthenticationManager by reference to its id, | "authenticationManager". Most deployers will be able to use the default AuthenticationManager | implementation and so do not need to change the class of this bean. We include the whole | AuthenticationManager here in the userConfigContext.xml so that you can see the things you will | need to change in context. +--> <bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl"> <!-- | This is the List of CredentialToPrincipalResolvers that identify what Principal is trying to authenticate. | The AuthenticationManagerImpl considers them in order, finding a CredentialToPrincipalResolver which | supports the presented credentials. | | AuthenticationManagerImpl uses these resolvers for two purposes. First, it uses them to identify the Principal | attempting to authenticate to CAS /login . In the default configuration, it is the DefaultCredentialsToPrincipalResolver | that fills this role. If you are using some other kind of credentials than UsernamePasswordCredentials, you will need to replace | DefaultCredentialsToPrincipalResolver with a CredentialsToPrincipalResolver that supports the credentials you are | using. | | Second, AuthenticationManagerImpl uses these resolvers to identify a service requesting a proxy granting ticket. | In the default configuration, it is the HttpBasedServiceCredentialsToPrincipalResolver that serves this purpose. | You will need to change this list if you are identifying services by something more or other than their callback URL. +--> <property name="credentialsToPrincipalResolvers"> <list> <!-- | UsernamePasswordCredentialsToPrincipalResolver supports the UsernamePasswordCredentials that we use for /login | by default and produces SimplePrincipal instances conveying the username from the credentials. | | If you've changed your LoginFormAction to use credentials other than UsernamePasswordCredentials then you will also | need to change this bean declaration (or add additional declarations) to declare a CredentialsToPrincipalResolver that supports the | Credentials you are using. +--> <!-- 为认证过的用户的Principal添加属性 --> <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver"> <property name="attributeRepository" > <ref local="attributeRepository"/> </property> </bean> <!-- | HttpBasedServiceCredentialsToPrincipalResolver supports HttpBasedCredentials. It supports the CAS 2.0 approach of | authenticating services by SSL callback, extracting the callback URL from the Credentials and representing it as a | SimpleService identified by that callback URL. | | If you are representing services by something more or other than an HTTPS URL whereat they are able to | receive a proxy callback, you will need to change this bean declaration (or add additional declarations). +--> <bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" /> </list> </property> <!-- | Whereas CredentialsToPrincipalResolvers identify who it is some Credentials might authenticate, | AuthenticationHandlers actually authenticate credentials. Here we declare the AuthenticationHandlers that | authenticate the Principals that the CredentialsToPrincipalResolvers identified. CAS will try these handlers in turn | until it finds one that both supports the Credentials presented and succeeds in authenticating. +--> <property name="authenticationHandlers"> <list> <!-- | This is the authentication handler that authenticates services by means of callback via SSL, thereby validating | a server side SSL certificate. +--> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false"/> <!-- | This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS | into production. The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials | where the username equals the password. You will need to replace this with an AuthenticationHandler that implements your | local authentication strategy. You might accomplish this by coding a new such handler and declaring | edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules. +--> <!-- <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> --> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="casDataSource" /> <property name="sql" value="select password from t_admin_user where login_name = ? " /> <!-- <property name="sql" value="select password from tb_user where user_name=? " /> <property name="passwordEncoder" ref="passwordEncoderBean"/> --> </bean> </list> </property> </bean> <!-- This bean defines the security roles for the Services Management application. Simple deployments can use the in-memory version. More robust deployments will want to use another option, such as the Jdbc version. The name of this should remain "userDetailsService" in order for Spring Security to find it. --> <!-- <sec:user name="@@THIS SHOULD BE REPLACED@@" password="notused" authorities="ROLE_ADMIN" />--> <sec:user-service id="userDetailsService"> <sec:user name="@@THIS SHOULD BE REPLACED@@" password="notused" authorities="ROLE_ADMIN" /> </sec:user-service> <!-- Bean that defines the attributes that a service may return. This example uses the Stub/Mock version. A real implementation may go against a database or LDAP server. The id should remain "attributeRepository" though. <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"> <property name="backingMap"> <map> <entry key="uid" value="uid" /> <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> <entry key="groupMembership" value="groupMembership" /> </map> </property> </bean> --> <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> <constructor-arg index="0" ref="casDataSource" /> <constructor-arg index="1" value="select email,name,login_name,password from t_admin_user where {0}" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="login_name"/> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="login_name" value="username"></entry> <entry key="email" value="email"></entry> <entry key="name" value="name"></entry> <entry key="password" value="password"></entry> </map> </property> </bean> <!-- <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> <constructor-arg index="0" ref="casDataSource" /> <constructor-arg index="1" value="select user_Id , password,EMAIL, FINDPASSWORDACTIVE from tb_user where {0} " /> <property name="queryAttributeMapping"> <map> <entry key="username" value="user_name"/> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="user_name" value="username"></entry> <entry key="USER_ID" value="userid"></entry> <entry key="password" value="password"></entry> <entry key="FINDPASSWORDACTIVE" value="FINDPASSWORDACTIVE"></entry> <entry key="EMAIL" value="EMAIL"></entry> <entry key="QUESTION" value="QUESTION"></entry> </map> </property> </bean> --> <!-- Sample, in-memory data store for the ServiceRegistry. A real implementation would probably want to replace this with the JPA-backed ServiceRegistry DAO The name of this bean should remain "serviceRegistryDao". --> <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"> <!-- <property name="registeredServices"> <list> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="0" /> <property name="name" value="HTTP" /> <property name="description" value="Only Allows HTTP Urls" /> <property name="serviceId" value="http://**" /> </bean> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="1" /> <property name="name" value="HTTPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="https://**" /> </bean> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="2" /> <property name="name" value="IMAPS" /> <property name="description" value="Only Allows HTTPS Urls" /> <property name="serviceId" value="imaps://**" /> </bean> <bean class="org.jasig.cas.services.RegisteredServiceImpl"> <property name="id" value="3" /> <property name="name" value="IMAP" /> <property name="description" value="Only Allows IMAP Urls" /> <property name="serviceId" value="imap://**" /> </bean> </list> </property> --> </bean> <!-- <bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@192.168.16.232:1521:mypro"/> <property name="username" value="scott"/> <property name="password" value="tiger"/> <property name="maxActive" value="100"/> <property name="maxWait" value="1000"/> <property name="poolPreparedStatements" value="true"/> <property name="defaultAutoCommit" value="true"/> </bean> --> <bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mypro?characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value=""/> <property name="maxActive" value="100"/> <property name="maxWait" value="1000"/> <property name="poolPreparedStatements" value="true"/> <property name="defaultAutoCommit" value="true"/> </bean> <!-- 密码 --> <bean id="passwordEncoderBean" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg value="MD5" /> </bean> </beans>
casServiceValidationSuccess.jsp
<%@ page session="false"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%><cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:authenticationSuccess> <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user> <c:if test="${not empty pgtIou}"> <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications) > 1}"> <cas:proxies> <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1"> <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> </c:forEach> </cas:proxies> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)>0}"> <cas:attributes> <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}" step="1"> <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}> </c:forEach> </cas:attributes> </c:if> </cas:authenticationSuccess> </cas:serviceResponse>
ticketGrantingTicketCookieGenerator.xml
<?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"> <description> Defines the cookie that stores the TicketGrantingTicket. You most likely should never modify these (especially the "secure" property). You can change the name if you want to make it harder for people to guess. </description> <bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator" p:cookieSecure="false" p:cookieMaxAge="-1" p:cookieName="CASTGC" p:cookiePath="/cas" /> </beans>
web.xml 加入编码设置:
<filter> <filter-name>encoding-filter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding-filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
客户端程序调用
需要引入jar包:
cas-client-core-3.2.0.jar
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下寻找 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext-resources.xml classpath:/applicationContext-dao.xml classpath:/applicationContext-service.xml classpath*:/applicationContext.xml /WEB-INF/applicationContext*.xml </param-value> </context-param> <filter> <filter-name>encodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <servlet> <servlet-name>myproInit</servlet-name> <servlet-class>com.mypro.core.webapp.servlet.MyproInitServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <filter> <filter-name>struts-prepare</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter </filter-class> </filter> <filter> <filter-name>struts</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts-prepare</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>*.action</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <!-- 对Spring容器进行实例化,并把实例存放在application的属性里 --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <jsp-config> <taglib> <taglib-uri>/pro-tags</taglib-uri> <taglib-location>/WEB-INF/tlds/pro.tld</taglib-location> </taglib> </jsp-config> <session-config> <session-timeout>30</session-timeout> </session-config> <!-- 该过滤器负责用户的认证工作,必须启用它--> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <!-- CAS login 服务地址--> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>http://192.168.16.54:8081/casserver/login</param-value> </init-param> <init-param> <param-name>renew</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>gateway</param-name> <param-value>false</param-value> </init-param> <!-- 客户端应用服务地址--> <init-param> <param-name>serverName</param-name> <param-value>http://192.168.16.54:8081</param-value> </init-param> </filter> <!--负责Ticket校验,必须启用--> <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://192.168.16.54:8081/casserver</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://192.168.16.54:8081</param-value> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 --> <filter> <filter-name>CAS HttpServletRequest WrapperFilter</filter-name> <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <!-- 该过滤器使得开发者可以通过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 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> <filter-mapping> <filter-name>CAS HttpServletRequest WrapperFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 改过滤器用于实现单点登出功能,可选配置--> <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> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/common/error.jsp</location> </error-page> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@page import="org.jasig.cas.client.authentication.AttributePrincipal"%> <%@page import="java.util.*"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> <a href="http://192.168.16.54:8081/cas/logout?service=http://192.168.16.54:8081/mypro"> <% AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal(); String loginName = principal.getName(); out.println("loginName " + loginName); Map<String, Object> attributes = principal.getAttributes(); out.println("<br>"); if (attributes != null) { out.println(attributes.get("userid")); out.println("<br>"); out.println("password" + attributes.get("password")); out.println("<br>"); out.println("EMAIL" + attributes.get("EMAIL")); out.println("<br>"); out.println("FINDPASSWORDACTIVE" + attributes.get("FINDPASSWORDACTIVE")); out.println("<br>"); } %> </body> </html>
相关推荐
根据给定文件“cas使用配置.txt”的标题、描述、标签以及部分内容,我们可以提炼出一系列关于CAS(Central Authentication Service)在IT环境中的配置与部署的重要知识点。以下是对这些知识点的详细阐述: ### CAS...
总的来说,这个压缩包提供了一套完整的CAS实施教程,从源码到配置,再到实际应用,对于想要理解和使用CAS的开发者来说是一份宝贵的资源。通过学习和实践,你可以掌握CAS的核心概念,实现自定义认证策略,以及优化...
CAS Server全部配置详解
### 单点登录CAS的配置过程详解 #### 一、引言 单点登录(Single Sign-On, SSO)是一种身份验证机制,允许用户通过一次登录即可访问多个应用系统而无需再次登录。CAS (Central Authentication Service) 是一种开源的...
### CAS SSO配置文档详解 #### 一、SSO实现原理与CAS的作用 单点登录(Single Sign-On,简称SSO)是一种用户身份验证机制,允许用户在一个安全领域内访问多个应用系统,而无需多次输入身份验证信息。在税务行业...
4. **自定义登录界面**:如果你想自定义客户端的登录界面,可以在应用中创建一个定制的登录页面,然后配置CAS客户端库以使用该页面。你需要确保页面能够收集用户的凭证(通常是用户名和密码)并提交到CAS服务器进行...
CAS 安装和配置的关键在于正确配置 CAS Server 和客户端应用,确保服务器能够正确处理认证请求,客户端应用能够识别并响应 CAS Server 的认证结果。通过这种方式,你可以构建一个安全、高效的单点登录系统,提升用户...
02 H3C CAS-云容器引擎配置指导 03 H3C CAS 虚拟机快照配置指导 04 H3C CAS-虚拟机防病毒配置指导 05 H3C CAS SR-IOV配置指导 06 H3C CAS vGPU热迁移配置指导 07 H3C CAS 内存管理最佳实践 08 H3C CAS 磁盘...
总结,配置CAS Server 4.0.0使用MySQL数据源涉及多个步骤,包括修改配置文件以提供数据库连接信息,定义数据源bean,创建数据库表结构,以及进行连接测试和可能的自定义配置。确保每个步骤都正确执行,才能使CAS ...
cas 3.5配置指南
2. **配置 CAS 验证**:在客户端应用的配置文件中,设置 CAS Server 的地址、服务验证 URL 和登出 URL。 3. **测试 SSO 功能**:确保在同一个浏览器会话中,访问 app1 和 app2 不需要再次登录,且可以获取登录用户...
如果你使用的是Spring Boot驱动的CAS,可以利用其热加载配置的特性,通过`/actuator/refresh`端点刷新配置,避免不必要的服务中断。 总结起来,CAS Service 5.2.x与MySQL数据库的REST配置涉及以下几个关键步骤: 1....
【CAS SSO 配置详解】 CAS(Central Authentication Service)是一种广泛应用的开源单点登录(Single Sign-On,简称SSO)解决方案,由耶鲁大学发起并由JA-SIG组织维护。它为企业级Web应用提供了安全可靠的认证服务...
CAS(Central Authentication Service,中央认证服务)是一种广泛使用的开源单点登录(Single Sign-On, SSO)系统,它允许用户通过一个入口点登录,然后在多个应用之间无缝切换,而无需再次验证身份。CAS的目的是...
3. **生成及导入证书**:使用keytool工具生成证书,并将其导入到CAS服务器的证书库中。具体步骤包括生成服务端密钥文件、生成服务端证书和导入证书到cacerts密钥库文件。例如,在命令行中执行: - `keytool -genkey...
在这个场景中,我们将探讨如何使用CAS配置来实现单点登录。 首先,我们需要理解CAS服务器的角色。CAS服务器作为认证中心,负责验证用户的身份。当用户尝试访问受保护的资源时,他们会被重定向到CAS服务器进行登录。...
本案例中,我们将探讨如何将Liferay 5.2.3与CAS(Central Authentication Service)配置为SSO系统。 Liferay是一款开源的企业级门户平台,它提供了一个灵活的框架来构建和管理Web应用程序。而CAS则是一个开源的身份...
首先,需要在项目中引入CAS客户端的jar包cas-client-core-3.3.3.jar,以便使用CAS客户端提供的单点登录功能。 2. 修改Web.xml配置 在项目的Web.xml文件中,需要添加以下配置: * 单点退出监听器:org.jasig.cas....
### 使用CAS在Tomcat中实现单点登录的关键知识点 #### 一、CAS简介与特性 - **CAS**(Central Authentication Service)是由耶鲁大学发起的一个开源项目,它为Web应用程序提供了一种简单可靠且功能强大的单点登录...
基于Tomcat6的CAS SSO配置涉及的主要知识点包括SSO(Single Sign-On,单点登录)、CAS(Central Authentication ...正确配置和使用CAS能有效地提升系统的安全性,简化用户登录流程,同时保持应用的可扩展性和灵活性。