SSO CAS 探究

CAS的官网:http://www.jasig.org/cas

CAS Server wiki:https://wiki.jasig.org/display/CASUM/Home

CAS Client wiki:https://wiki.jasig.org/display/CASC/Home

http://blog.csdn.net/haydenwang8287/article/details/5765941

http://www.micmiu.com/enterprise-app/sso/sso-cas-sample/

http://yuzhwe.iteye.com/blog/830143  获取更多用户信息

 http://www.doc88.com/p-598933477220.html 

http://toplchx.iteye.com/blog/1013001cas 与spring security整合

CAS 基础配置

1JDK环境变量设置

2 安全证书配置

3 部署CAS-Server相关的Tomcat

4 部署CAS-Client相关的Tomcat

5 不使用HTTPS配置

6 Client端获取Server 登陆信息

7 Clinet 获取更多用户信息配置

 

1 环境变量

set JAVA_HOME=D:\sso\jdk1.6.0_13
set TOMCAT_HOME=D:\sso\cas-apache-tomcat-6.0.35

2 证书配置

1 创建

keytool -genkey -alias zendai -keyalg RSA -keysize 1024 -keypass changeit -validity 365 -keystore d:\sso\zendai.keystore -storepass changeit

  姓氏:uc.zendai.com  (要与访问cas server域名相同,非常重要)

  单位名称:zendai.com

  组织名:zendai

  城市:SH

  身份:SH

  国家:CN

2 导出

keytool -export -alias zendai -keystore d:\sso\zendai.keystore -file d:\sso\zendai.crt -storepass changeit

3 删除

keytool -delete -alias zendai -keystore D:\j2ee\jdk1.6.0_30\jre\lib\security\cacerts

pwd:changeit

4 导入

keytool -import -keystore D:\j2ee\jdk1.6.0_30\jre\lib\security\cacerts -file d:\sso\zendai.crt -alias zendai

pwd:changeit

5 查看所有证书

keytool -list -keystore D:\j2ee\jdk1.6.0_30\jre\lib\security\cacerts

pwd:changeit

 

注意:

CAS 证书制作经常容易出 PKIX path building failed:报错

解决方法:

1 检查导入的JDK是否是系统环境变量默认的JDK。

2 检查设置环境变量的JDK证书是否导入.

3 证书导入成功确认后,确认CAS SERVER 8443路径认证的 证书是否与导入的证书一致.



 3 Server 端

CAS的官网:http://www.jasig.org/cas 下载Server 端和Client端

修改 tomcat conf server.xml

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/ssodemo.keystore" keystorePass="michaelpwd"
clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8" />

 

4 Client端

client端 加入 cas-core-client.jar,common-logger.jar 后修改web.xml

<!-- ======================== 单点登录开始 ======================== -->

<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->

<listener>

<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

</listener>

<!-- 该过滤器用于实现单点登出功能,可选配置。 -->

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

 

<filter>

<filter-name>CAS Filter</filter-name>

<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>

<init-param>

<param-name>casServerLoginUrl</param-name>

<param-value>https://demo.micmiu.com:8443/cas-server/login</param-value>

</init-param>

<init-param>

<param-name>serverName</param-name>

<param-value>http://app1.micmiu.com:8888</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CAS Filter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- 该过滤器负责对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>https://demo.micmiu.com:8443/cas-server</param-value>

</init-param>

<init-param>

<param-name>serverName</param-name>

<param-value>http://app1.micmiu.com:8888</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CAS Validation Filter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

<!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->

<filter>

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

 

<!-- 该过滤器使得开发者可以通过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 Assertion Thread Local Filter</filter-name>

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

<!-- ======================== 单点登录结束 ======================== -->

 

CAS 动态登陆认证

1  复制所需的类库到web应用下,如下二个jar包。

cas-server-support-jdbc-3.1.1.jar

2 配置cas/WEB-INF/目录下的deployerConfigContext.xml 文件。

注释掉 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />    

增加数据源<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">

       <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>

       <property name="url"><value>jdbc:oracle:thin:@localhost:1521:oracle</value></property>

       <property name="username"><value>foundation</value></property>

       <property name="password"><value>foundation</value></property>

  // <property name="passwordEncoder" ref="MD5PasswordEncoder"/>

    </bean>

