CAS Server实现单点登录(Single Sign On , 简称 SSO )

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS Server实现单点登录(Single Sign On , 简称 SSO )相关的知识,希望对你有一定的参考价值。

一、什么是单点登录。
二、利用耶鲁大学的开源项目CAS(Central Authentication Service),搭建基于JavaWeb项目的单点登录。
三、针对具体项目对CAS做二次开发以适用具体的业务。

一、什么是单点登录。
     单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
     当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。

二、利用耶鲁大学的开源项目CAS(Central Authentication Service),搭建基于JavaWeb项目的单点登录。
    2.1配置 Tomcat 使用 Https 协议
        a、由于 Client 与 CAS Server 之间的交互采用 Https 协议,因此部署 CAS Server 的服务器还需要支持 SSL 协议。如果希望 Tomcat 支持 Https,主要的工作是配置 SSL 协议,其配置过程和配置方法可以参考 Tomcat 的相关文档。不过在生成证书的过程中,会有需要用到主机名的地方,CAS 建议不要使用 IP 地址,而要使用机器名或域名。
        b、在CMD命令行利用keytool工具来创建证书,并导出和导入证书。
        keytool -genkey -keyalg RSA -alias tomcatmycas -dname "cn=localhost" -storepass 123456 -keystore d:\keyserver.keystore
        keytool -export -alias tomcatmycas -file %JAVA_HOME%\jre\lib\security\tomcatmycas.crt -storepass 123456 -keystore d:\keyserver.keystore 
        keytool -import -alias tomcatmycas -file %JAVA_HOME%\jre\lib\security\tomcatmycas.crt -keystore %JAVA_HOME%\jre\lib\security\cacerts -storepass changeit 
        c、配置conf/server.xml

        <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"  
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"  
               keystoreFile="d:\keyserver.keystore" keystorePass="123456"   
               truststoreFile="d:\jdk1.7.0_17\jre\lib\security\cacerts"  

               clientAuth="false" sslProtocol="TLS" /> 

 2.2下载cas-server-webapp-4.0.0.war,并将war包部署到tomcat中。(建议改名为cas.war,然后部署到tomcat的webapps中)。
        a、默认的cas.war包中只配置了一个用户可以登录,在具体项目中可以对认证方法做扩展。
        <bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">

            <property name="users">
                <map>
                    <entry key="casuser" value="Mellon"/>
                </map>
            </property>
        </bean>

 2.3访问https://localhost:8443/cas/ 出现默认的cas登录界面,就说明CaseServer已经成功部署了。

2.4新建两个javaweb应用appone和apptwo,根本在appone和apptwo中引入cas-client的jar包并引入相关配置。
         a、引入cas-client的jar包

                <!-- cas -->
<dependency>
   <groupId>org.jasig.cas.client</groupId>
   <artifactId>cas-client-core</artifactId>
   <version>3.2.2</version>
</dependency>

        b、配置appone和apptwo的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>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>localhost:8080</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>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS_Validation_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>
<!-- ======================== 单点登录结束 ======================== -->

    c、启动appone和apptwo两个应用。
      i1、访问:http://localhost:8080/appone/  
        appone的debug日志如下:
        --------------------------------------------------
        Jetty startup finished in 8.4 s.
        Used memory: 10.2 MB of 24.4 MB (247.5 MB maximum)
        Console available: type "help".
        --------------------------------------------------
        2016.11.13 10:28:34 DEBUG CommonUtils - serviceUrl generated: http://localhost:8080/appone/
        2016.11.13 10:28:34 DEBUG AuthenticationFilter - no ticket and no assertion found
        2016.11.13 10:28:34 DEBUG AuthenticationFilter - Constructed service url: http://localhost:8080/appone/
        2016.11.13 10:28:34 DEBUG AuthenticationFilter - redirecting to "https://localhost:8443/cas/?service=http%3A%2F%2Flocalhost%3A8080%2Fappone%2F"
     结合cas服务的debug日志可以看出当前用户没有登录,单点登录验证不通过。
   i2、同时页面会跳转到统一的登陆页面
   https://localhost:8443/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fappone%2F
    在登录页面使用cas默认的用户名和密码<entry key="casuser" value="Mellon"/>登录,登录成功后跳转到
   http://localhost:8080/appone/ 界面。
   i3、登录成功后,appone的debug日志如下:
     2016.11.13 10:30:36 DEBUG SingleSignOutHandler - Recording session for token ST-1-dYOTJF9RJOhgSsRRKHmH-cas01.example.org
    2016.11.13 10:30:36 DEBUG HashMapBackedSessionMappingStorage - Attempting to remove Session=[1v6p40uead77nldjlzonptrje]
    2016.11.13 10:30:36 DEBUG HashMapBackedSessionMappingStorage - No mapping for session found.  Ignoring.
    2016.11.13 10:30:36 DEBUG CommonUtils - serviceUrl generated: http://localhost:8080/appone/
    2016.11.13 10:30:36 DEBUG Cas20ProxyReceivingTicketValidationFilter - Attempting to validate ticket: ST-1-dYOTJF9RJOhgSsRRKHmH-cas01.example.org
    2016.11.13 10:30:36 DEBUG CommonUtils - serviceUrl generated: http://localhost:8080/appone/
    2016.11.13 10:30:36 DEBUG Cas20ServiceTicketValidator - Placing URL parameters in map.
    2016.11.13 10:30:36 DEBUG Cas20ServiceTicketValidator - Calling template URL attribute map.
    2016.11.13 10:30:36 DEBUG Cas20ServiceTicketValidator - Loading custom parameters from configuration.
    2016.11.13 10:30:36 DEBUG Cas20ServiceTicketValidator - Retrieving response from server.
    2016.11.13 10:30:37 DEBUG Cas20ServiceTicketValidator - Server response: 
    <cas:serviceResponse xmlns:cas=‘http://www.yale.edu/tp/cas‘>
<cas:authenticationSuccess>
<cas:user>casuser</cas:user>
</cas:authenticationSuccess>
    </cas:serviceResponse>
    2016.11.13 10:30:37 INFO  ProxyGrantingTicketStorageImpl - No Proxy Ticket found for [].
    2016.11.13 10:30:37 DEBUG Cas20ProxyReceivingTicketValidationFilter - Successfully authenticated user: dhpei
    2016.11.13 10:30:37 DEBUG Cas20ProxyReceivingTicketValidationFilter - Redirecting after successful ticket validation.
    2016.11.13 10:30:37 DEBUG CommonUtils - serviceUrl generated: http://localhost:8080/appone/
    i4、通过日志不难看出,用户已经单点登录成功,并通过单点登陆服务获取到了当前用户的登录名。

 三、针对具体项目对CAS做二次开发以适用具体的业务。
    从cas官网上面下载源码,结合具体业务对源码做定制改造以适用项目。

以上是关于CAS Server实现单点登录(Single Sign On , 简称 SSO )的主要内容,如果未能解决你的问题,请参考以下文章

SSO统一身份认证——CAS Server6.3.x设定退出方式(十二)

SSO统一身份认证——CAS Server6.3.x中gradlew的使用

单点登录CAS使用记:使用maven的overlay实现无侵入的改造CAS

cas单点登录怎么在服务器端获得用户信息

SSO 基于CAS实现单点登录 实例解析

简单的 CAS 实现 SSO 单点登录