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

Spring Boot 3.2.0+Spring GraphQL:GraphIQL自省免鉴权配置咨询

解决方案

要实现GraphQL自省请求无需认证,而普通查询/变更请求保持鉴权,可以通过以下两种方式实现:

方式一:Spring Security请求匹配器(推荐)

通过自定义请求匹配器识别自省请求,在Security层面直接放行,性能更优。

  1. 自定义自省请求匹配器
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.StreamUtils;
import java.nio.charset.StandardCharsets;

public class GraphQLIntrospectionMatcher implements RequestMatcher {
    private static final String INTROSPECTION_MARKERS = "__schema|__type";

    @Override
    public boolean matches(HttpServletRequest request) {
        if (!"/graphql".equals(request.getRequestURI())) {
            return false;
        }
        try {
            String requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
            return requestBody.matches(".*(" + INTROSPECTION_MARKERS + ").*");
        } catch (Exception e) {
            return false;
        }
    }
}
  1. 配置Spring Security
    在Security配置类中,让自省请求绕过认证,其余/graphql请求保持鉴权:
import org.springframework.context.annotation.Bean;
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.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(new GraphQLIntrospectionMatcher()).permitAll()
                .requestMatchers("/graphql").authenticated()
                .anyRequest().permitAll()
            )
            // 替换为你实际使用的认证方式(如JWT、OAuth2等)
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(/* 自定义转换器 */)));
        return http.build();
    }
}

方式二:GraphQL拦截器处理

通过Spring GraphQL的拦截器,在查询执行前判断是否为自省请求,跳过认证检查。

  1. 自定义GraphQL拦截器
import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.WebGraphQlRequest;
import org.springframework.graphql.server.WebGraphQlResponse;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.context.SecurityContextHolder;
import reactor.core.publisher.Mono;

public class IntrospectionAuthInterceptor implements WebGraphQlInterceptor {
    private static final String INTROSPECTION_MARKERS = "__schema|__type";

    @Override
    public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
        String query = request.getDocument();
        if (query != null && query.matches(".*(" + INTROSPECTION_MARKERS + ").*")) {
            // 自省请求直接放行
            return chain.next(request);
        }
        // 非自省请求检查认证状态
        var auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth == null || !auth.isAuthenticated()) {
            return Mono.error(new AuthenticationCredentialsNotFoundException("请携带认证令牌访问"));
        }
        return chain.next(request);
    }
}
  1. 注册拦截器
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.server.WebGraphQlInterceptor;

@Configuration
public class GraphQlConfig {

    @Bean
    public WebGraphQlInterceptor introspectionAuthInterceptor() {
        return new IntrospectionAuthInterceptor();
    }
}

注意事项

  • 方式一在请求进入Security过滤器时就完成判断,避免了不必要的认证流程,推荐使用;
  • 方式二更贴近GraphQL业务逻辑,适合需要对请求做额外处理的场景;
  • 确保GraphIQL发送的自省请求为POST方法,且请求体包含__schema或__type关键字,匹配逻辑才能生效;
  • 代码中的认证配置部分需替换为你项目实际使用的方案(如JWT、Session认证等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:42:45