3 改变认证方式

<bean  class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
变为数据库认证方式:

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
        <property name="sql" value="select password from app_user where username=?" />
      <property name="dataSource" ref="dataSource" />
</bean>

 

4 添加解密方式

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

 

5 不使用HTTPS证书配置

            1、tomcat/webapps/cas/WEB-INF/deployerConfigContext.xml

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

                                                            p:httpClient-ref="httpClient"/>

            增加参数p:requireSecure="false",是否需要安全验证,即HTTPS,false为不采用,加上去之后如下:

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

                                                            p:httpClient-ref="httpClient"  p:requireSecure="false"/>

 

            2、Tomcat 6.0/webapps/cas/WEB-INF/spring-configuration/

ticketGrantingTicketCookieGenerator.xml

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

                 p:cookieSecure="true"

                 p:cookieMaxAge="-1"

                 p:cookieName="CASTGC"

                 p:cookiePath="/cas" />

参数p:cookieSecure="true",同理为HTTPS验证相关,TRUE为采用HTTPS验证,与deployerConfigContext.xml的参数保持一致。

参数p:cookieMaxAge="-1",简单说是COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的IE窗口有效,IE关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在3600秒内,打开任意IE窗口,都不需要验证。

 

warnCookieGenerator.xml

<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

                 p:cookieSecure="true"

                 p:cookieMaxAge="-1"

                 p:cookieName="CASPRIVACY"

                 p:cookiePath="/cas" />

两个参数与上面同理。

 

3、TICKET的生命周期也可以在web.xml加这个参数实现:

<!-- Timeout for granting tickets -->

    <context-param>

        <param-name>edu.yale.its.tp.cas.grantingTimeout</param-name>

        <param-value>7200</param-value>

    </context-param>

  6 Client获取Server登陆信息

Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
AttributePrincipal principal = assertion.getPrincipal();

 

7 获取更多用户信息配置

<!-- 在这里配置获取更多的信息 --> 
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> 
<constructor-arg index="0" ref="dataSource" /> 
<constructor-arg index="1" value="select U_id as UId,U_type as UType,U_email as UEmail from t_user where U_username=?" /> 
<property name="queryAttributeMapping"> 
<map> 
<entry key="username" value="uid"/><!-- 这里必须这么写,系统会自己匹配。 --> 
</map> 
</property> 
<!-- 要获取的属性在这里配置 --> 
<property name="resultAttributeMapping"> 
<map> 
<entry key="UId" value="U_id" /> 
<entry key="UType" value="U_type" /> 
<entry key="UEmail" value="U_email" /> 
</map> 
</property> 
</bean> 

在客户端获取信息

     AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();

     String loginName = principal.getName();//获取用户名

     Map<String, Object> attributes = principal.getAttributes();

     if(attributes != null) {

         System.out.println(attributes.get("U_id"));

         System.out.println(attributes.get("U_type"));

         System.out.println(attributes.get("U_email"));

     }

 

 

CAS验证流程: 


1.用户浏览受系统保护的URL。 

2.CAS Client服务端收到请求,Filter拦截该请求,在Filter中判断该用户是否已经登陆,如果已经登陆,就直接进入系统,否则,将请求转发到CAS Server服务端的LoginURL。 

3.在LoginURL中会获取到用户的Cookie,检验用户是否已经在其他相关使用SSO的系统登陆成功。如果已经在其他的系统登陆了,则将请求转回CAS Client,并且带回一个ticket, CAS Client再次发送请求到ValidateURL。否则,系统提示用户输入ID和PASSWORD。 

4. 提交后请求到ValidateURL,CAS Server验证ticket的有效性。然后返回结果给CAS Client。如果ticket有效,则CAS Client应让该用户浏览受保护的资源。否则,重定向到登陆页面,提示用户输入ID和PASSWORD。 

5. 校验ID和Password是否匹配。如不匹配,再次要求用户输入ID和PASSWORD。否则,CAS Server记录用户登陆成功。并向浏览器回送Cookie,记录用户已经登陆成功。如果浏览器不支持Cookie,则无法实现单点登陆。 

posted on 2012-07-23 06:14  adolfmc  阅读(681)  评论(0编辑  收藏  举报