SpringBoot + Nginx 免鉴权接口安全防护方案解析

 更新时间:2026年07月07日 09:13:55   作者:xixingzhe2  
在使用Spring Boot和Nginx构建Web应用时,确保接口安全是非常重要的,特别是在某些接口不需要进行HTTP基本认证或OAuth等鉴权的情况下,仍然需要采取措施来保护应用的安全,本文介绍SpringBoot + Nginx 免鉴权接口安全防护方案,感兴趣的朋友一起看看吧

一、核心风险说明

免鉴权接口(登录、验证码、注册、健康检查、公开查询等)无 token 校验,常见攻击:

  1. 暴力破解(登录密码 / 验证码爆破)
  2. 高频刷接口(短信轰炸、注册灌水、DoS)
  3. SQL 注入、XSS、路径遍历
  4. 爬虫批量拉取公开数据
  5. IP 恶意请求、CC 攻击
  6. 越权、参数篡改、重放攻击

防护分三层:Nginx 层前置拦截(低成本、高性能) + SpringBoot 应用层校验(业务逻辑防护) + 基础设施兜底。

二、Nginx 层防护(优先做,不占用 Java 服务资源)

1. 单 IP 限流,防高频刷接口(CC / 短信轰炸)

对所有免登接口单独配置限流,区分普通接口 / 验证码 / 登录接口(验证码限流更严)

# 全局限流配置 http块
http {
    # 按IP限流,10M内存存储IP
    limit_req_zone $binary_remote_addr zone=free_api:10m rate=10r/s;
    # 验证码单独限流,更严格
    limit_req_zone $binary_remote_addr zone=code_api:10m rate=1r/3s;
    # 登录接口限流
    limit_req_zone $binary_remote_addr zone=login_api:10m rate=2r/m;
}
server {
    location /api/login {
        limit_req zone=login_api burst=3 nodelay;
        proxy_pass http://springboot;
    }
    location /api/sendCode {
        limit_req zone=code_api burst=1 nodelay;
    }
    # 所有免鉴权接口统一限流
    location ~ ^/api/(public|register|health) {
        limit_req zone=free_api burst=5 nodelay;
        proxy_pass http://springboot;
    }
}

参数说明:

  • $binary_remote_addr:这是 Nginx 的一个内置变量,表示客户端的 IP 地址(二进制格式)。
  • zone=free_api:10m:定义一个名为 free_api 的共享内存区域,大小为 10 MB。
  • rate=1r/3s:每 3 秒最多 1 次请求
  • burst:突发缓冲队列,超出直接返回 503
  • nodelay:队列请求立即处理,不延迟排队

1.1 zone=free_api:10m

部分说明
zone关键字,表示定义一块共享内存区域
free_api自定义名称,在后续 limit_req 指令中引用它
10m内存大小为 10 MB(m 代表兆字节)

内存能存储多少数据?

  • Nginx 使用高效的哈希表存储每个 IP 的访问状态
  • 每个 IP 大约占用 32-64 字节
  • 10 MB ≈ 能存储 15万-30万个 不同的 IP 地址
  • 当内存用满时,Nginx 会移除最旧的记录(LRU 策略)。如果日活用户 100万,这会导致旧的IP记录被频繁淘汰,限流失效。

选择多大内存合适?

# 小型业务(日活 < 1万)
zone=free_api:1m
# 中等业务(日活 1万-50万)
zone=free_api:10m
# 大型业务(日活 > 50万)
zone=free_api:50m

1.2 rate=10r/s

部分说明
rate关键字,定义速率限制
10r10 个请求(r = request)
/s每秒(per second),也可以使用 /m(每分钟)

常用速率示例

# 每秒 1 个请求(适合防止暴力破解登录接口)
rate=1r/s;
# 每分钟 60 个请求(等价于每秒1个,但允许突发)
rate=60r/m;
# 每秒 100 个请求(适合高并发公开API)
rate=100r/s;

重要概念:速率是如何计算的?

  • 基于 令牌桶算法(Token Bucket)
  • Nginx 会以固定速率(每秒 10 个)往桶中添加令牌
  • 每个请求需要消耗 1 个令牌
  • 令牌耗尽后,新请求会被延迟或拒绝

2. IP 黑名单 + 临时封禁(爆破拦截)

配合限流自动拉黑恶意 IP,使用 nginx lua/deny,或定时脚本同步攻击 IP

