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

Spring Boot Security如何对携带特定请求头的请求禁用授权校验

实现方法

核心逻辑是在JWT资源服务器的校验过滤器执行前,识别到携带指定internal-key请求头的请求,直接给安全上下文注入可信认证身份,即可跳过后续JWT校验流程,不会被拦截。


方案1:自定义过滤器(推荐)

这种方式兼容性最好,不会打乱Security的过滤器链顺序,同时能给内部请求注入合法身份,适配业务代码里读取安全上下文的场景。

  1. 先写自定义内部请求校验过滤器,继承OncePerRequestFilter保证单次请求只执行一次:
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

public class InternalRequestFilter extends OncePerRequestFilter {
    // 密钥建议从配置文件注入,不要硬编码
    private final String validInternalKey;

    public InternalRequestFilter(String validInternalKey) {
        this.validInternalKey = validInternalKey;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestKey = request.getHeader("internal-key");
        // 头存在且值匹配时,注入内部可信身份
        if (validInternalKey.equals(requestKey)) {
            UsernamePasswordAuthenticationToken internalAuth = new UsernamePasswordAuthenticationToken(
                    "internalCaller",
                    null,
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_INTERNAL"))
            );
            SecurityContextHolder.getContext().setAuthentication(internalAuth);
        }
        filterChain.doFilter(request, response);
    }
}
  1. 修改原有安全配置,把自定义过滤器加到JWT校验过滤器BearerTokenAuthenticationFilter之前:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;

@Configuration
public class CustomSecurityConfiguration extends WebSecurityConfigurerAdapter {

    // 从配置文件读取内部密钥,示例配置项:security.internal-key=你的自定义复杂密钥
    @Value("${security.internal-key}")
    private String internalKey;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(new InternalRequestFilter(internalKey), BearerTokenAuthenticationFilter.class)
            .authorizeRequests(authz -> authz
                .anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt());
    }
}

方案2:轻量规则配置(快速实现)

如果不需要在业务逻辑里获取内部请求的认证身份,可以直接在授权规则里加头匹配放行逻辑,注意规则顺序必须放在anyRequest之前,否则不会生效:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests(authz -> authz
            // 匹配携带internal-key头的请求直接放行
            .requestMatchers(req -> req.getHeader("internal-key") != null).permitAll()
            .anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2.jwt());
}

注意事项:

  • 不要使用过于简单的internal-key值,生产环境请使用足够长度的随机密钥,定期轮换
  • 方案2的permitAll不会给请求注入认证身份,如果业务代码依赖SecurityContextHolder获取登录用户信息,内部请求会出现空指针,优先选择方案1
  • 如果需要限制内部请求的权限范围,可以在注入认证身份时按需分配权限角色,在授权规则里做细粒度控制

内容的提问来源于stack exchange,提问作者Pavan Kumar Lekkala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:25:18