在 Spring Boot 中可用 @RequestHeader 实现轻量级接口鉴权:一、基础用法提取单个头字段;二、Map 批量接收指定头用于验签;三、配合拦截器统一处理并存入用户信息;四、注意大小写不敏感、空值处理及安全传输。

在 Java Spring Boot 中,可以通过 @RequestHeader 注解从 HTTP 请求头中提取关键信息(如 Token、AppId、Timestamp 等),再结合自定义逻辑完成轻量级鉴权。它不替代完整的安全框架(如 Spring Security),但适合接口级简单校验或作为前置过滤。
一、基础用法:获取单个请求头字段
直接在 Controller 方法参数中使用 @RequestHeader,支持字符串、数值、枚举等类型:
@GetMapping("/api/data")
public ResponseEntity<String> getData(
@RequestHeader("Authorization") String authHeader,
@RequestHeader(value = "X-App-Id", required = false) String appId) {
<pre class="brush:php;toolbar:false;">// 校验 Authorization 是否存在且格式合法(如 Bearer token)
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return ResponseEntity.status(401).body("Invalid or missing Authorization header");
}
String token = authHeader.substring(7).trim();
if (!isValidToken(token)) {
return ResponseEntity.status(403).body("Forbidden: Invalid token");
}
return ResponseEntity.ok("Data accessed successfully");}
二、批量注入:用 Map 接收全部或指定请求头
适合需要校验多个字段(如签名组合:AppId + Timestamp + Signature)的场景:
立即学习“Java免费学习笔记(深入)”;
- 接收所有请求头:
@RequestHeader Map<string string> headers</string> - 只接收指定键:
@RequestHeader({"X-App-Id", "X-Timestamp", "X-Signature"}) Map<string string> headers</string>
示例(验签逻辑):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@PostMapping("/api/submit")
public ResponseEntity<String> submit(@RequestHeader({"X-App-Id", "X-Timestamp", "X-Signature"}) Map<String, String> headers) {
String appId = headers.get("X-App-Id");
String timestamp = headers.get("X-Timestamp");
String signature = headers.get("X-Signature");
<pre class="brush:php;toolbar:false;">if (appId == null || timestamp == null || signature == null) {
return ResponseEntity.status(400).body("Missing required headers");
}
// 防重放:检查时间戳是否超时(如 5 分钟内有效)
long ts;
try {
ts = Long.parseLong(timestamp);
} catch (NumberFormatException e) {
return ResponseEntity.status(400).body("Invalid timestamp");
}
if (System.currentTimeMillis() - ts > 5 * 60 * 1000) {
return ResponseEntity.status(401).body("Request expired");
}
// 验签:服务端用 appId + timestamp + body + secretKey 生成签名,比对
String expectedSig = generateSignature(appId, timestamp, getRequestBody(), "your-secret-key");
if (!expectedSig.equals(signature)) {
return ResponseEntity.status(401).body("Invalid signature");
}
return ResponseEntity.ok("OK");}
三、配合拦截器统一鉴权(推荐用于多接口)
避免在每个方法里重复写校验逻辑,可将 @RequestHeader 的提取和校验下沉到 HandlerInterceptor:
- 重写
preHandle方法,通过HttpServletRequest获取 header(或用@RequestHeader在拦截器方法参数中注入) - 校验通过返回
true,否则设置响应状态并返回false - 把解析后的用户信息(如 userId、roles)存入
RequestContextHolder或ThreadLocal,供后续 Controller 使用
简化的拦截器示例:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String auth = request.getHeader("Authorization");
if (auth == null || !auth.startsWith("Bearer ")) {
response.setStatus(401);
return false;
}
<pre class="brush:php;toolbar:false;"> String token = auth.substring(7);
UserPrincipal user = parseAndValidateToken(token);
if (user == null) {
response.setStatus(403);
return false;
}
// 存入请求属性,Controller 中可通过 request.getAttribute("user") 获取
request.setAttribute("user", user);
return true;
}}
注册拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.excludePathPatterns("/public/**", "/login")
.addPathPatterns("/api/**");
}
}四、注意事项与最佳实践
-
大小写不敏感:HTTP 头名本身不区分大小写,Spring 会自动标准化(如
"x-app-id"和"X-App-Id"都能匹配) -
空值处理:加
required = false可避免 400 错误;未设该属性且 header 缺失时抛MissingRequestHeaderException - 不要在 header 中传敏感明文:如密码、密钥;Token 应使用 JWT 或短期有效凭证,并通过 HTTPS 传输
- 结合 Spring Security 更稳妥:复杂权限模型(RBAC、ABAC)、OAuth2、CSRF 防护等,仍应交由 Spring Security 处理

