# 封禁恶意IP列表
deny 192.168.1.100;
# 允许内网
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;

3. 请求参数过滤,拦截注入攻击

Nginx 匹配 URL / 参数关键字,拦截 SQL 注入、XSS、路径遍历

if ($query_string ~* "union|select|and|or|alert|<script>|../") {
    return 403;
}
# 拦截异常请求方法
if ($request_method !~ ^(GET|POST)$ ) {
    return 405;
}
# 限制请求体大小,防大报文DoS
client_max_body_size 10k;

4. 伪造 IP 防护(必须配置,避免黑客伪造 X-Forwarded-For 绕过限流)

如果前端有 CDN / 负载均衡,正确取真实客户端 IP,防止伪造 IP 无限刷接口:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 信任CDN内网IP,防止伪造XFF
real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;

5. 验证码 / 登录接口增加人机校验拦截

Nginx 拦截无验证码、无滑块票据的请求,结合前端传入captchaId参数校验,无则 403。

6. 关闭敏感头、防信息泄露

server_tokens off; # 隐藏nginx版本
proxy_hide_header Server;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;

三、SpringBoot 应用层防护(业务级安全,Nginx 挡不住的恶意请求)

1. 接口粒度区分免鉴权路径(统一拦截器 / 过滤器)

使用 Spring Security / 自定义 Filter,白名单放行免登接口,其余强制 token;禁止全局开放。

Spring Security 示例

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                // 免鉴权白名单
                .requestMatchers("/api/login", "/api/sendCode", "/api/public/**", "/actuator/health").permitAll()
                // 其他全部需要认证
                .anyRequest().authenticated()
        );
        return http.build();
    }
}

2. 业务层限流(分布式场景,Nginx 单机限流失效补充)

使用 Redis 实现分布式 IP 限流,针对登录、验证码做次数限制:

  • 同一 IP 1 分钟最多 5 次登录失败,锁定 10 分钟
  • 同一手机号 1 分钟最多 1 条验证码,1 天上限 10 条

伪代码示例:

// 登录失败计数
String key = "login:fail:" + ip;
Long count = redisTemplate.opsForValue().increment(key, 1);
if(count == 1) redisTemplate.expire(key, 10, TimeUnit.MINUTES);
if(count > 5) return "登录过于频繁,请稍后再试";

3. 人机验证(核心防刷手段)

所有高危免登接口强制人机校验:

  1. 图形验证码(登录 / 注册)
  2. 滑块 / 行为验证码(极验、阿里云验证码)
  3. 设备指纹:前端采集浏览器指纹、UA、设备 ID 上传后台校验。

无合法验证码票据直接拒绝业务处理。

4. 请求参数强校验(防注入、越权)

使用 Hibernate Validator 全局校验所有入参:

  • 手机号、邮箱长度、格式正则校验
  • ID、数字参数限制数值范围
  • 禁止特殊字符、脚本标签传入
@PostMapping("/sendCode")
public Result sendCode(@NotBlank @Pattern(regexp = "^1[3-9]\\d{9}$") String phone) {
    // 业务逻辑
}

全局异常拦截非法参数请求,记录攻击日志。

5. 防重放攻击(公开查询接口)

给前端分配临时签名参数 timestamp + nonce + sign

  1. 前端用密钥对参数 + 时间戳加密生成 sign
  2. 后端校验:时间戳 5 分钟内有效、nonce 一次性存入 Redis 去重、sign 校验一致 防止抓包后重复调用免登接口拉取数据。

6. 敏感操作风控规则

  • 同一 IP 短时间大量注册账号 → 拒绝注册
  • 异地高频登录 → 二次验证
  • 批量查询接口增加分页上限,禁止一次性查全量数据

7. 全局异常日志 + 攻击记录

拦截所有 400、403、限流、参数非法请求,记录:IP、接口、参数、UA,定时统计恶意 IP 推送告警。

四、分布式 / 集群补充方案

  • Redis 分布式限流:多台 Nginx、多 SpringBoot 实例时,单机 Nginx 限流失效,统一用 Redis 存储 IP 访问计数。
  • CDN/WAF 前置防护:阿里云 WAF、Cloudflare 等云 WAF:内置 CC 防护、SQL 注入、爬虫识别、验证码拦截,最省心。
  • 接口灰度频次控制:公开数据接口做分档 QPS 限制:普通访客低并发,登录用户放开额度。

