CAS单点登陆实现案例

咱们先按套路来,上点客套的:html

一、CAS的基本工做原理java

二、CAS的时序图以下mysql

三、好吧好吧,下面废话不说,我直接来干货web

A、hosts文件的配置,无关紧要,可是按照我以前看别人的博客,这个仍是方便安全证书的生成的算法

    C:\Windows\System32\drivers\etc\hosts 文件中添加三条spring

        127.0.0.1 demo.tch.comsql

        127.0.0.1 app1.tch.com数据库

        127.0.0.1 app2.tch.comapache

        demo.tch.com =>>对应部署cas server的tomcat,这个虚拟域名还用于证书生成
        app1.tch.com =>> 对应部署app1的tomcat
        app2.tch.com =>>对应部署app2的tomcat浏览器

B、生成安全证书

C:\Users\yang>keytool -genkey -alias ssodemo1 -keyalg RSA -keysize 1024 -keypass 123456 -keystore 
 f:\sso\ssodemo.keystore -storepass 123456

keypass 和 storepass 两个密码要一致,不然下面tomcat 配置https 访问失败;

而后咱们将证书导出:

C:\Users\yang>keytool -export -alias ssodemo1 -keystore f:\sso\ssodemo.keystore -file 
 f:\sso\ssodemo.crt -storepass 123456

 

有关keytool工具的详细运用见:http://www.micmiu.com/lang/java/keytool-start-guide/

C、进行服务端的配置,这个比较重要,并且也是浪费我时间最多的一个地方,由于网上的博客不少东西写的都不对,我也不知道他们是怎么实现的,我把个人弯路show给你看:

服务端tomcat配置文件 conf/server.xml文件进行以下修改:

<Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" />

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keystoreFile="F:/Study/Java/Projects/SSO/Demo/keys/ssodemo.keystore" keystorePass="123456"
               clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"/>
	
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

 <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>

 <Host name="demo.tch.com"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

对以上代码进行截图,而后对以上配置进行分析

CAS-Server下载地址:http://www.jasig.org/cas/download

本文以cas-server-3.4.11-release.zip为例,解压提取cas-server-3.4.11/modules/cas-server-webapp-3.4.11.war文件,把改文件copy到 G:\sso\tomcat-cas\webapps\目下,并重命名为:cas.war.

启动tomcat-cas,在浏览器地址栏输入:https://demo.tch.com:8443/cas/login ,回车

写这篇日志的时候,不少东西我都已经修改了,可是以上表示成功了,真实的图片容我给你盗个图来

CAS-server的默认验证规则:只要用户名和密码相同就认证经过(仅仅用于测试,生成环境须要根据实际状况修改),输入admin/admin 点击登陆,就能够看到登陆成功的页面:

看到上述页面表示CAS-Server已经部署成功。

上面的初体验仅仅是简单的身份验证,实际应用中确定是要读取数据库的数据,下面咱们来进一步配置CAS服务器怎么读取数据库的信息进行身份验证。 首先打开

cas/WEB-INF/deployerConfigContext.xml

注释掉:SimpleTestUsernamePasswordAuthenticationHandler这个验证Handler,这个是比较简单的,只是判断用户名和密码相同便可经过,这个确定不能在实际应用中使用,弃用!紧接着添加以下代码

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

在文件的末尾以前加入以下代码:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
   <property name="url"><value>jdbc:mysql:///wsriademo</value></property>
   <property name="username"><value>root</value></property>
   <property name="password"><value>root</value></property>
</bean>
 
<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
    <constructor-arg index="0">
        <value>MD5</value>
    </constructor-arg>
</bean>

