CAS單點登錄:集成客戶端,自定義client-starter(二)


0.說明

本系列文章只根據自己的需要做部分定制,完整的教程見:https://blog.csdn.net/qq_34021712/category_9278675.html

有興趣的可以一起研究。

1.服務端

1.1.Service配置

客戶端接入 CAS 首先需要在服務端進行注冊,否則客戶端訪問將提示“未認證授權的服務”警告:

簡單需求:對所有https和http請求的service進行允許認證。

在resources/services下新建文件fdzang-1000.json,這個文件是我根據cas源代碼HTTPSandIMAPS-10000001.json更改的。路徑:cas\WEB-INF\classes\services

{
  "@class": "org.apereo.cas.services.RegexRegisteredService",
  "serviceId": "^(https|imaps|http)://.*",
  "name": "fdzang",
  "id": 1000,
  "description": "CAS-SSO 登入",
  "evaluationOrder": 10000
}

注意:

services目錄中可包含多個 JSON 文件,其命名必須:${name}-${id}.json,id必須為json文件中內容id一致

對其中屬性的說明如下,更多詳細內容見:官方文檔-Service-Management

  • @class:必須為org.apereo.cas.services.RegisteredService的實現類
  • serviceId:對服務進行描述的表達式,可用於匹配一個或多個 URL 地址
  • name: 服務名稱 
  • id:全局唯一標志
  •  description:服務描述,會顯示在默認登錄頁
  •  evaluationOrder:定義多個服務的執行順序

1.2.修改application.properties

配置好service之后,根據官方文檔-service-registry,還需修改 application.properties 文件告知 CAS 服務端從本地加載服務定義文件

# 注冊客戶端
cas.serviceRegistry.initFromJson=true

2.自定義client-starter

2.1.創建項目

創建一個springboot項目,pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fdzang</groupId>
    <artifactId>cas-client-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 引用依賴的父包 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.9.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>3.5.0</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- 配置該插件將源碼放入倉庫 -->
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

2.2.加載配置文件

這個類主要的作用是讀取client端application.yml中,關於cas相關的配置

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.validation.constraints.NotNull;

@Data
@ConfigurationProperties(prefix = "cas", ignoreUnknownFields = false)
public class CasClientConfigurationProperties {
    /**
     * CAS 服務端 url 不能為空
     */
    @NotNull
    private String serverUrlPrefix;

    /**
     * CAS 服務端登錄地址  上面的連接 加上/login 該參數不能為空
     */
    @NotNull
    private String serverLoginUrl;

    /**
     * 當前客戶端的地址
     */
    @NotNull
    private String serverName;

    /**
     * 忽略規則,訪問那些地址 不需要登錄
     */
    private String ignorePattern;

    /**
     * 認證的URL
     */
    private String authrizationUrl;
}

2.3.編寫AutoConfigure配置類

這些自動注入的配置,能夠讓客戶端實現接入cas。

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.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.util.StringUtils;

import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableConfigurationProperties(CasClientConfigurationProperties.class)
public class CasClientConfiguration {

    @Autowired
    CasClientConfigurationProperties configProps;

    @Bean
    public FilterRegistrationBean filterSingleRegistration() {
        final FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new SingleSignOutFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(1);

        Map<String, String> params = new HashMap<String, String>();
        params.put("casServerUrlPrefix", configProps.getServerUrlPrefix());
        params.put("serverName", configProps.getServerName());
        registration.setInitParameters(params);

        return registration;
    }

    @Bean
    public ServletListenerRegistrationBean<EventListener> singleSignOutListenerRegistration() {
        ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>();
        registrationBean.setListener(new SingleSignOutHttpSessionListener());
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean filterAuthenticationRegistration() {
        final FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AuthenticationFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(2);

        Map<String, String> params = new HashMap<String, String>();
        params.put("casServerLoginUrl", configProps.getServerLoginUrl());
        params.put("serverName", configProps.getServerName());
        if (!StringUtils.isEmpty(configProps.getIgnorePattern())) {
            params.put("ignorePattern", configProps.getIgnorePattern());
        }
        registration.setInitParameters(params);

        return registration;
    }

    @Bean
    public FilterRegistrationBean filterValidationRegistration() {
        final FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(3);

        Map<String, String> params = new HashMap<String, String>();
        params.put("casServerUrlPrefix", configProps.getServerUrlPrefix());
        params.put("serverName", configProps.getServerName());
        params.put("useSession", "true");
        registration.setInitParameters(params);

        return registration;
    }

    @Bean
    public FilterRegistrationBean filterWrapperRegistration() {
        final FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new HttpServletRequestWrapperFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(4);

        return registration;
    }

    @Bean
    public FilterRegistrationBean casAssertionThreadLocalFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AssertionThreadLocalFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(5);

        return registration;
    }
}

2.4.編譯基於注解啟動方式

客戶端只需要在啟動類上加上@EnableCasClient注解即可實現接入cas

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(CasClientConfiguration.class)
public @interface EnableCasClient {

}

3.客戶端

3.1.新建項目

新建一個springboot項目,pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fdzang</groupId>
    <artifactId>cas-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.9.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.cas.client.version>3.5.0</java.cas.client.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.fdzang</groupId>
            <artifactId>cas-client-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

3.2.配置文件application.yml

server:
  port: 8082

cas:
  server-url-prefix: https://server.cas.com:8443/cas
  server-login-url: https://server.cas.com:8443/cas/login
  server-name: http://127.0.0.1:8082

3.3.主啟動類

import com.fdzang.cas.client.configuration.EnableCasClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableCasClient
public class ClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

3.4.測試接口

import com.fdzang.cas.client.configuration.CasClientConfigurationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
public class UserController {

    @Autowired
    CasClientConfigurationProperties configProps;

    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = request.getRemoteUser();

        return username;
    }

    @GetMapping("/logout")
    public void loginOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String url = configProps.getServerUrlPrefix() + "/logout?service=" + configProps.getServerName();
        response.sendRedirect(url);
    }
}


免責聲明!

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



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