五、不同免鉴权接口差异化防护策略

接口类型核心攻击防护重点
登录接口密码暴力破解登录失败计数封禁、人机验证、IP 限流
短信验证码短信轰炸手机号 + IP 双重限流、每日上限
注册接口灌水批量注册设备指纹、滑块验证码、IP 频次
公开查询接口爬虫批量爬取签名防重放、分页限制、IP 限流
健康检查 / 监控扫描探测内网 IP 白名单,外网直接禁止访问

六、最简落地执行顺序

  • Nginx 配置 IP 限流、请求过滤、真实 IP 解析(第一层拦截)
  • SpringSecurity 严格配置免登白名单,杜绝越权开放接口
  • 登录 / 验证码接入人机验证码,增加 Redis 业务限流
  • 所有入参统一校验,增加时间戳签名防重放
  • 接入 WAF / 防火墙兜底,开启攻击日志告警
  • 定期清理、拉黑高频恶意 IP

七、常见踩坑点

  • 只在应用层限流,没做 Nginx 前置:大量无效请求打满 Java 线程池,服务雪崩
  • X-Forwarded-For 未正确配置,黑客伪造 IP 绕过限流
  • permitAll 配置 /**,误开放所有接口,造成越权漏洞
  • 验证码仅前端校验,后端不二次校验,黑客绕过前端直接调用接口
  • 单机 Nginx 集群部署,未做分布式 Redis 限流,限流失效

到此这篇关于SpringBoot + Nginx 免鉴权接口安全防护方案的文章就介绍到这了,更多相关SpringBoot Nginx 免鉴权接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 微信小程序录音文件格式silk遇到的问题及解决方法

    微信小程序录音文件格式silk遇到的问题及解决方法

    录音文件为silk格式,说是silk其实是base64加密后的webm格式,只需将其转为webm格式即可。但是在处理过程中遇到各种坑,下面小编给大家带来了微信小程序录音文件格式silk遇到的问题及解决方法,感兴趣的朋友一起看看吧
    2018-09-09
  • Hibernate的Session_flush与隔离级别代码详解

    Hibernate的Session_flush与隔离级别代码详解

    这篇文章主要介绍了Hibernate的Session_flush与隔离级别代码详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 解析SpringBoot自定义参数校验注解

    解析SpringBoot自定义参数校验注解

    这篇文章主要介绍了SpringBoot自定义参数校验注解,引入依赖,spring validation是在hibernate-validator上做了一层封装,文中提到了定义参数校验注解与处理器的示例代码,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • Java获取网页数据步骤方法详解

    Java获取网页数据步骤方法详解

    这篇文章主要介绍了Java获取网页数据步骤方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 关于Java如何正确地实现方法重载详解

    关于Java如何正确地实现方法重载详解

    在一个类中,可以定义多个构造方法,这叫做方法的重载!但是关于方法重载,具有有哪些要求和细节?在今天的这篇文章中,小编给大家详细说说方法重载相关的内容,需要的朋友可以参考下
    2023-05-05
  • Java中List排序的三种实现方法实例

    Java中List排序的三种实现方法实例

    其实Java针对数组和List的排序都有实现,对数组而言你可以直接使用Arrays.sort,对于List和Vector而言,你可以使用Collections.sort方法,下面这篇文章主要给大家介绍了关于Java中List排序的三种实现方法,需要的朋友可以参考下
    2021-12-12
  • Java synchronize线程安全测试

    Java synchronize线程安全测试

    这篇文章主要介绍了Java synchronize线程安全测试,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java详解entity转换到vo过程

    Java详解entity转换到vo过程

    这篇文章将用实例来和大家介绍一下entity转换到vo的方法过程。文中的示例代码讲解详细,对我们学习Java有一定的帮助,需要的可以参考一下
    2022-06-06
  • springboot自定义配置及自定义对象映射的全流程

    springboot自定义配置及自定义对象映射的全流程

    这篇文章主要介绍了springboot自定义配置及自定义对象映射的全流程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Java设计模式之Strategy模式

    Java设计模式之Strategy模式

    Strategy模式即策略模式,就是将一个算法的不同实现封装成一个个单独的类,这些类实现同一个接口,使用者直接使用该接口来访问具体的算法。这个样子,使用者就可以使用不同的算法来实现业务逻辑了。
    2016-07-07

最新评论