成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實(shí)戰(zhàn)出真知!SpringBoot 接口級(jí)防護(hù):限流、重放攻擊與簽名機(jī)制全解析

開發(fā) 前端
本文將基于 Spring Boot 框架,手把手實(shí)現(xiàn)一套可落地的接口安全防護(hù)機(jī)制,涵蓋簽名驗(yàn)證、防重放、限流控制等核心能力,適用于 B 端開放接口、系統(tǒng)對(duì)接場(chǎng)景。

在當(dāng)今數(shù)字化服務(wù)廣泛開放的背景下,后端接口往往暴露在公網(wǎng)之下,極易成為攻擊者的突破口。接口調(diào)用的重放攻擊、參數(shù)偽造、暴力請(qǐng)求等問題屢見不鮮,嚴(yán)重威脅服務(wù)安全與數(shù)據(jù)完整性。

本文將基于 Spring Boot 框架,手把手實(shí)現(xiàn)一套可落地的接口安全防護(hù)機(jī)制,涵蓋簽名驗(yàn)證、防重放、限流控制等核心能力,適用于 B 端開放接口、系統(tǒng)對(duì)接場(chǎng)景。

接口簽名驗(yàn)證設(shè)計(jì)思路

簽名的目標(biāo)是確保「請(qǐng)求未被篡改 + 來源可信 + 有效時(shí)間內(nèi)唯一調(diào)用」。其基本設(shè)計(jì)流程如下:

請(qǐng)求參數(shù)說明

參數(shù)名

說明

appId

接口調(diào)用方唯一標(biāo)識(shí)

timestamp

請(qǐng)求時(shí)間戳,用于防止過期請(qǐng)求

nonce

隨機(jī)字符串,確保請(qǐng)求唯一性

sign

簽名值,由后端根據(jù)參數(shù)與秘鑰生成

簽名生成算法

簽名算法一般為:

sign = MD5(按 key 排序后的參數(shù)字符串 + appSecret)

參數(shù)拼接規(guī)則舉例:

appId=123&nonce=xyz&t=1710001234&data=xxx&appSecret=abcDEF123

接口限流與重放攻擊防護(hù)

限流實(shí)現(xiàn)(Redis 簡(jiǎn)單計(jì)數(shù)法)

String key = "rate_limit:" + normalizedPath + ":" + getClientIp(request);
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
    redisTemplate.expire(key, 10, TimeUnit.SECONDS);
}
if (count > 5) {
    throw new ApiException("請(qǐng)求過于頻繁,請(qǐng)稍后再試");
}

重放防護(hù)(基于 nonce + timestamp)

String nonceKey = "nonce_cache:" + appId + ":" + nonce;
Boolean success = redisTemplate.opsForValue().setIfAbsent(nonceKey, "1", 5, TimeUnit.MINUTES);
if (Boolean.FALSE.equals(success)) {
    throw new ApiException("重復(fù)請(qǐng)求被攔截");
}

Spring Boot + 自定義注解 + 攔截器實(shí)現(xiàn)簽名校驗(yàn)

接下來我們通過完整代碼實(shí)現(xiàn)接口簽名機(jī)制,確保項(xiàng)目中可直接落地。

步驟 1:定義簽名校驗(yàn)注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiSign {
    boolean required() default true;
}

步驟 2:創(chuàng)建攔截器處理邏輯

@Component
public class ApiSecurityInterceptor implements HandlerInterceptor {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    private static final long EXPIRE_TIME = 5 * 60; // 5分鐘


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) return true;


        HandlerMethod method = (HandlerMethod) handler;
        ApiSign apiSign = method.getMethodAnnotation(ApiSign.class);
        if (apiSign == null || !apiSign.required()) return true;


        // 提取參數(shù)
        String appId = request.getParameter("appId");
        String sign = request.getParameter("sign");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");


        if (StringUtils.isAnyBlank(appId, sign, nonce, timestamp)) {
            throw new ApiException("簽名參數(shù)不完整");
        }


        // 校驗(yàn)時(shí)間戳
        long currentTime = System.currentTimeMillis() / 1000;
        if (Math.abs(currentTime - Long.parseLong(timestamp)) > EXPIRE_TIME) {
            throw new ApiException("請(qǐng)求時(shí)間已過期");
        }


        // 重放校驗(yàn)
        String nonceKey = "nonce_cache:" + appId + ":" + nonce;
        if (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(nonceKey, "1", EXPIRE_TIME, TimeUnit.SECONDS))) {
            throw new ApiException("重復(fù)請(qǐng)求被拒絕");
        }


        // 簽名驗(yàn)證
        Map<String, String[]> parameterMap = request.getParameterMap();
        String calculatedSign = SignUtils.calculateSign(parameterMap, getAppSecret(appId));
        if (!sign.equalsIgnoreCase(calculatedSign)) {
            throw new ApiException("簽名校驗(yàn)失敗");
        }


        return true;
    }


    private String getAppSecret(String appId) {
        // 實(shí)際項(xiàng)目中建議從數(shù)據(jù)庫(kù)或配置中心加載
        return "secretFor_" + appId;
    }
}

