2、cas4.0 单点登录 之 cas-client

cas4.0 单点登录 之 cas-client

cas4.0 单点登录 之 https证书 已经做好了证书的准备工作,现在结合cas-server来配置单点登录;

一、安装cas服务端(cas-server)

cas服务端是一个war包,这里只做体验单点登录,cas-server下载点这里cas-server-webapp-4.0.0.war,将war包放tomcat下运行即可,运行cas-server的tomcat的要开启SSL支持,上面文章也有说明,server.xml需要如下配置:

<Connector port="8443" protocol="HTTP/1.1" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="d:/cas/keystore" keystorePass="caspass"/>

cas-server的定制开发后面文章再讲。

二、cas客户端配置(cas-client)

1、web.xml方式配置

写了个简单客户端配置,源码cas_client_test_demo.zip

a) pom.xml

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.0.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.jasig.cas.client</groupId>
        <artifactId>cas-client-core</artifactId>
        <version>3.4.1</version>
    </dependency>
</dependencies>

b) web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">


    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- ****************** 单点登录开始 ********************-->
    <!-- 用于实现单点登出功能 可选 -->
    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
    </listener>

    <!-- 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前 可选 -->
    <filter>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://cas.castest.com:8443/cas/</param-value>
        </init-param>
    </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>
            <!--casServerLoginUrl:cas服务的登陆url -->
            <param-name>casServerLoginUrl</param-name>
            <param-value>https://cas.castest.com:8443/cas/login</param-value>
        </init-param>
        <init-param>
            <!--serverName:本项目的ip+port -->
            <param-name>serverName</param-name>
            <param-value>http://www.zrk1000.com:8081</param-value>
        </init-param>
        <init-param>
            <param-name>useSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>redirectAfterValidation</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CASFilter</filter-name>
        <url-pattern>/test</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://cas.castest.com:8443/cas/</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://www.zrk1000.com:8081</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CAS Validation Filter</filter-name>
        <!-- 对test做登录拦截-->
        <url-pattern>/test</url-pattern>
    </filter-mapping>

    <!-- 该过滤器对HttpServletRequest请求包装, 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名,可选 -->

    <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()。 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息 -->
    <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>
    <!-- ****************** 单点登录结束 ********************-->


</web-app>

**注意:casServerLoginUrl和casServerUrlPrefix必须使用域名,且域名要和证书中的“名字与姓氏”完全相同,没有域名的可以配置本地hosts做映射
我的hosts配置是这样:
2、cas4.0 单点登录 之 cas-client_第1张图片
这里用的一台机器,两个域名均指向了本机,有域名的童鞋及土豪无视

c) spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">

    <mvc:annotation-driven />
    <context:component-scan base-package="com.castest.*" />

</beans>

d) 测试Controller

package com.castest.cas;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {


    @RequestMapping("/test")
    @ResponseBody
    public String index(HttpServletRequest request, HttpServletResponse response) {
        String result = "execute test method</br>";
        result +=   "sessionId : "+request.getSession().getId()  +"</br>";
        result +=   "request.getRemoteUser() : " + request.getRemoteUser()     +"</br>";
        result +=   "request.getUserPrincipal() : " + request.getUserPrincipal()  +"</br>";
        return result;
    }

    @RequestMapping(value={"/","/index"})
    @ResponseBody
    public String error(HttpServletRequest request, HttpServletResponse response) {
        String result = "execute index method</br>";
        result +=   "sessionId : "+request.getSession().getId()  +"</br>";
        result +=   "request.getRemoteUser() : " + request.getRemoteUser()     +"</br>";
        result +=   "request.getUserPrincipal() : " + request.getUserPrincipal()  +"</br>";
        return result;
    }


}

e) 测试结果

1、
请求:http://www.zrk1000.com:8081/cas_client/index

2、cas4.0 单点登录 之 cas-client_第2张图片

结果:web.xml中只对/test做登陆拦截,/index未跳转登陆正常

2、
请求:http://www.zrk1000.com:8081/cas_client/test
–> https://cas.castest.com:8443/cas/login?service=http%3A%2F%2Fwww.zrk1000.com%3A8081%2Fcas_client%2Ftest

被拦截重定向到了cas-server的默认登陆页面;server参数为原请求URL,认证成功后会重定向到此地址。
cas默认用户名为:casuser 默认密码:Mellon (cas-server的WEB-INF/deployerConfigContext.xml中)
–>http://www.zrk1000.com:8081/cas_client/test

2、cas4.0 单点登录 之 cas-client_第3张图片

结果:web.xml中只对/test做登陆拦截,/index不跳转;登陆正常,并且登陆成功后获取到了用户信息

2、基于spring boot配置

使用spring boot创建web项目没有web.xml,只能使用java代码的方式添加filter和listener,原理和web.xml一样,这里做了简单的配置,源码cas_client_boot_test_demo.zip,其中cas_client_boot_demo.war依赖cas_client_boot.jar。
使用spring boot的项目cas这样配置:

spring.mvc.view.prefix=/WEB-INF/page
spring.mvc.view.suffix=.jsp
server.session.cookie.domain=.castest.com
server.session.cookie.path=/
server.port=8081

spring.cas.sign-out-filters=/* spring.cas.auth-filters=/test spring.cas.validate-filters=/test spring.cas.request-wrapper-filters=/* spring.cas.assertion-filters=/* spring.cas.cas-server-login-url=https://cas.castest.com:8443/cas/login spring.cas.cas-server-url-prefix=https://cas.castest.com:8443/cas/ spring.cas.redirect-after-validation=true spring.cas.use-session=true spring.cas.server-name=http://www.zrk1000.com:8081

3 常见错误

1、javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching cas.castest.com found
原因:cas客户端使用的证书库中未找到相应的域名,也就是说客户端JDK导入的证书的域名与客户端访问的cas-server域名不同
解决:检查JDK证书库中证书域名是否和cas-server的域名相同,保持一致即可

2、javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
原因:证书未导入等原因
解决:往jdk导入证书,使用IDE的小伙伴也要检查工具使用的jdk是否和你导入证书的jdk是同一个

你可能感兴趣的:(单点登录,cas-client,cas4-0,cas-boot)