SSO - CAS 4.0 入门实战

资源准备

  • cas-server-webapp-4.0.0.war
  • c3p0-0.9.1.2.jar (版本不定,可用即可)
  • mysql-connector-java-5.1.29.jar (版本不定,可用即可)
  • cas-server-support-jdbc-4.0.0.jar
  • cas-client-core-3.3.3.jar
  • jcl-over-slf4j-1.7.7.jar
  • jul-to-slf4j-1.7.7.jar
  • log4j-1.2.16.jar、
  • log4j-over-slf4j-1.7.7.jar
  • logback-classic-1.1.2.jar
  • logback-core-1.1.2.jar
  • slf4j-api-1.7.7.jar

(加粗为必备资源)

基本配置

将下载好的cas-server-webapp-4.0.0.war重命名为cas.war并放到tomcat(默认版本为7,不建议使用更低版本的)的webapps目录下。启动tomcat,解压。然后修改cas的配置。

1. CAS的HTTP模式与HTTPS设置
  • /cas/WEB-INF/deployerConfigContext.xml

增加p:requireSecure="false"属性

<bean id="proxyAuthenticationHandler"
          class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
          p:httpClient-ref="httpClient" p:requireSecure="false"/>
  • /cas/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml

修改p:cookieSecure="true"p:cookieSecure="false".

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
        p:cookieSecure="false"
        p:cookieMaxAge="-1"
        p:cookieName="CASTGC"
        p:cookiePath="/cas" />
  • /cas/WEB-INF/spring-configuration/warnCookieGenerator.xml

修改p:cookieSecure="true"p:cookieSecure="false".

<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
        p:cookieSecure="false"
        p:cookieMaxAge="-1"
        p:cookieName="CASPRIVACY"
        p:cookiePath="/cas" />

修改好上诉配置之后重启tomcat,访问localhost:8080/cas 可以进入CAS的登录页面,登录用户名密码为casuser/Mellon。可以从上面的deployerConfigContext.xml中找到以下配置,即默认用户名密码配置。

<bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean>
  • 示例页面

(我这里配置了tomcat端口为80)

login

login-success

2. 配置数据库来验证用户

将列出的资源的c3p0-0.9.1.2.jarmysql-connector-java-5.1.29.jarcas-server-support-jdbc-4.0.0.jar放入caslib目录下。修改配置,并重启tomcat。
* deployerConfigContext.xml

<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
        <constructor-arg>
            <map>
                <!--
                   | IMPORTANT
                   | Every handler requires a unique name.
                   | If more than one instance of the same handler class is configured, you must explicitly
                   | set its name to something other than its default name (typically the simple class name).
                   -->
                <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
                <entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver" />
                <!-- <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> -->
            </map>
        </constructor-arg>

        .......

    </bean>

    ......

    <!-- 
    <bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean>
    -->
    <!-- Define the DB Connection -->
    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource"
        p:driverClass="com.mysql.jdbc.Driver"
        p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"
        p:user="root"
        p:password="root" />

    <!-- Define the encode method-->
    <bean id="passwordEncoder"
        class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"
        c:encodingAlgorithm="MD5"
        p:characterEncoding="UTF-8" />

    <bean id="dbAuthHandler"
        class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
        p:dataSource-ref="dataSource"
        p:sql="select password from test.user_data where name=? and used=1"
        p:passwordEncoder-ref="passwordEncoder"/>

(注意:其中的jdbcUrl为你的数据库的url,user/password同理,记得修改,密码为:MD5 32位 小写。另外sql也可以根据自身习惯修改,数据库、表、数据记得创建。)
我这里添加了一条数据 casuser/Mellon(md5 32位 小写),重启之后继续访问localhost:8080/cas,输入用户名密码,登陆成功!


keytool 生成https访问证书

学习链接 - java keytool 证书工具使用小结,详细命令参数可见该资料

1. 生成证书

注:命名及位置自己定义

