`
szqfsx123
  • 浏览: 42359 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

cas使用配置

    博客分类:
  • cas
阅读更多

单点登录(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数据源进行用户认证需要修改casauthenticationHandlers方式,在文件/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一种方式,其他认证方式均可删除。另外需要在在文件中添加datasourepassordEncoder两个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中的RegisteredServiceImplignoreAttributes属性将决定是否添加attributes属性内容,默认为false:不添加,只有去掉这个配置,cas server才会将获取的用户的附加属性添加到认证用的Principalattributes中去.

<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请求的包裹,

       比如允许开发者通过HttpServletRequestgetRemoteUser()方法获得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>

 

分享到:
评论
1 楼 qinshang007 2013-03-18  
你好,为什么每次注释掉serviceRegistryDao bean中的属性之后,就不能登入到cas的认证界面了?去掉后,又可以登入!

相关推荐

Global site tag (gtag.js) - Google Analytics