您的位置:首页 > 编程语言 > Java开发

cas单点登录

2014-07-04 16:24 621 查看


一、            简介

1.      cas是有耶鲁大学研发的单点登录服务器
2.      本教材所用环境:
l  Tomcat 6
l  JDK 6
l  CAS Server版本 cas-server-3.5.2.1-release
l  CAS Client版本 cas-client-3.2.1-release

二、            生成证书

证书对于实现此单点登录非常之重要,证书是服务器端和客户端安全通信的凭证,本教程只是演示,所有用了JDK自带的证书生成工具keytool。当然在实际项目中你可以到专门的证书认证中心购买证书。

中文官方网站:http://www.verisign.com/cn/

1、    用JDK自带的keytool生成证书
命令:keytool -genkey -alias DhccCasKey -keyalg RSA -keystore D:/keys/DhccCasKey
此命令是生成一个证书,其中 DhccCasKey是证书别名。
此命令的执行如图所示:
                    
其中名字与姓氏这一项最好写你的域名,如果在单击测试你可以在C:\Windows\System32\drivers\etc\hosts文件中映射一个虚拟域名,注意不要写IP。
2、    导出证书
命令:keytool -export -file d:/keys/DhccCasKey.crt -alias DhccCasKey -keystore d:/keys/DhccCasKey
如图:
                      
密码为上步设置的密码。

3、    把证书导入到客户端JDK中。
命令:keytool -import -keystore D:\Java\jdk1.6.0_45\jre\lib\security\cacerts -file D:/keys/DhccCasKey.crt -alias DhccCasKey
此命令是把证书导入到JDK中(路径中不能有空格)。

如图:
            
到此证书导入成功。

三、            配置服务端

