cas单点登录服务部署及SpringBoot集成客户端

服务部署:

环境准备:

  JDK: 1.8

  cas-overlay-template :5.3.x https://github.com/apereo/cas-overlay-template

  maven:3.6.3

   导入IDEA,此时会去下载一个依赖:cas-server-webapp-tomcat-5.3.14.war ,具体的版本可以根据IDEA的提示去下载。可以通过以下地址去下载,下载完拷贝到maven仓库就行 :https://repo1.maven.org/maven2/org/apereo/cas/cas-server-webapp-tomcat/5.3.14/

  然后再IDEA中执行 mvn clean package 进行打包,打完包后会得到一个  cas.war。把这个war包放到tomcat的webapp目录下,启动tomcat即可。

  我这边打包遇到个报错:

   删除maven仓库repository文件夹下org/apache/maven下的文件夹,然后重新 maven reimport一下,再重新mvn clean package。

HTTP支持:

  这个版本默认是只支撑https请求的(https访问需要配置证书,百度一下),当我们客户端集成shiro,cas-client要整合的时候,发现跳转登录会报不安全之类的信息。这个时候需要我们开启http支持

  到tomcat的webapps目录下找到  cas/WEB-INFclassesapplication.properties。在cas.authn.accept.users=casuser::Mellon的下面添加如下两行配置。

cas.authn.accept.users=casuser::Mellon

cas.tgc.secure=false
cas.serviceRegistry.initFromJson=true

  WEB-INFclassesservicesHTTPSandIMAPS-10000001.json 中添加http的支持。

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "^(https|http|imaps)://.*",
  "name" : "HTTPS and IMAPS",
  "id" : 10000001,
  "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
  "evaluationOrder" : 10000
}

   然后启动服务。按照application.properties提供的账号密码 casuser::Mellon 进行登录即可:

CAS连接数据库:

1.在cas-overlay-template项目的pom中添加相关依赖:

<mysql.driver.version>5.1.46</mysql.driver.version>

<!--数据库认证相关 start-->
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-support-jdbc</artifactId>
    <version>${cas.version}</version>
</dependency>
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-support-jdbc-drivers</artifactId>
    <version>${cas.version}</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.driver.version}</version>
</dependency>
<!--数据库认证相关 end-->

2.然后打包,丢到tomcat中启动。然后找到 webapps目录下找到  cas/WEB-INFclassesapplication.properties 。将原来的用户配置注释掉。添加如下信息:

#cas.authn.accept.users=casuser::Mellon
cas.authn.jdbc.query[0].url=jdbc:mysql://192.168.1.101:3306/spring-orm1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false        
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=123456
cas.authn.jdbc.query[0].sql=select * from user where username=?
cas.authn.jdbc.query[0].fieldPassword=password
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver

3.在数据库中添加对应表。然后重启tomcat。就可以进行数据库的用户认证登录。

Springboot 整合cas-client:

第三方提供的依赖整合:

1.添加依赖:

<!-- CAS -->
<dependency>
  <groupId>net.unicon.cas</groupId>
  <artifactId>cas-client-autoconfig-support</artifactId>
  <version>1.5.0-GA</version>
</dependency>

2.修改 application.properties 配置文件:

## CAS 配置
cas.validation-type = CAS
#cas服务地址
cas.server-url-prefix = http://localhost:8080/cas
#cas服务登录地址
cas.server-login-url = http://localhost:8080/cas/login
#cas服务登出地址
cas-server-logout-url = http://localhost:8080/cas/logout
#本地服务地址
cas.client-host-url = http://localhost:8888

3.启用服务注解:

@SpringBootApplication
@EnableCasClient//开启cas-client
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

  通过上面的三个步骤就可以完成client的自动整合。

手动整合:

1.添加依赖:

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

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
</dependency>

2.修改 application.properties 配置:

## CAS 配置
spring.cas.sign-out-filters=/logout
spring.cas.auth-filters=/*
spring.cas.validate-filters=/* 
spring.cas.request-wrapper-filters=/*
spring.cas.assertion-filters=/*
spring.cas.cas-server-login-url=http://localhost:8080/cas/login
spring.cas.cas-server-url-prefix=http://localhost:8080/cas
spring.cas.redirect-after-validation=true
spring.cas.use-session=true
spring.cas.server-name=http://localhost:8888

3.添加cas读取配置文件的相关配置类:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
// 获取配置文件中属性值
@Component
@ConfigurationProperties(prefix = "spring.cas")
public class SpringCasAutoConfig {

    private static final String separator = ",";

    private String validateFilters;

    private String signOutFilters;

    private String authFilters;

    private String assertionFilters;

    private String requestWrapperFilters;

    private String casServerUrlPrefix;

    private String casServerLoginUrl;

    private String serverName;

    private boolean useSession = true;

    private boolean redirectAfterValidation = true;

   // 省略 get / set

}

4.添加 cas 配置整合类:

package com.example.demo;

import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.AssertionThreadLocalFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

@Configuration
public class CasConfig {

    // 是否启用CAS
    private static boolean casEnabled  = true;

    @Autowired
    private SpringCasAutoConfig autoConfig;

    /**
     * 用于实现单点登出功能
     */
    @Bean
    public ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> singleSignOutHttpSessionListener() {
        ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> listener = new ServletListenerRegistrationBean<>();
        listener.setEnabled(casEnabled);
        listener.setListener(new SingleSignOutHttpSessionListener());
        listener.setOrder(1);
        return listener;
    }

    /**
     * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean logOutFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        LogoutFilter logoutFilter = new LogoutFilter(autoConfig.getCasServerUrlPrefix() + "/logout?service=" + autoConfig.getServerName(), new SecurityContextLogoutHandler());
        filterRegistration.setFilter(logoutFilter);
        filterRegistration.setEnabled(casEnabled);
        if (autoConfig.getSignOutFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getSignOutFilters());
        else
            filterRegistration.addUrlPatterns("/logout");
        filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix());
        filterRegistration.addInitParameter("serverName", autoConfig.getServerName());
        filterRegistration.setOrder(2);
        return filterRegistration;
    }

    /**
     * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean singleSignOutFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new SingleSignOutFilter());
        filterRegistration.setEnabled(casEnabled);
        if (autoConfig.getSignOutFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getSignOutFilters());
        else
            filterRegistration.addUrlPatterns("/*");
        filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix());
        filterRegistration.addInitParameter("serverName", autoConfig.getServerName());
        filterRegistration.setOrder(3);
        return filterRegistration;
    }

    /**
     * 该过滤器负责用户的认证工作
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean authenticationFilter() {

        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new AuthenticationFilter());
        filterRegistration.setEnabled(casEnabled);
        if (autoConfig.getAuthFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getAuthFilters());
        else
            filterRegistration.addUrlPatterns("/*");
        // casServerLoginUrl:cas服务的登陆url
        filterRegistration.addInitParameter("casServerLoginUrl", autoConfig.getCasServerLoginUrl());
        // 本项目登录ip+port
        filterRegistration.addInitParameter("serverName", autoConfig.getServerName());
        filterRegistration.addInitParameter("useSession", autoConfig.isUseSession() ? "true" : "false");
        filterRegistration.addInitParameter("redirectAfterValidation", autoConfig.isRedirectAfterValidation() ? "true" : "false");
        filterRegistration.setOrder(4);
        return filterRegistration;
    }

    /**
     * 该过滤器负责对Ticket的校验工作
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        Cas20ProxyReceivingTicketValidationFilter cas20ProxyReceivingTicketValidationFilter = new Cas20ProxyReceivingTicketValidationFilter();
        cas20ProxyReceivingTicketValidationFilter.setServerName(autoConfig.getServerName());
        filterRegistration.setFilter(cas20ProxyReceivingTicketValidationFilter);
        filterRegistration.setEnabled(casEnabled);
        if (autoConfig.getValidateFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getValidateFilters());
        else
            filterRegistration.addUrlPatterns("/*");
        filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix());
        filterRegistration.addInitParameter("serverName", autoConfig.getServerName());
        filterRegistration.setOrder(5);
        return filterRegistration;
    }


    /**
     * 该过滤器对HttpServletRequest请求包装,
     * 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new HttpServletRequestWrapperFilter());
        filterRegistration.setEnabled(true);
        if (autoConfig.getRequestWrapperFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getRequestWrapperFilters());
        else
            filterRegistration.addUrlPatterns("/login");
        filterRegistration.setOrder(6);
        return filterRegistration;
    }

    /**
     * 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
     * 比如AssertionHolder.getAssertion().getPrincipal().getName()。
     * 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean assertionThreadLocalFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new AssertionThreadLocalFilter());
        filterRegistration.setEnabled(true);
        if (autoConfig.getAssertionFilters().size() > 0)
            filterRegistration.setUrlPatterns(autoConfig.getAssertionFilters());
        else
            filterRegistration.addUrlPatterns("/*");
        filterRegistration.setOrder(7);
        return filterRegistration;
    }

}

  启动项目进行测试即可。

原文地址:https://www.cnblogs.com/wuzhenzhao/p/12624882.html