复制cas-server-3.4.3.1\modules\cas-server-support-jdbc-3.4.3.1.jar和mysql/Oracle驱动jar包到tomcat/webapp/cas/WEB-INF/lib目录

  • QueryDatabaseAuthenticationHandler,是cas-server-support-jdbc提供的查询接口其中一个,QueryDatabaseAuthenticationHandler是经过配置一个 SQL 语句查出密码,与所给密码匹配

  • dataSource,我就不用解释了吧,就是使用JDBC查询时的数据源

  • sql,语句就是查询哪一张表,本例根据t_admin_user表的login_name字段查询密码,CAS会匹配用户输入的密码,若是匹配则经过

  • passwordEncoder,这个就算是本身加的盐巴了,意思很明显就是处理密码的加密,看你的应用中数据库保存的是明码仍是加密过的,好比本例是使用MD5加密的,因此配置了MD5PasswordEncoder这个Handler,cas内置了MD5的功能因此只须要配置一下就能够了;若是在实际应用中使用的是公司本身的加密算法那么就须要本身写一个Handler来处理密码,实现方式也比较简单,建立一个类继承org.jasig.cas.authentication.handler.PasswordEncoder而后在encode方法中加密用户输入的密码而后返回便可.

而后修改cas/WEB-INF/cas.properties文件,修改以下两行,具体含义我就很少说了

server.name=http://demo.tch.com:8080
server.prefix=${server.name}/cas

D、客户端的配置

导入jar包

<dependency>
    <groupid>org.jasig.cas.client</groupid>
    <artifactid>cas-client-core</artifactid>
    <version>3.1.12</version>
</dependency>

修改你客户端中的web.xml文件进行修改,添加filter

<!-- sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆-->
    <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>http://demo.tch.com:8080/cas/login</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://app1.tch.com:18080</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CASFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--该过滤器负责对Ticket的校验工做,必须启用它-->
    <filter>
        <filter-name>CASValidationFilter</filter-name>
        <filter-class>
            org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>http://demo.tch.com:8080/cas</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://app1.tch.com:18080</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CASValidationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--
                            该过滤器负责实现HttpServletRequest请求的包裹,
                            好比容许开发者经过HttpServletRequest的getRemoteUser()方法得到SSO登陆用户的登陆名,可选配置。
                    -->
    <filter>
        <filter-name>CASHttpServletRequest WrapperFilter</filter-name>
        <filter-class>
            org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CASHttpServletRequest WrapperFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--
                    该过滤器使得开发者能够经过org.jasig.cas.client.util.AssertionHolder来获取用户的登陆名。
                    好比AssertionHolder.getAssertion().getPrincipal().getName()。
                    -->
    <filter>
        <filter-name>CASAssertion Thread LocalFilter</filter-name>
        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CASAssertion Thread LocalFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

注*此时app1的http端口号为1880,经过拦截来跳转到cas服务,cas服务经过了用户名和密码以后携带cas生成的tickets回到客户端。

在app1系统的intercepter拦截器中,根据AssertionHolder.getAssertion().getPrincipal().getName()取得当前登陆用户的用户名,来从本身的系统数据库中取得用户信息。同时在单独登陆系统时,也不会受到cas系统干扰。

User user = (User) session.getAttribute("admin");
        if(null == user){
            if(null != AssertionHolder.getAssertion()){
                String userName = AssertionHolder.getAssertion().getPrincipal().getName();
                if(null != userName || !"".equals(userName)){
                    user = userService.queryUserByuserName(userName);
                }
            }
        }

E、预期流程:打开app1 url —->跳转cas server验证 —->显示app1的应用 —->打开app2 url —->显示app2应用 —->注销cas server —->打开app1/app2url —->从新跳转到cas server验证.

F、

CAS服务端(cas-server)的界面只能在测试的时候用一下,真正系统上线确定须要定制开发本身的页面,就像网易CSDN的统一认证平台同样,全部子系统的认证都经过此平台来转接,你们能够根据他们的页面本身定制出适合所属应用或者公司的界面;简单介绍一下吧,复制 cas\WEB-INF\view\jsp\default\ui的一些JSP文件,每个文件的用途文件名已经区分了,本身修改了替换一下就能够了。 例如:

  • 登陆界面:casLoginView.jsp
  • 登陆成功:casGenericSuccess.jsp
  • 登出界面:casLogoutView.jsp

 

 

参考资料:http://www.2cto.com/os/201402/281465.html

                http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html

相关文章
相关标签/搜索