单点登录(sso)是指基于用户/会话认证的一个过程,用户只需一次性提供凭证(仅一次登录),就可以访问多个应用。
一, 最近一段时间公司进行系统整合,公司决定采用yale cas 单点登录进行整合,在这里对在项目整合中遇到的问题进行总结:
1,到官方上下载CAS2.x服务器改名为ssoAuth
2,以ssoAuth/login为所有系统的登录页,对每个系统进行配置,配置如下:
可查看这篇文章:http://129-cat-163-com.iteye.com/blog/477506
3,在登录之后,遇到一个问题,就是重新刷新又回到登录页(在登录之后会产生一个CASTGC的cookie)
解决:
更改ssoAuth/WebContent/spring-configuration/ticketGrantingTicketCookieGenerator.xml中的 p:cookiePath="/ssoAuth" 和warnCookieGenerator.xml中的p:cookiePath="/ssoAuth" 因为更改了登录名之后,cookie path设置的值没有相应的改变..在验证时获取不到castgc的cookie
4,不跳转到ssoAuth/login下每一个系统都自定义登录页,
可查看这这里面的三篇文章:http://hi.baidu.com/fallenlord/blog/item/ecaa5f263e52cf0b908f9d21.html
5,代理问题
代理可解决的问题:
当一个系统1要去取另一个系统2的数据时,两台不在同一台电脑上,而这两个又被同时都加到单点登录中,这时当你1系统已经登录要去取2系统的数据时,而2系统还没有登录,这时取不到数据??
这时候代理就派上用场.代理票据的产生
http://www.blogjava.net/security/archive/2006/04/26/SSO_CASProxy.html
解决:
可先查看这篇文章http://fallenlord.blogbus.com/logs/57175888.html
再以下详解:
在ssoProxyClient(代理端) ssoProxyBackClient(被代理端) ssoAuth上都要进行配置,
ssoAuth:在整合时发现一个问题,查找源代码,客户端配置正确而不返回代理票据
deployerConfigContext.xml下配置
下面的httpClient要添加上去 <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false" />
代理端与被代理端都要进行配置(配置较长,不一一介绍)有需要留下联系地址,我发过去...
7,代理性能问题解决:
如以上问题所述,系统2变成了被代理的系统,代理系统1每次要到被代理服务器去取一次票据之后,传到系统2去,这时系统2也要到服务器去取下验证的代理票据,进行比对,,
这样一来,每次都要与服务器通信两次,,,性能耗费很大,在不考虑安全性的前提下,可以对双方进行保存一个票据,这样一来,不管访问多少次,只在服务器通信了两次.
我对以上的代理与被代理系统进行了扩展,,一样)有需要留下联系地址,我发过去...
8,客户端可以返回更多的用户数据,这个有两处要进行配置
以下提供一个较完整的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- cas数据源。 --> <bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>net.sourceforge.jtds.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:jtds:sqlserver://192.168.4.22:3433/db</value> </property> <property name="username"> <value>****</value> </property> <property name="password"> <value>****</value> </property> </bean> <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName"> <constructor-arg value="MD5" /> </bean> <bean id="passwordEncoder2" class="org.jasig.cas.authentication.handler.PlainTextPasswordEncoder"> </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"> <!-- | 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 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> <!--这里面的用户表验证,可以配置多个,由上向下的表验证,只要有一个成功就退出--> <!-- support EAP database --> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="casDataSource" /> <property name="sql" value="SELECT Password FROM table1 WHERE Id = ?" /> <property name="passwordEncoder" ref="passwordEncoder" /> </bean> <!-- support another user table,对以上的类进行扩展,不采用那样的验证机制 --> <bean class="com.wqy.sso.auth.QueryDatabaseAuthenticationHandler2"> <property name="dataSource" ref="casDataSource" /> <property name="sql" value="SELECT FGUID FROM table2 WHERE FUserID = ? and cast(ID as varchar(50))=?" /> <!--改变加密机制--> <property name="passwordEncoder" ref="passwordEncoder2" /> </bean> <!-- | 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" /> --> </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 Acegi to find it. To use this, you should add an entry similar to the following between the two value tags: battags=notused,ROLE_ADMIN where battags is the username you want to grant access to. You can put one entry per line. --> <bean id="userDetailsService" class="org.springframework.security.userdetails.memory.InMemoryDaoImpl"> <property name="userMap"> <value> </value> </property> </bean> <!-- 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.jdbc.SingleRowJdbcPersonAttributeDao"> <constructor-arg index="0" ref="casDataSource" /> <constructor-arg index="1" value="SELECT FBy5 AS type,deptId,id,position FROM table WHERE Fid=?" /> <property name="queryAttributeMapping"> <map> <!-- username:为登录的用户名 uid:系统内部会赋给以上的fid --> <entry key="username" value="uid" /> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="id" value="id1" /> <entry key="deptId" value="dept1" /> <entry key="Position" value="position1"/> <entry key="type" value="type1" /> </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" /> </beans>
--->看下一章节