1、    下载CAS的服务端(互联网svn:http://119.255.194.121:8090/svn/01_RESEARCH/ cas-server-webapp),修改统一登录页面样式,修改数据源配置(/WEB-INF/cas.properties),编译打war包,把打好的war文件拷贝到%TOMCAT_HOME%\webapps下。

2、    修改%TOMCAT_HOME%\conf\server.xml文件去掉此文件83到93行之间的注释,修改为:

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="D:/keys/DhccCasKey"
keystorePass="dhcc1234"/>
3、 以上配置完成访问http://yourhost:8443/cas出现一下页面

                                   

点击继续浏览会出现

                                         

输入用户名admin和密码1234登录则会出现

                                      

登录成功。

至此,说明服务端配置成功。

四、            配置客户端

1、 添加客户端到你的项目中
手动下载cas-client,地址:http://downloads.jasig.org/cas-clients/,然后解压cas-client-3.2.1-release.zip,在modules文件夹中有需要的cas-client-core-3.2.1.jar,请根据自己的项目情况选择使用,把相应的jar包放到你项目WEB-INF/lib下。
2、  在客户端项目的web.xml配置过滤器
   <!-- cas单点登录配置开始 -->

<listener>
<description>用于单点退出,该过滤器用于实现单点登出功能,可选配置</description>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

<filter>
<description>该过滤器用于实现单点登出功能,可选配置</description>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<description>该过滤器负责用户的认证工作,必须启用它</description>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<description>cas server的登陆地址</description>
<param-name>casServerLoginUrl</param-name>
<param-value>https://www.sun.com:8443/cas/login</param-value>
</init-param>
<init-param>
<description>客户端访问地址</description>
<param-name>serverName</param-name>
<param-value>http://www.sun.com:8087</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<description>该过滤器负责对Ticket的校验工作,必须启用它</description>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
</filter-class>
<init-param>
<description>cas server的登陆地址前缀</description>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://www.sun.com:8443</param-value>
</init-param>
<init-param>
<description>客户端访问地址</description>
<param-name>serverName</param-name>
<param-value>http://www.sun.com:8087</param-value>
</init-param>
<init-param>
<description>编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>

4000
<url-pattern>/*</url-pattern>
</filter-mapping>

<!--<filter>-->
<!--<description>该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置-->
<!--</description>-->
<!--<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>-->
<!--<filter-class>-->
<!--org.jasig.cas.client.util.HttpServletRequestWrapperFilter-->
<!--</filter-class>-->
<!--</filter>-->
<!--<filter-mapping>-->
<!--<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>-->
<!--<url-pattern>/*</url-pattern>-->
<!--</filter-mapping>-->

<filter>
<description>该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
比如AssertionHolder.getAssertion().getPrincipal().getName()。
</description>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- cas单点登录配置结束 -->

3.         客户端获取登陆用户信息

AttributePrincipal principal = AssertionHolder.getAssertion().getPrincipal();
String casUserName = principal.getName();//获取登录名
System.out.println(casUserName);
System.out.println(JSONObject.toJSON(principal.getAttributes()).toString());//获取登录账号的其他信息

附录

deployerConfigContext.xml 文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a
copy of the License at the following location:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

-->
<!--
| 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.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!--数据配置-->
<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!--
| 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">

<!-- Uncomment the metadata populator to allow clearpass to capture and cache the password
This switch effectively will turn on clearpass.
<property name="authenticationMetaDataPopulators">
<list>
<bean class="org.jasig.cas.extension.clearpass.CacheCredentialsMetaDataPopulator">
<constructor-arg index="0" ref="credentialsCache" />
</bean>
</list>
</property>
-->

<!--
| 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">
<property name="attributeRepository" ref="attributeRepository"/>
</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"/>
<!--
| 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" />
-->

<!--在 cas-server-support-jdbc.jar 包中,提供了 3 个基于 JDBC 的 AuthenticationHandler,
分别为 BindModeSearchDatabaseAuthenticationHandler, QueryDatabaseAuthenticationHandler,
SearchModeSearchDatabaseAuthenticationHandler。其中 BindModeSearchDatabaseAuthenticationHandler
是用所给的用户名和密码去建立数据库连接,根据连接建立是否成功来判断验证成功与否;
QueryDatabaseAuthenticationHandler 通过配置一个 SQL 语句查出密码,与所给密码匹配;
SearchModeSearchDatabaseAuthenticationHandler 通过配置存放用户验证信息的表、用户名字段和密码字段,构造查询语句来验证。-->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="casDataSource"/>
<property name="sql"
value="select password from sp_org_user where loginname = ? "/>
<property name="passwordEncoder" ref="myPasswordEncoder"/>
</bean>

</list>
</property>
</bean>

<bean id="myPasswordEncoder" class="com.dhcc.extcas.MyPasswordEncoder"/>
<!--
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>-->

<!--新增attributeRepository配置(开始) -->
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<!-- 指定使用的数据源,此处dataSource是已配置好的数据源 -->
<constructor-arg index="0" ref="casDataSource"/>
<!-- 从数据库中查询信息的SQL语句,通常只需要修改表名即可 -->
<constructor-arg index="1" value="select * from sp_org_user where {0}"/>
<property name="queryAttributeMapping">
<map>
<!-- 上述查询的参数,将userName替换为表中表示用户名的字段名称 -->
<entry key="username" value="loginname"/>
</map>
</property>
<property name="resultAttributeMapping">
<map>
<!-- 需要返回给Web应用的其它信息,多个信息时可继续增加entry节点-->
<!--key值为数据表中的字段名称,value值为Client端取值时的名称标识-->
<entry key="id" value="id"/>
<entry key="name" value="name"/>
<entry key="pritype" value="pritype"/>
<!--<entry key="loginname" value="loginname"/>-->
<entry key="cardno" value="cardno"/>
<!--<entry key="password" value="password"/>-->
<entry key="sortnum" value="sortnum"/>
<entry key="path" value="path"/>
<entry key="email" value="email"/>
<entry key="mobile" value="mobile"/>
<entry key="phone" value="phone"/>
<entry key="description" value="description"/>
<entry key="photo" value="photo"/>
<entry key="levelgroupid" value="levelgroupid"/>
<entry key="createtime" value="createtime"/>
<entry key="lastmodifytime" value="lastmodifytime"/>
<entry key="delflag" value="delflag"/>
<entry key=" validflag" value=" validflag"/>
<entry key="lastmodifyusername" value="lastmodifyusername"/>
<entry key="lastmodifyuserid" value="lastmodifyuserid"/>
<entry key="createuserid" value="createuserid"/>
<entry key="lastmodifydate" value="lastmodifydate"/&g
a5df
t;
<entry key="createdate" value="createdate"/>
<entry key="casn" value="casn"/>
<entry key="mac" value="mac"/>
<entry key="ip" value="ip"/>
<entry key="idcard" value="idcard"/>
<entry key="rycode" value="rycode"/>
<entry key="mmtswt" value="mmtswt"/>
<entry key="mmtswtda" value="mmtswtda"/>
<entry key="loginfromcaflag" value="loginfromcaflag"/>
</map>
</property>
</bean>
<!--新增attributeRepository配置(结束) -->

<!--
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.RegexRegisteredService">
<property name="id" value="0"/>
<property name="name" value="HTTP and IMAP"/>
<property name="description" value="Allows HTTP(S) and IMAP(S) protocols"/>
<property name="serviceId" value="^(https?|imaps?)://.*"/>
<property name="evaluationOrder" value="10000001"/>

<property name="ignoreAttributes" value="true"/>
<property name="allowedAttributes">
<!--客户端需要使用的对象的属性名称-->
<list>
<value>id</value>
<value>name</value>
<value>pritype</value>
<!--<value>loginname</value>-->
<value>cardno</value>
<!--<value>password</value>-->
<value>sortnum</value>
<value>path</value>
<value>email</value>
<value>mobile</value>
<value>phone</value>
<value>description</value>
<value>photo</value>
<value>levelgroupid</value>
<value>createtime</value>
<value>lastmodifytime</value>
<value>delflag</value>
<value>validflag</value>
<value>lastmodifyusername</value>
<value>lastmodifyuserid</value>
<value>createuserid</value>
<value>lastmodifydate</value>
<value>createdate</value>
<value>casn</value>
<value>mac</value>
<value>ip</value>
<value>idcard</value>
<value>rycode</value>
<value>mmtswt</value>
<value>mmtswtda</value>
<value>loginfromcaflag</value>
</list>
</property>

</bean>
</list>
</property>
</bean>

<bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager"/>

<bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor">
<property name="monitors">
<list>
<bean class="org.jasig.cas.monitor.MemoryMonitor"
p:freeMemoryWarnThreshold="10"/>
<!--
NOTE
The following ticket registries support SessionMonitor:
* DefaultTicketRegistry
* JpaTicketRegistry
Remove this monitor if you use an unsupported registry.
-->
<bean class="org.jasig.cas.monitor.SessionMonitor"
p:ticketRegistry-ref="ticketRegistry"
p:serviceTicketCountWarnThreshold="5000"
p:sessionCountWarnThreshold="100000"/>
</list>
</property>
</bean>
</beans>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java cas sso 单点登录