keytool -genkey -alias michaelkey -keyalg RSA -keysize 1024 -keypass michaelpwd -validity 365 -keystore E:\sso\michael.keystore -storepass michaelpwd2

创建证书

2. 查看证书
  • -v 命令
keytool -list  -v -keystore E:\sso\michael.keystore -storepass michaelpwd2

-v 命令查看证书

  • -rfc 命令
keytool -list -rfc -keystore E:\sso\michael.keystore -storepass michaelpwd2

-rfc 命令查看证书

3. 导出证书
  • 导出证书
keytool -export -alias michaelkey -keystore E:\sso\michael.keystore -file E:\sso\michael.crt -storepass michaelpwd2

导出证书

  • 查看导出的证书
keytool -printcert -file E:\sso\michael.crt

查看导出的证书

证书生成目录


将证书导入到JAVA证书库

(注:这是使用一个新生成的证书:证书信息中名字与姓氏这一项必须填写你的访问的域名或者主机名,keypass 和 storepass 两个密码要一致,否则下面tomcat 配置https 访问失败;)

// 可以将生成的 crt 文件转换成 cer 文件
// 双击 --> 详细信息 --> 复制到文件 --> 选择导出文件格式 base64/二进制 (均为 .cer 文件)--> 命名 --> 完成

1. cmd 命令进入 dos --> cd C:\JDK\jre\lib\security
2. 输入命令行: keytool -import -alias ssodemo -keystore cacerts -file E:\sso\ssodemo.crt -trustcacerts
3. 输入密码: changeit (java 默认)


以后更新时,先删除原来的证书,然后导入新的证书 
keytool -list -keystore cacerts -alias ssodemo
keytool -delete -alias ssodemo -keystore cacerts 
keytool -import -alias ssodemo -file ssodemo.crt -keystore cacerts -trustcacerts

java证书安装


tomcat 配置 https

<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" />
-->

修改为:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" 
           keystoreFile="E:/sso/ssodemo.keystore" keystorePass="michaelpwd"/>

启动tomcat,成功后访问tomcat,https://localhost:8443/,会提示证书错误或不受信任,没有关系,选择继续访问。看到tomcat的默认页面说明配置成功。

火狐浏览器  https访问tomcat

tomcat 默认页面


多台 tomcat 模拟单点登录跳转

(注:至少两台 = = 不然怎么跳)
* 1. host 设置跳转域名

这里我们进行单机模拟实验,毕竟没有资源(你要是有资源,那你需要每台机器上面都有安装证书)。

127.0.0.1 cas.sso.com
127.0.0.1 app1.sso.com
...
  • 2. 设置 tomcat

准备两台tomcat,重命名为:tomcat-cas、tomcat-app。tomcat-cas 按照上面的步骤:导入cas.war,修改配置,生成证书,导入证书到JAVA,配置https;访问https://cas.sso.com:8443/能够成功访问到cas登录页面,则OK。

下面来配置一下tomcat-app (能启动并访问,则OK。):

<!-- 修改 /conf/server.xml  修改端口号,使其能够正常启动 -->
<Server port="18005" shutdown="SHUTDOWN">

<Connector port="18080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="18443" />

<Connector port="18009" protocol="AJP/1.3" redirectPort="18443" />
  • 使用tomcat自带的example项目进行模拟实验

1)添加cas client jar 包
找到 /WEB-INF/lib,添加 cas-client-core-3.3.3.jar,另外需要引入 log4j 的jar包,以支持 client 的日志,不然会报错,jcl-over-slf4j-1.7.7.jar、jul-to-slf4j-1.7.7.jar、log4j-1.2.16.jar、log4j-over-slf4j-1.7.7.jar、logback-classic-1.1.2.jar、logback-core-1.1.2.jar、slf4j-api-1.7.7.jar。版本自定,能用就行,咱们也只是做实验。

2)添加 filter
修改 web.xml 文件,添加 cas 访问需要的 filter,

<!-- ======================== 单点登录开始 ======================== -->   
<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
<filter>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>