步驟 3:簽名工具類封裝

public class SignUtils {


    public static String calculateSign(Map<String, String[]> params, String appSecret) {
        SortedMap<String, String> sortedParams = new TreeMap<>();
        for (Map.Entry<String, String[]> entry : params.entrySet()) {
            if ("sign".equalsIgnoreCase(entry.getKey())) continue;
            sortedParams.put(entry.getKey(), entry.getValue()[0]);
        }


        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        sb.append("appSecret=").append(appSecret);


        return DigestUtils.md5DigestAsHex(sb.toString().getBytes(StandardCharsets.UTF_8)).toUpperCase();
    }
}

步驟 4:配置攔截器生效

@Configuration
public class WebConfig implements WebMvcConfigurer {


    @Autowired
    private ApiSecurityInterceptor apiSecurityInterceptor;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(apiSecurityInterceptor)
                .addPathPatterns("/api/**");
    }
}

步驟 5:接口使用方式示例

@GetMapping("/api/secure/data")
@ApiSign
public Result<String> getSecureData() {
    return Result.success("這是簽名驗(yàn)證通過的數(shù)據(jù)");
}

請(qǐng)求調(diào)用流程說明

  1. 調(diào)用方生成帶簽名的請(qǐng)求;
  2. 請(qǐng)求通過限流判斷 → 重放判斷 → 參數(shù)完整性校驗(yàn);
  3. 后端根據(jù)參數(shù)生成服務(wù)端簽名與客戶端簽名對(duì)比;
  4. 簽名一致放行,失敗則拒絕。

總結(jié)

本方案結(jié)合 Spring Boot 提供了一套輕量、可擴(kuò)展的接口安全保護(hù)機(jī)制:

功能點(diǎn)

技術(shù)實(shí)現(xiàn)

簽名校驗(yàn)

自定義注解 + 攔截器 + 參數(shù)排序 + MD5 簽名

防重放

Redis 緩存 nonce,設(shè)定過期時(shí)間

限流

Redis 計(jì)數(shù)器,單位時(shí)間請(qǐng)求次數(shù)限制

易用性

注解式接入,低侵入、接口層無需重復(fù)代碼

可擴(kuò)展性

可集成 AES 加密、IP 白名單、權(quán)限控制等高級(jí)能力

適用于中臺(tái)接口、對(duì)接系統(tǒng)、開放平臺(tái)等場(chǎng)景。可以作為統(tǒng)一接口安全網(wǎng)關(guān)的重要組成部分,也可獨(dú)立部署在 Spring Boot 服務(wù)中。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2025-06-03 04:10:00

2024-10-08 08:26:43

2011-04-06 10:36:21

2025-06-26 02:11:00

2025-02-26 00:28:01

2011-04-06 10:23:46

2011-04-06 10:31:53

2021-03-30 10:46:42

SpringBoot計(jì)數(shù)器漏桶算法

2024-07-18 09:29:02

2017-07-14 17:41:20

2025-05-12 08:24:04

高并發(fā)流量系統(tǒng)

2015-01-20 09:35:52

2014-11-18 09:35:14

2011-04-06 10:03:16

2022-03-02 11:42:06

勒索軟件網(wǎng)絡(luò)安全

2013-12-23 10:14:36

虛擬網(wǎng)絡(luò)

2013-12-24 07:17:25

虛擬網(wǎng)絡(luò)網(wǎng)絡(luò)虛擬化

2020-12-30 10:22:08

物聯(lián)網(wǎng)安全攻擊防護(hù)防火墻

2013-05-13 17:49:26

2013-04-26 09:45:35

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲国产精品久久久久婷婷老年 | 亚洲国产精品一区二区三区 | 亚洲在线免费观看 | 精品国产一区二区三区久久 | 免费观看一级毛片 | 91精品国产91久久久久游泳池 | 一区二区三区日韩精品 | 久久久久久久久久久久91 | 亚洲成人av在线播放 | 国产精品爱久久久久久久 | 综合一区 | 91av视频| 成人特级毛片 | 午夜网| 一级毛片免费 | 欧洲一区二区视频 | 成人在线精品 | 亚洲人va欧美va人人爽 | 免费观看一级特黄欧美大片 | 人人看人人爽 | 在线亚洲免费 | 国产美女一区 | 天天干天天玩天天操 | 一级做a爰片性色毛片16 | 色欧美综合 | 久久久精 | 亚洲视频免费观看 | 亚洲精品视频导航 | 自拍偷拍中文字幕 | 一区二区久久 | 日本高清视频在线播放 | 精品国产一区二区三区性色 | 91精品国产麻豆 | av中文字幕在线播放 | 黄色片a级 | 日韩成人专区 | aaa在线观看 | 欧美精品91 | 亚洲成人av在线播放 | 99精品在线观看 | 欧美精品久久 |