Spring Boot如何实现API密钥安全并禁用默认基础身份验证
API密钥校验机制使用及配置指南
其他应用调用你的API服务的方法
这套安全机制要求调用方在请求头中携带约定的API密钥,具体操作如下:
- 首先确认你在配置文件中设置的两个参数:请求头名称
ReportService.http.auth-token-header-name、密钥值ReportService.http.auth-token - 调用方发送HTTP请求时,在请求头中添加对应键值对,比如你配置的请求头名称为
X-REPORT-API-KEY、密钥为test123456,则请求头需要包含X-REPORT-API-KEY: test123456 - 示例curl调用命令:
curl -H "X-REPORT-API-KEY: test123456" http://你的服务地址/接口路径
- 如果调用方未携带密钥、密钥错误,会收到401未授权的响应。
启用API密钥安全方案、禁用Spring默认基础身份验证的步骤
步骤1:引入必要依赖
确保你的pom.xml(Maven)或build.gradle(Gradle)中已经引入Spring Security依赖,Maven示例:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
步骤2:添加配置参数
在application.properties或application.yml中添加以下配置:
# 自定义API密钥请求头名称 ReportService.http.auth-token-header-name=X-REPORT-API-KEY # 自定义API密钥值,生产环境建议用配置中心、环境变量等方式存储,不要明文写在配置文件 ReportService.http.auth-token=你自定义的高强度密钥 # 禁用Spring Security默认的基础用户名密码认证 spring.security.basic.enabled=false # 不需要配置spring.security.user相关的用户名密码参数
如果是高版本Spring Boot(2.7+)默认基础认证已不会自动触发,若还是出现默认登录页,可以在启动类注解中排除自动配置:
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class})
步骤3:确认代码扫描范围
你提供的两个类APISecurityConfig和APIKeyAuthFilter需要放在Spring Boot启动类的同级包或子包下,确保Spring能扫描到类上的@Configuration、@EnableWebSecurity注解,配置才能生效。
步骤4:功能验证
- 不携带API密钥头调用任意接口,确认返回401状态码
- 携带正确的API密钥头调用接口,确认可以正常拿到响应
- 携带错误的API密钥头调用接口,确认返回401状态码
注意事项
- 生产环境不要把API密钥硬编码在配置文件、代码中,建议使用Nacos等配置中心加密存储,或者通过服务启动环境变量传入
- 如果有不需要校验的公开接口,可以在
APISecurityConfig的configure方法中添加放行规则,示例:
httpSecurity.antMatcher("/**").csrf().disable().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().addFilter(filter).authorizeRequests() // 放行公开接口 .antMatchers("/public/**", "/actuator/health").permitAll() .anyRequest().authenticated();
- 建议定期轮换API密钥,降低泄露风险
附录:完整代码实现
APISecurityConfig.java
package com.microservice.reportGenerator.validation; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @Configuration @EnableWebSecurity @Order(1) public class APISecurityConfig extends WebSecurityConfigurerAdapter { @Value("${ReportService.http.auth-token-header-name}") private String principalRequestHeader; @Value("${ReportService.http.auth-token}") private String principalRequestValue; @Override public void configure(HttpSecurity httpSecurity) throws Exception { APIKeyAuthFilter filter = new APIKeyAuthFilter(principalRequestHeader); System.out.println(principalRequestHeader + " Y" + principalRequestValue); filter.setAuthenticationManager(new AuthenticationManager() { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String principal = (String) authentication.getPrincipal(); if (!principalRequestValue.equals(principal)) { throw new BadCredentialsException("The API key was not found or not the expected value."); } authentication.setAuthenticated(true); return authentication; } }); httpSecurity.antMatcher("/**").csrf().disable().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().addFilter(filter).authorizeRequests() .anyRequest().authenticated(); } }
APIKeyAuthFilter.java
package com.microservice.reportGenerator.validation; import javax.servlet.http.HttpServletRequest; import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; public class APIKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter { private String principalRequestHeader; public APIKeyAuthFilter(String principalRequestHeader) { this.principalRequestHeader = principalRequestHeader; } @Override protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { System.out.println(request.getHeader(principalRequestHeader)); return request.getHeader(principalRequestHeader); } @Override protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { return "N/A"; } }
内容的提问来源于stack exchange,提问作者JESUS l.
相关产品推荐
相关产品推荐

