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-INF\classes\application.properties。在cas.authn.accept.users=casuser::Mellon的下面添加如下兩行配置。

cas.authn.accept.users=casuser::Mellon cas.tgc.secure=false cas.serviceRegistry.initFromJson=true

  WEB-INF\classes\services\HTTPSandIMAPS-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-INF\classes\application.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;
    }

}

  啟動項目進行測試即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM