即使使用有效的 JWT 令牌,GraphQL 请求也始终是 403

问题描述 投票:0回答:1

我有一个 Spring Boot 项目,其中包含使用 JWT 过滤器保护的工作 REST 端点。例如,GET 请求需要不记名令牌,然后返回用户数据。所有 REST 端点都按预期工作。现在我们想要实现 GraphQL 查询以用于将来的数据获取。

这就是问题所在。 如果 /graphql 端点在安全配置中未受到保护

.authorizeHttpRequests(
            authorizeRequests ->
                authorizeRequests
                    .requestMatchers("/graphql/**")
                    .permitAll() // Whitelist
                    .anyRequest().authenticated() // Everything else should be authenticated
        )

查询通过,我得到了我想要的数据。但是,如果我现在将 GraphQL 端点从这个“白名单”中删除,则每个请求(无论有没有有效的访问令牌)都会以 403 的形式返回。Postman 或 IntelliJ 控制台中也没有错误消息,我可以在其中追溯到哪里此代码来自。

如需更多资源,这是我的完整安全配置:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(
                        authorizeRequests ->
                                authorizeRequests
                                        .requestMatchers("/graphql/**")
                                        .permitAll()
                                        .anyRequest().authenticated()
                )
                .sessionManagement(
                        sessionManagement ->
                                sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider)
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }
}

这是我的 JWT 过滤器:

@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

  private final JwtService jwtService;
  private final UserDetailsService userDetailsService;

  @Override
  protected void doFilterInternal(
      @NotNull HttpServletRequest request,
      @NotNull HttpServletResponse response,
      @NotNull FilterChain filterChain)
      throws ServletException, IOException {
    final String authHeader = request.getHeader("Authorization");
    final String jwt;
    final String userEmail;

    if (authHeader == null || !authHeader.startsWith("Bearer ")) {
      filterChain.doFilter(request, response);
      return;
    }

    jwt = authHeader.substring(7);// beginIndex is 7 bc "Bearer " is 7
    userEmail = jwtService.extractUserEmail(jwt);

    if (userEmail != null
        && SecurityContextHolder.getContext().getAuthentication() == null) { // check f if user is already authenticated
      UserDetails userDetails = userDetailsService.loadUserByUsername(userEmail);

      if (jwtService.isTokenValid(jwt, userDetails)) {
        UsernamePasswordAuthenticationToken authToken =
            new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());

        authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authToken);
      }
    }

    filterChain.doFilter(request, response);
  }
}
spring-boot authentication graphql http-status-code-403
1个回答
0
投票

如果您将授权请求链更改为

...
authorizeRequests
  .anyRequest()
  .permitAll()
...

它应该让所有请求通过,然后您可以使用 Spring Security 处理您的授权。

© www.soinside.com 2019 - 2024. All rights reserved.