<!-- 该过滤器负责用户的认证工作,必须启用它 -->
<filter>
  <filter-name>CAS Authentication Filter</filter-name>
  <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
  <init-param>
    <param-name>casServerLoginUrl</param-name>
    <param-value>https://cas.sso.com:8443/cas/login</param-value>
  </init-param>
  <init-param>
    <param-name>serverName</param-name>
    <param-value>http://app1.sso.com:18080</param-value>
  </init-param>
</filter>

<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<filter>
    <filter-name>CAS Validation Filter</filter-name>
    <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
    <init-param>
        <param-name>casServerUrlPrefix</param-name>
        <param-value>https://cas.sso.com:8443/cas</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://app1.sso.com:18080</param-value>
    </init-param>
    <init-param>
        <param-name>redirectAfterValidation</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<!-- 该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->
<filter>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>

<!-- 该过滤器使得开发者可以通过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 Single Sign Out Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Authentication Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Validation Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Assertion Thread Local Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

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


<!-- 所有 filter 结束后添加 logout 的 listener  -->
<!-- 用于单点退出 -->  
<listener>  
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
</listener>  

详细配置说明,请看官方文档(全英文)

启动 tomcat-cas 和 tomcat-app1 ,访问链接http://app1.sso.com:18080/examples/servlets/servlet/HelloWorldExample,然后会跳转到 cas 的登录页面,输入用户名密码,跳转,成功,祝贺,普天同庆。

cas-login

可以看到链接中附带了service=xxxx, 后面的地址就是http://app1.sso.com:18080/examples/servlets/servlet/HelloWorldExample,设置一下字符集即可。

这里写图片描述

可以看到上图,附带了jsessionid。

至此,成功,但是还需要在实际开发中测试一下。


获取登陆成功用户名

修改example 项目的 HelloWorldExample.java,并重新编译成.class文件,

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

import javax.servlet.*;
import javax.servlet.http.*;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;

/**
 * CAS simple Servlet
 *
 * @author <a href="http://www.micmiu.com">Michael Sun</a>
 */

public class HelloWorldExample extends HttpServlet {

    private static final long serialVersionUID = -6593274907821061823L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",
                request.getLocale());
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.println("<head>");

        String title = rb.getString("helloworld.title");

        out.println("<title>" + title + "</title>");
        out.println("</head>");
        out.println("<body bgcolor=\"white\">");

        out.println("<a href=\"../helloworld.html\">");
        out.println("<img src=\"../images/code.gif\" height=24 "
                + "width=24 align=right border=0 alt=\"view code\"></a>");
        out.println("<a href=\"../index.html\">");
        out.println("<img src=\"../images/return.gif\" height=24 "
                + "width=24 align=right border=0 alt=\"return\"></a>");
        out.println("<h1>" + title + "</h1>");

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

        if (null != assertion) {
            // 有效的开始时间
            out.println(" Log | ValidFromDate =:"
                    + assertion.getValidFromDate() + "<br>");
            // 有效的结束时间
            out.println(" Log | ValidUntilDate =:"
                    + assertion.getValidUntilDate() + "<br>");
            Map<String, Object> attMap = assertion.getAttributes();
            out.println(" Log | getAttributes Map size = " + attMap.size()
                    + "<br>");
            for (Entry<String, Object> entry : attMap.entrySet()) {
                out.println("     | " + entry.getKey() + "=:"
                        + entry.getValue() + "<br>");
            }
            AttributePrincipal principal = assertion.getPrincipal();

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

            String username = null;
            out.print(" Log | UserName:");
            if (null != principal) {
                username = principal.getName();
                out.println("<span style='color:red;'>" + username
                        + "</span><br>");
            }

        }

        out.println("</body>");
        out.println("</html>");
    }
}

启动tomcat,访问,如图:

这里写图片描述

可以分析出 CAS 登录成功后的一些结构:

Session
    || - Attribute
        || - Assertion 
            || - ValidFromDate
               - ValidUntilDate
               - AttributePrincipal 
                   || - Name

可以自行查阅资料,了解更多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值