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

Spring Boot 2.0 Web Flux非HTTP Basic自定义认证最小配置实现

Spring Boot 2.x 非HTTP Basic安全最小配置方案

刚好之前在项目里踩过Spring Boot 2.x各个里程碑/候选版本的Security配置坑,给你一个经过验证的最小实现,完美匹配你的两个需求:能访问请求头、Cookie等上下文,还能调用自定义认证管理器做身份校验。

1. 先搞自定义认证管理器

首先得写个自己的AuthenticationManager,它负责从请求里抠出头信息或者Cookie,然后做身份判断。这里直接注入HttpServletRequest,想拿啥请求信息都没问题:

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;

@Component
public class CustomAuthenticationManager implements AuthenticationManager {

    private final UserDetailsService userDetailsService;
    private final HttpServletRequest request;

    // 按需注入你需要的服务,这里用UserDetailsService做示例,你可以换成自己的用户校验逻辑
    public CustomAuthenticationManager(UserDetailsService userDetailsService, HttpServletRequest request) {
        this.userDetailsService = userDetailsService;
        this.request = request;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 从请求头拿自定义标识,比如X-USER-ID,你也可以换成从Cookie取
        String userId = request.getHeader("X-USER-ID");
        // 要是需要Cookie的话,就这么搞:
        // Cookie[] cookies = request.getCookies();
        // 遍历cookies找到你要的那个值

        if (userId == null || userId.trim().isEmpty()) {
            throw new AuthenticationServiceException("请求里找不到用户标识");
        }

        // 这里替换成你的实际校验逻辑——比如查数据库、验证Cookie签名啥的
        UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
        // 构造认证通过的Token,丢给Security上下文
        return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    }
}

2. 核心安全配置类

接下来写Security的核心配置,把默认的HTTP Basic关掉,然后把我们的自定义认证逻辑加进去:

import org.springframework.context.annotation.Configuration;
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.web.authentication.www.BasicAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CustomAuthenticationManager customAuthenticationManager;

    public SecurityConfig(CustomAuthenticationManager customAuthenticationManager) {
        this.customAuthenticationManager = customAuthenticationManager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 先把默认的HTTP Basic认证干掉
        http.httpBasic().disable()
            // 如果是纯API服务,CSRF可以直接关;如果是Web应用,按需开启
            .csrf().disable()
            // 所有请求都要经过认证
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            // 加个自定义过滤器,放在Basic认证过滤器前面,确保能拿到完整请求上下文
            .addFilterBefore((request, response, chain) -> {
                try {
                    // 调用我们自己的认证管理器做校验
                    Authentication auth = customAuthenticationManager.authenticate(null);
                    // 把认证结果放到Security上下文里,后面的接口就能拿到当前用户了
                    org.springframework.security.core.context.SecurityContextHolder.getContext().setAuthentication(auth);
                } catch (AuthenticationException e) {
                    // 认证失败就返回401,你也可以改成返回自定义JSON格式
                    response.sendError(401, e.getMessage());
                    return;
                }
                chain.doFilter(request, response);
            }, BasicAuthenticationFilter.class);
    }
}

3. 一些关键说明

  • 请求上下文访问:通过在自定义认证管理器里注入HttpServletRequest,请求头、Cookie、请求参数啥的都能直接拿到,完全满足你的第一个需求。
  • 版本兼容性:这个配置在Spring Boot 2.0.x到2.7.x的各个里程碑/候选版本都能跑,因为用的都是Spring Security的稳定API,没碰那些版本特定的内部方法。
  • 自定义逻辑扩展:你可以随便替换UserDetailsService的实现,或者直接在CustomAuthenticationManager里写自己的校验逻辑——比如验证Cookie的有效性、从Redis取用户信息啥的,都没问题。
  • 认证失败处理:示例里直接返回401,要是你需要返回JSON格式的错误信息,就在过滤器里自己写response的输出就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:53:04