`
JavaCrazyer
  • 浏览: 3009067 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

SSO单点登录之二:Yale CAS实现单点登录(服务器端)

阅读更多

耶鲁大学开发的CAS单点登录系统在SSO中应该说是比较有名的啦,既然也是开源的,我们为何不拿过来学习学习呢

很早之前的耶鲁的CAS开源包地址是在:http://www.yale.edu/tp/auth/ 

目前的CAS开源包都已经转移到新网址了,并且开源包里面的类名都没有以yelu开头了而是jasing

CAS客户端:http://downloads.jasig.org/cas-clients/ 

CAS服务器端:http://www.jasig.org/cas/download 

我下载的都是目前最新版的cas-server-3.4.5服务器端和cas-client-3.2.0客户端

 

 CAS服务器端基础应用

1)将cas-server-3.4.zip解压到一个目录,将cas-server-3.4.5\modules\cas-server-webapp-3.4.5.war拷贝到tomcat的webapp中去,并且改名为CasServer.war.启动tomcat

2)现在可以访问CAS应用了,当然要使用HTTPS加密协议访问,例如本问用到地址:https://javacrazyer.sso.com:8443/CasServer/login,现在打开了CAS服务器的页面输入admin/admin点击登录(CAS默认的验证规则只要用户名和密码相同就通过)


 

所以如果你看到下面的这张图片你就成功了  



 

CAS服务器端深入应用,与数据库配置登录

 

首先打开tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml文件,配置的地方如下:

 1)找到第92行处,注释掉:SimpleTestUsernamePasswordAuthenticationHandler这个验证Handler,这个是比较简单的,只是判断用户名和密码相同即可通过,这个肯定不能在实际应用中使用,弃用!  

 2)注释掉92行后在下面添加下面的代码:

 

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
        <property name="dataSource" ref="dataSource" />
        <property name="sql" value="select password from t_admin_user where login_name=?" />
        <property name="passwordEncoder" ref="MD5PasswordEncoder"/>
</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:///wsriademo</value></property>
   <property name="username"><value>root</value></property>
   <property name="password"><value>root</value></property>
</bean>

<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">  
        <constructor-arg index="0">
                <value>MD5</value>
        </constructor-arg>
</bean>
 

完整的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.
					+-->
				<bean
					class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
				<!--
					| 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" />
				<!--
					| 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="dataSource" />
        <property name="sql" value="select password from t_admin_user where login_name=?" />
        <property name="passwordEncoder" ref="myPasswordEncoder"/>
    </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>
	
	<!-- 
	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="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
   <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
   <property name="url"><value>jdbc:mysql:///javacrazyer</value></property>
   <property name="username"><value>root</value></property>
   <property name="password"><value>root</value></property>
</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:///javacrazyer</value></property>
   <property name="username"><value>root</value></property>
   <property name="password"><value>root</value></property>
</bean>

<bean id="myPasswordEncoder" class="org.jasig.cas.authentication.handler.MyPasswordEncoder"/>
<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">  
        <constructor-arg index="0">
                <value>MD5</value>
        </constructor-arg>
</bean>

</beans>

2.1)dataSource,就是使用JDBC查询时的数据源

这里呢关于dataSource的配置可以采用多种方式,正如我的配置文件中采用了spring支持的dataSource(这里需要添加cas-server-3.4.5\modules\cas-server-support-jdbc-3.4.5.jar),也采用了dbcp的方式(这里需要添加commons-dbcp.jar和commons-pool.jar),当然少不了添加MySQL驱动包了,当然我们可以配置N多种数据源在这里,真用到的其实只会有一个, <property name="dataSource" ref="dataSource" />这句话可以引用你想要的数据源。

这里关于数据源配置可以参考我早前写的关于spring数据源配置方式的文章

2.2)passwordEncoder:处理密码加密

细心的朋友从最后面的代码可以看到MD5加密的类有两个实MD5PasswordEncoder就是默认我们只需把摸认类添

加上无需写其他继承类,而如果你非要继承的话,那么就写你自己的类继承自PasswordEncoder,具体可以更改encode方法

我这里就选择使用了继承的方式,我写的类如下

 

package org.jasig.cas.authentication.handler;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public final class MyPasswordEncoder implements PasswordEncoder {

	public MyPasswordEncoder() {
	};

	public String encode(String password) {
		if (password == null || password.length() == 0) {
			throw new IllegalArgumentException(
					"String to encript cannot be null or zero length");
		}

		StringBuffer hexString = new StringBuffer();

		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(password.getBytes());
			byte[] hash = md.digest();

			for (int i = 0; i < hash.length; i++) {
				if ((0xff & hash[i]) < 0x10) {
					hexString.append("0"
							+ Integer.toHexString((0xFF & hash[i])));
				} else {
					hexString.append(Integer.toHexString(0xFF & hash[i]));
				}
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		return hexString.toString();
	}

}

 当然你也可以选择不继承,采用默认的,都由 <property name="passwordEncoder" ref="MD5PasswordEncoder"/>来决定选择哪个加密方式。

 

2.3)QueryDatabaseAuthenticationHandler是cas-server-support-jdbc提供的查询接口其中一个,QueryDatabaseAuthenticationHandler是通过配置一个 SQL 语句查出密码,与所给密码匹配 

 

2.4)sql:登录查询哪一张表

这里大家或许还有一句话可以看到<property name="sql" value="select password from t_admin_user where login_name=?" />

所以需要用到数据库脚本,数据库名称我这里起名为javacrazyer

/*
Navicat MySQL Data Transfer
Source Host     : localhost:3306
Source Database : javacrazyer
Target Host     : localhost:3306
Target Database : javacrazyer
Date: 2011-01-21 15:19:40
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for area_info
-- ----------------------------
DROP TABLE IF EXISTS `area_info`;
CREATE TABLE `area_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '地区ID',
  `area_code` varchar(32) NOT NULL COMMENT '地区编码',
  `area_name` varchar(60) NOT NULL COMMENT '地区名称',
  `parent_area_id` bigint(20) NOT NULL COMMENT '上级ID',
  `area_number` char(6) DEFAULT NULL,
  `country_code` varchar(32) DEFAULT NULL,
  `area_level` int(11) NOT NULL,
  `enabled` bit(1) NOT NULL,
  `sort` int(11) DEFAULT NULL,
  `remark` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `bmc_bd_uqareainfo` (`area_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of area_info
-- ----------------------------

-- ----------------------------
-- Table structure for city
-- ----------------------------
DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '城市ID',
  `CITY_NAME` varchar(20) NOT NULL COMMENT '城市名称',
  `SUPER_ID` bigint(20) NOT NULL COMMENT '上级城市(没有为-1)',
  `REMARK` varchar(255) DEFAULT NULL COMMENT '城市备注',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='城市';

-- ----------------------------
-- Records of city
-- ----------------------------

-- ----------------------------
-- Table structure for t_admin_user
-- ----------------------------
DROP TABLE IF EXISTS `t_admin_user`;
CREATE TABLE `t_admin_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `password` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `login_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_admin_user
-- ----------------------------
INSERT INTO `t_admin_user` VALUES ('1', '88f6f4ddbd7160aa6a547589af036ee0', null, null, 'cheneywu');
INSERT INTO `t_admin_user` VALUES ('2', '098f6bcd4621d373cade4e832627b4f6', null, null, 'test');
 

 到这里你就认为完事了?看到我脚本中的密码的值是MD5加密过的,为什么加密?2.2中已经介绍过了,所以对于用户名/密码为:test/test的账户来说,在数据库中就应该为test/8f6bcd4621d373cade4e832627b4f6.这个密码值是怎么得到的,sql语言

中可以进行操作:select md5("test")

给力上图


这时你再去访问地址:https://javacrazyer.sso.com:8443/CasServer/login,输入数据库中存在的相同值的用户名密码,就能成功登陆了

 

关于CAS客户端SSO登录下一篇文章将会介绍

  • 大小: 34.3 KB
  • 大小: 39.5 KB
  • 大小: 2 KB
3
4
分享到:
评论

相关推荐

    yale-cas服务器端深度定制

    【标题】"Yale CAS服务器端深度定制"主要涉及到的是CAS(Central Authentication Service)系统,这是一个基于Java开发的开源身份验证框架,由耶鲁大学开发并广泛应用于各个机构的单点登录(Single Sign-On,SSO)...

    CAS框架SSO的实现.rar

    使用CAS框架实现SSO单点登录,其中包含: 1、CAS服务器端安装包 2、客户端源码包和所需的所有jar包 3、CAS+框架+SSO的实现.pdf 5、CAS+SSO实例安装和配置指南PDF版.rar 6、Tomcat中使用Yale+CAS实现单点登陆(SSO)....

    CAS服务器端与客户端jar包(服务器端)

    单点登录(Single Sign-On,简称SSO)是一种网络用户身份验证的机制,它允许用户在一次登录后访问多个应用程序,而无需再次进行身份验证。CAS(Central Authentication Service)是Yale大学开源的一个SSO项目,它...

    入门级单点登录源码

    CAS(Central Authentication Service)是 Yale 大学开发的一个开源的单点登录协议实现,广泛应用于教育、企业和政府机构。 标题提到的"入门级单点登录源码",是指提供了一个初学者级别的 CAS 单点登录系统的源代码...

    单点登录cas参考

    ### CAS单点登录框架 #### 一、CAS简介 单点登录(Single Sign On,简称SSO)是一种用户登录管理方式,用户只需要在一处登录,即可访问多个应用系统。这种方式为用户和系统管理员提供了便利,增强了用户体验,简化...

    java sso 精简版单点登录

    Java SSO(Single Sign-On)精简版单点登录系统是一种设计用于简化用户登录流程的技术。在这样的系统中,用户只需一次登录即可访问多个相互关联的应用系统,无需反复输入用户名和密码。SSO的主要目标是提供更高效、...

    单点登录系统调研报告

    【CAS协议】是Yale大学开发的一种开放源码的单点登录协议,全称为Central Authentication Service。CAS协议的核心在于,用户只需向认证服务器提供一次身份验证,之后通过代理票据(Ticket)在各个应用系统间实现无...

    sso系统CAS配置.pdf

    完成上述步骤后,CAS客户端应用就能与服务器进行交互,实现单点登录功能。当用户访问受保护的资源时,会被重定向到CAS服务器进行身份验证,验证成功后返回服务端,用户无须再次输入凭证即可访问应用。 总之,CAS...

    cas-client-3.3.3-release和cas-server-4.2.1-release下载

    单点登录(Single Sign-On,简称SSO)是一种网络访问控制机制,允许用户在一次登录后,无需再次认证即可访问多个相互信任的应用系统。CAS(Central Authentication Service)是 Yale 大学开发的一个开源项目,它提供...

    cas源码.....

    【描述】:CAS(Central Authentication Service)是 Yale 大学发起的一个开源项目,主要用于实现单点登录(Single Sign-On, SSO)。它是一个基于 Web 的身份验证系统,允许用户通过单一的登录过程访问多个应用系统...

    WAS与CAS配置

    在IBM WebSphere Application Server(WAS)环境中配置与Central Authentication Service(CAS)实现单点登录(SSO)是一个涉及多个组件和步骤的过程。首先需要了解的是,WAS是一个广泛应用于IBM Tivoli软件产品中的...

    cas-client-3.1.12-release.zip

    CAS(Central Authentication Service)是 Yale 大学开发的一个开源项目,主要用于实现单点登录(Single Sign-On, SSO)。它是一个基于Web的认证协议,旨在简化用户对多个应用系统的访问管理,通过一次登录即可访问...

    基于edX平台的云计算课程系统开发研究.pdf

    CAS提供了一个开源的单点登录解决方案,由Yale大学发起,并在2004年成为JA-SIG的一个项目。 在edX平台的二次开发过程中,项目组首先对基于eduStack OVA镜像的edX平台进行了部署研究,并进行了相应的定制开发,包括...

    liferayPortal

    - Single Sign-On (SSO):通过Yale CAS和Siteminder等提供单点登录功能。 - Hierarchical and Extensible系统:支持社区和组织的层次结构和扩展。 - Mule or ServiceMix ESB:支持企业服务总线集成。 #### 八、性能...

Global site tag (gtag.js) - Google Analytics