Skip to content

FilterRegistrationBean<CustomFilter> Does Not Apply With HttpGraphQlTester #1265

@danielshiplett

Description

@danielshiplett

I've recently been asked to improve some security and testing of another team's application. They provide both a WebMVC and Spring for GraphQL API. As part of our security improvements, we layer another OncePerRequestFilter into WebMVC. This filter just creates some additional ThreadLocal context information (built upon Spring Security Jwt authentication) that helps our applications abstract away some of the complexity of an always changing security landscape that we face.

For our other applications, it has been easy to write tests that use MockMvc and Spring AddOns OAuth2 Test Support's @WithJwt test annotation. We have standardized personas that provide the minimal JWT we need to test our production Spring Security and custom abstractions.

As part of the process of updating this application, I have a test that makes use of the @AutoConfigureMockMvc to call a WebMVC endpoint. This simulates a user uploading new content to the application. Spring Security and our filter work fine. Here's a snippet of code followed by the logs that are generated:

    // plan ingest
    val importRequest = MockMvcRequestBuilders.multipart("/plans/import")
      .file(planFile)
      .contentType(MediaType.APPLICATION_JSON)
      .with(SecurityMockMvcRequestPostProcessors.csrf())

    val result = mockMvc.perform(importRequest).andExpect(MockMvcResultMatchers.status().isCreated).andReturn()
    2025-07-17T14:04:01.713-04:00 TRACE 24832 --- [APP] [    Test worker] w.c.CustomContextHolderFilter : doFilterInternal: /plans/import
    2025-07-17T14:04:01.738-04:00 TRACE 24832 --- [APP] [    Test worker] w.c.CustomContextHolderFilter : kradosUserProfileContext: app.security.context.OAuth2ResourceServerCustomContext@384e51f5
    2025-07-17T14:04:01.746-04:00  INFO 24832 --- [APP] [    Test worker] a.filter.RequestLoggingFilter    : Before request [POST /plans/import, client=127.0.0.1, user=local-user]
    2025-07-17T14:04:05.893-04:00  WARN 24832 --- [APP] [    Test worker] a.s.c.plan.PlanController          : plan upload time: PT4.113483S

The next step of the test is to then make a GraphQL query to return some information about the new content. Here's the test code snippet and the logs:

    // graphql all queries for the plan slug
    val client = MockMvcWebTestClient.bindToApplicationContext(context)
      .apply(SecurityMockMvcConfigurers.springSecurity())
      .defaultRequest(MockMvcRequestBuilders.post("/graphql").with(SecurityMockMvcRequestPostProcessors.csrf()))
      .configureClient()
      .baseUrl("/graphql")
      .build()

    val graphQlTester = HttpGraphQlTester.create(client);

    val importResultData: PartialImportResultData = jacksonObjectMapper().readValue(result.response.contentAsString)
    val slug = importResultData.slug
    val graphQlResponse = graphQlTester
      .documentName("planDetails")
      .variable("planSlug", slug)
      .execute()
    2025-07-17T14:04:06.101-04:00  WARN 24832 --- [APP] [    Test worker] a.CustomContextAccessor : >>>>****  getValue: app.security.context.EmptyCustomContext@a1ce033
    2025-07-17T14:04:06.332-04:00  WARN 24832 --- [APP] [    Test worker] a.CustomContextAccessor : >>>>****  setValue: app.security.context.EmptyCustomContext@a1ce033

In this case, in the logs, I can see my ThreadLocalAssessor implementation running to indicate that the GraphQL engine is asynchronously loading data from the DataFetcher. However, the EmptyCustomContext is indicative that my CustomContextHolder was never set. This means that the CustomContextHolderFilter was never executed. Which we can see is missing from the logs.

I'm guessing this has something to do with the fact that the application is WebMVC and not WebFlux, as I tried to @AutoConfigureWebTestClient and couldn't get any of the Spring Security test processors like csrf() or springSecurity() to apply to it. It was because of NULL httpHandlerBuilder and similar. That is also why I cannot use the MockMvcWebTestClient.bindTo(mockMvc).

The other possibility is that the GraphQL endpoint is in a different application context? And therefore, my filters aren't being applied to it at all?

I'd appreciate any guidance you can provide on this problem. Unfortunately, I cannot provide access to the actual code. And, unless really necessary, would like to avoid writing up a smaller example project, as it will probably still take significant time.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions