CAS实现单点登录(SSO)完整步骤

教程目的:从头到尾细细道来单点登录服务器及客户端应用的每个步骤

生成证书前需要配置证书:



1、生成证书
用JDK自带的keytool工具生成证书:
D盘下创建keys文件,不需要创建hailong
命令:keytool -genkey -alias(别名)hailong -keyalg RSA -keystore D:/keys/hailong 



hailong 是证书别名
2、导出证书
命令:C:\>keytool -export -file d:/keys/hailongCRT.crt -alias hailong(别名要一致) -keystore d:/keys/hailong


.crt密钥文件

3、把证书导入到客户端JDK中。
命令:keytool -import -keystore D:\software\jdk\java1.7\jdk1.7.0_79\jre\lib\security\cacerts -file D:/keys/hailongCRT.crt -alias hailong


如果出现以下错误,把...jdk1.7.0_79\jre\lib\security下的cacerts文件删除掉,在执行。
eytool错误: java.io.IOException: Keystore was tampered with, or password was incorrect
 

4、配置服务端
下载CAS的服务端,解压,把解压后的文件中文件夹中的cas-server-webapp-3.4.8.war文件拷贝的apache-tomcat-7.0.73\webapps下,并修改文件名为:cas.war。


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


5、启动tomcat
账号 admin,密码 admin 默认账号和密码一样就行


配置host域名,用https访问 https://sso.wsria.com:8443/cas
具体链接 http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html
http://liujiawinds.iteye.com/blog/1990715

cas客户端配置
<!-- pom.xml-->
<dependency>
	<groupId>org.jasig.cas.client</groupId>
	<artifactId>cas-client-core</artifactId>
	<version>3.1.12</version>
</dependency>

<!-- ======================== 单点登录开始 ======================== -->  
    <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->  
    <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>CASFilter</filter-name>  
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
        <init-param>  
            <param-name>casServerLoginUrl</param-name>  
            <param-value>https://www.hailongsso.com:8443/cas/login</param-value>
            <!--这里的server是服务端的IP,点单登录地址链接 -->  
        </init-param>  
        <init-param>  
            <param-name>serverName</param-name>  
            <param-value>http://www.hailongsso.com:8081</param-value><span style="color:#FF0000;"> ①</span>  
            <!--登录后的客户链接地址 -->  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CASFilter</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://www.hailongsso.com:8443/cas</param-value>  
        </init-param>  
        <init-param>  
            <param-name>serverName</param-name>  
            <param-value>http://www.hailongsso.com:8081</param-value>  <span style="color:#FF0000;">②</span>  
        </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>  

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

输入客户端地址 http://www.hailongsso.com:8081/SingleSignOnExample
重定向到cas单点登录画面


拦截认证的AuthenticationFilter.java具体分析
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        //TGC Cookie传过来了,验证一下是不是其生成的,如果是,那我用TGT签发一个ST,redirect给浏览器
        //session 对应 TGC Cookie 三次进入 null 有值 有值
        // 第一次来,没有TGC Cookie,客户端输入账号密码后去cas才能有
        final HttpSession session = request.getSession(false);
        //assertion 对应ST 三次进入 null null  有值
        // 第二次来,没有ST,第三次进来去CAS申请后才有值。
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;

        if (assertion != null) {
            filterChain.doFilter(request, response);
            return;
        }

        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
        final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            filterChain.doFilter(request, response);
            return;
        }

        final String modifiedServiceUrl;

        log.debug("no ticket and no assertion found");
        if (this.gateway) {
            log.debug("setting gateway attribute in session");
            modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
        } else {
            modifiedServiceUrl = serviceUrl;
        }

        if (log.isDebugEnabled()) {
            log.debug("Constructed service url: " + modifiedServiceUrl);
        }

        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

        if (log.isDebugEnabled()) {
            log.debug("redirecting to \"" + urlToRedirectTo + "\"");
        }

        response.sendRedirect(urlToRedirectTo);
    }

对于cas客户端的认证和拦截配置到具体的业务服务项目里,对认证拦截可以有自定义的规则,重写或替换AuthenticationFilter.java等类。

修改CAS的认证逻辑
CAS默认的逻辑是用户名和密码一致就可以登陆,现在需要把原web系统的用户名和密码校验挪到CAS中。这里假设原先web系统中有一张sys_user表存储了用户名和MD5散列后的密码。

打开cas/WEB-INF/deployerConfigContext.xml
注释掉SimpleTestUsernamePasswordAuthenticationHandler这个Handler,并添加
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
	<property ref="dataSource" name="dataSource"></property>
	<property name="sql" value="select t.encrypted_user_password from sys_user t where t.user_name=?"></property>                     
	<property ref="MD5PasswordEncoder" name="passwordEncoder"></property>
</bean>


在文件末尾之前加入数据库的链接:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>jdbc:oracle:thin:@yourIP:1521:yourOracleInstanceId</value>
        </property>
        <property name="username">
            <value>yourName</value>
        </property>
        <property name="password">
            <value>yourPassword</value>
        </property>
    </bean>
    <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
        <constructor-arg index="0">
            <value>MD5</value>
        </constructor-arg>
    </bean>

cas加入jdbc支持
复制cas-server-3.5.2\modules\cas-server-support-jdbc-3.5.2.jar和oracle驱动(这里采用oracle数据)的ojdbc14.jar或者classes12.jar放到cas/WEB-INF/lib目录下。

cas-server-webapp源码打包cas-server-webapp.war修改成cas.war
就是以上所说服务的war包:



猜你喜欢

转载自572327713.iteye.com/blog/2356545