当前位置: 首页 > article >正文

开发自定义starter

环境:Spring Cloud Gateway

需求:防止用户绕过网关直接访问服务器,用户只需引入依赖即可。

1、创建项目

首先创建一个spring boot项目

2、配置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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.15</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.github.lanxiu-code</groupId>
    <artifactId>security-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>security-spring-boot-starter</name>
    <description>security-spring-boot-starter</description>
    <url>https://github.com/lanxiu-code/security-spring-boot-starter</url>
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <developers>
        <developer>
            <id>lanxiu</id>
            <name>lanxiu</name>
            <email>3403138527@qq.com</email>
            <roles>
                <role>Project Manager</role>
                <role>Architect</role>
            </roles>
        </developer>
    </developers>

    <scm>
        <connection>https://github.com/lanxiu-code/security-spring-boot-starter.git</connection>
        <developerConnection>scm:git:ssh://git@github.com:lanxiu-code/security-spring-boot-starter.git
        </developerConnection>
        <url>https://github.com/lanxiu-code/security-spring-boot-starter</url>
    </scm>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </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.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <!--   central发布插件    -->
            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>lanxiu</publishingServerId>
                    <tokenAuth>true</tokenAuth>
                </configuration>
            </plugin>
            <!--   source源码插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!--   javadoc插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.9.1</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>1.6</version>
                <configuration>
                    <executable>D:\software\GPG\GnuPG\bin\gpg.exe</executable>
                    <keyname>lanxiu-code</keyname>
                </configuration>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>

  • spring-boot-configuration-processor:给用户提示配置

  • spring-boot-autoconfigure:自动装配功能

3、配置yml

spring:
  application:
    name: security-spring-boot-starter

security:
  gateway:
    only-gateway: true
    # 认证字段
    auth-key: auth
    # 认证值
    auth-value: gateway

4、SecurityConfig配置类

package com.lx.security.config;

import com.lx.security.constant.SecurityConstant;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "security.gateway")
public class SecurityConfig {
    /*
    * 是否只能通过网关请求服务器
    * */
    private Boolean onlyGateway = Boolean.TRUE;

    /*
    * 认证字段
    * */
    private String authKey = SecurityConstant.AUTH_KEY;

    /*
    * 认证值
    * */
    private String authValue = SecurityConstant.AUTH_VALUE;
}

5、ServerProtectInterceptor拦截器

package com.lx.security.interceptor;

import com.lx.security.config.SecurityConfig;
import com.lx.security.constant.SecurityConstant;
import com.lx.security.utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class ServerProtectInterceptor implements HandlerInterceptor {
    @Resource
    private SecurityConfig securityConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!securityConfig.getOnlyGateway()){
            return true;
        }
        String auth = request.getHeader(securityConfig.getAuthKey());
        if(securityConfig.getAuthValue().equals(auth)){
            return true;
        }else{
            //String result = "{\"code\":403,\"data\":null,\"message\":\"非法请求\"}";
            WebUtils.render(response, HttpStatus.FORBIDDEN.value());
            return false;
        }
    }

}

WebRequestInterceptor 和 HandlerInterceptor 都是 Spring 框架提供的拦截器机制的一部分,但它们在使用场景和生命周期上有一定的区别:

  1. 应用范围:
  • WebRequestInterceptor 是一个更通用的拦截器接口,它可以应用于任何类型的请求(如 HTTP 请求)。
  • HandlerInterceptor 则专门用于 Web MVC 应用中的控制器方法调用前后。
  1. 生命周期:
  • WebRequestInterceptor 的方法包括 preHandle, postHandle 和 afterCompletion,但它的 preHandle 方法是在请求处理之前调用,而 postHandle 和 afterCompletion 则分别在请求处理之后和视图渲染之后调用。
  • HandlerInterceptor 同样有 preHandle, postHandle 和 afterCompletion 方法,但是这些方法更加专注于 MVC 控制器的生命周期管理。

6、WebMvcConfig配置拦截器

package com.lx.security.config;

import com.lx.security.interceptor.ServerProtectInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Resource
    private ServerProtectInterceptor serverProtectInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(serverProtectInterceptor);
    }
}

7、SecurityAutoConfiguration自动装配类

package com.lx.security;


import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.lx.security")
@ConditionalOnProperty(prefix = "security.gateway", name = "only-gateway", havingValue = "true")
@EnableConfigurationProperties
public class SecurityAutoConfiguration {

}

@ConditionalOnProperty注解,它的作用是根据某个条件类决定是否自动配置,例如上面的意思是如果only-gateway和havingValue的值相同就会加载配置,否则不加载,如果配置了matchIfMissing = true,即使没有配置yml也会加载配置。

但是这个@ConditionalOnProperty注解有个坑,花了我一天才解决:

项目中的配置名称必须和条件注解@ConditionalOnProperty中的name一致。如果@ConditionalOnProperty中的name是驼峰的话(onlyGateway),项目中的配置名也要用驼峰,不能用-。

反之如果@ConditionalOnProperty中的name是用-的话(only-gateway),项目中的配置名可以用驼峰,也可以用-。

也可以直接选择不用@ConditionalOnProperty注解

上面两个图就会导致自动装配不生效,因为onlyGateway和only-gateway不相等

8、配置spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lx.security.SecurityAutoConfiguration

如果是SpringBoot3版本要在

METE-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中配置自动配置

com.lx.security.SecurityAutoConfiguration

9、打包

maven install

10、引入项目

<!-- 安全认证依赖 -->
<dependency>
    <groupId>com.lx.security</groupId>
    <artifactId>security-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

引入项目后配置好yml即可使用


http://www.kler.cn/news/337785.html

相关文章:

  • 二维数组的旋转与翻转(C++)(下(这是仔细讲解))
  • 在线教育系统开发:SpringBoot框架的实战应用
  • C++版iwanna1
  • Linux下使用apt和pip安装软件包时它们的安装位置
  • Java Web开发简介
  • MySQL多表查询:列子查询
  • Crypto虐狗记---”你“和小鱼(四)
  • 引领未来科技,精准链接IT精英 —— “万码优才“,IT技术人才找工作神器。
  • MySQL从0到1基础语法笔记(上)
  • eNodeB User Manual - Troubleshooting
  • 用 Delphi 做了一个简单的 CMS
  • Django 框架的知识点目录
  • TODO 提交PR修订 小林coding笔记中对TLS握手过程的阐释
  • 单例模式:Python中的“独一无二”模式
  • 掌握精准客流监测数据,及时传达应急事件信息的智慧园区开源了
  • 代码随想录 101. 孤岛的总面积
  • ✨机器学习笔记(六)—— ReLU、多分类问题、Softmax、Adam、反向传播
  • 基于springboot的数据库原理教学案例案例库管理系统
  • LeetCode 0983.最低票价:记忆化搜索
  • 软件设计师——信息安全