You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Basic Security下控制器如何获取请求头认证信息?直接创建Header可行吗?

在Spring Boot中获取请求头认证信息的方法

首先明确:不能直接创建Header对象来获取请求头信息,因为请求头是与当前HTTP请求绑定的上下文数据,必须通过Spring或Servlet提供的方式获取。以下是几种可行的方案,结合你已有的Spring Basic Security场景:

1. 控制器方法直接获取(适合单个接口的验证)

通过@RequestHeader注解可以直接在控制器方法参数中获取指定的请求头:

@RestController
@RequestMapping("/api")
public class ResourceController {

    @GetMapping("/data")
    public ResponseEntity<String> getData(
            @RequestHeader("Authorization") String authHeader,
            @RequestHeader(value = "X-API-Key", required = false) String apiKey) {
        
        // 解析Basic Auth的Authorization头
        if (authHeader != null && authHeader.startsWith("Basic ")) {
            String base64Credentials = authHeader.substring(6).trim();
            String credentials = new String(Base64.getDecoder().decode(base64Credentials), StandardCharsets.UTF_8);
            String[] usernamePassword = credentials.split(":", 2);
            String username = usernamePassword[0];
            String password = usernamePassword[1];
            
            // 这里添加自定义验证逻辑(比如和数据库存储的信息比对)
        }
        
        // 验证API密钥逻辑
        if (apiKey == null || !"your-valid-api-key".equals(apiKey)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid API Key");
        }
        
        return ResponseEntity.ok("Protected data");
    }
}

2. 通过HttpServletRequest获取(灵活获取所有头信息)

在控制器方法中注入HttpServletRequest,调用getHeader()方法获取指定头:

@GetMapping("/data")
public ResponseEntity<String> getData(HttpServletRequest request) {
    String authHeader = request.getHeader("Authorization");
    String apiKey = request.getHeader("X-API-Key");
    
    // 验证逻辑同上
    return ResponseEntity.ok("Protected data");
}

3. 全局拦截验证(推荐:控制器逻辑前统一校验)

如果需要在所有接口执行前统一验证请求头,适合用Spring Security的自定义过滤器,结合你已有的Basic Security配置,示例如下:

自定义认证过滤器

@Component
public class PreAuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        String apiKey = request.getHeader("X-API-Key");
        
        // 1. 验证API密钥
        if (apiKey == null || !validateApiKey(apiKey)) {
            sendUnauthorizedResponse(response, "Invalid API Key");
            return;
        }
        
        // 2. 验证Basic Auth信息
        if (authHeader == null || !authHeader.startsWith("Basic ")) {
            sendUnauthorizedResponse(response, "Missing Basic Auth Credentials");
            return;
        }
        
        // 解析并校验用户名密码
        String base64Creds = authHeader.substring(6).trim();
        String creds = new String(Base64.getDecoder().decode(base64Creds), StandardCharsets.UTF_8);
        String[] parts = creds.split(":", 2);
        if (!validateUsernamePassword(parts[0], parts[1])) {
            sendUnauthorizedResponse(response, "Invalid Username/Password");
            return;
        }
        
        // 验证通过,继续执行后续逻辑
        filterChain.doFilter(request, response);
    }
    
    private boolean validateApiKey(String apiKey) {
        // 替换为你的实际校验逻辑(比如从数据库读取有效密钥比对)
        return "valid-api-key-123".equals(apiKey);
    }
    
    private boolean validateUsernamePassword(String username, String password) {
        // 可复用Spring Security的用户校验逻辑,或自定义校验规则
        return "admin".equals(username) && "secure-pass".equals(password);
    }
    
    private void sendUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json");
        response.getWriter().write("{\"error\": \"" + message + "\"}");
    }
}

整合到Spring Security配置

将自定义过滤器添加到Security过滤链中,放在原有Basic Auth过滤器之前:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private PreAuthFilter preAuthFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 添加自定义前置验证过滤器
                .addFilterBefore(preAuthFilter, UsernamePasswordAuthenticationFilter.class)
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated()
                )
                .httpBasic(Customizer.withDefaults()); // 保留原有Basic Security配置
        
        return http.build();
    }
}

内容的提问来源于stack exchange,提问作者Siddharth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:58:22