开发自定义starter
环境:Spring Cloud Gateway
需求:防止用户绕过网关直接访问服务器,用户只需引入依赖即可。
1、创建项目
首先创建一个spring boot项目

2、配置pom.xml
▼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
▼yaml复制代码spring: application: name: security-spring-boot-starter security: gateway: only-gateway: true # 认证字段 auth-key: auth # 认证值 auth-value: gateway
4、SecurityConfig配置类
▼java复制代码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拦截器
▼java复制代码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 框架提供的拦截器机制的一部分,但它们在使用场景和生命周期上有一定的区别:
- 应用范围:
- WebRequestInterceptor 是一个更通用的拦截器接口,它可以应用于任何类型的请求(如 HTTP 请求)。
- HandlerInterceptor 则专门用于 Web MVC 应用中的控制器方法调用前后。
- 生命周期:
- WebRequestInterceptor 的方法包括 preHandle, postHandle 和 afterCompletion,但它的 preHandle 方法是在请求处理之前调用,而 postHandle 和 afterCompletion 则分别在请求处理之后和视图渲染之后调用。
- HandlerInterceptor 同样有 preHandle, postHandle 和 afterCompletion 方法,但是这些方法更加专注于 MVC 控制器的生命周期管理。
6、WebMvcConfig配置拦截器
▼java复制代码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自动装配类
▼java复制代码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
▼bash复制代码org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lx.security.SecurityAutoConfiguration
如果是SpringBoot3版本要在
METE-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中配置自动配置
▼bash复制代码com.lx.security.SecurityAutoConfiguration
9、打包
maven install
10、引入项目
▼xml复制代码<!-- 安全认证依赖 --> <dependency> <groupId>com.lx.security</groupId> <artifactId>security-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency>
引入项目后配置好yml即可使用
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
AI应用开发中的流式输出:从协议原理到工程实战的完整指南
38
第1章 LearnWise AI项目介绍
5
Spring Boot 如何处理跨域请求(CORS):深度调研报告
3
【入职求助贴】萌新刚入职某大厂做后端开发,目前还在试用期。最近遇到一个棘手的问题,想向大家求助一下。入职不久,leader 给我派了一个任务。跟我说是0.5天就可以解决,我刚毕业入职,做了一个星期没有做出来。实现一个收集定时成功任务的案例。听起来好像不复杂,但我自己摸索着做了一整个星期,到现在还没达到预期效果。这一周我基本是“边学边做”的状态,遇到卡点也会每天主动找 leader 沟通进度和疑问。
2
#字节内推# 实习、校招、社招均有岗位
4
