Skip to content

Duplicate annotation exception with MockMvc and method-level annotations #11436

@theseion

Description

@theseion

Describe the bug
While upgrading from Spring Boot 2.5.6 to 2.7.1 I noticed an issue with MockMvc and method-level @PreAuthorize annotations. The issue appears to be that the anonymous class that Mockito creates includes the same annotations on the methods as the original class. The new checks for duplicate annotations (introduced in 5.6) now see the same annotation twice, once on the original method and once on the anonymous override.

To Reproduce
This is my test setup (only relevant parts included):

@RequiredArgsConstructor
@SpringBootTest
class MyTestClass {
  @SpyBean private final ImportController importController;
  private MockMvc mockMvc;

  @BeforeEach
   void setUp() {
    mocks = MockitoAnnotations.openMocks(this);
    mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
  }

  @AfterEach
  void tearDown() throws Exception {
    mocks.close();
  }

  @Test
  void uploadFile() throws Exception {
      var file = new MockMultipartFile(/*...*/);
    mockMvc
        .perform(
            multipart("/import")
                .file(file)
                .with(oidcLogin())
                .with(csrf())
                .with(user("user").roles("EXPERT")))
        .andExpect(status().isOk());

   /* verification etc. */
  }
}

Running this test produces AnnotationConfigurationException in AuthorizationAnnotationUtils#findUniqueAnnotation due to a duplicate @PreAuthorize annotation on the uploadFile() method:

  @PreAuthorize("hasRole('EXPERT')")
  public UploadFileDto uploadFile(/*...*/) {
     /*...*/
  }

Expected behavior
Identical annotations on overridden methods should be possible and not throw an exception.

Sample

MWE: https://github.com/theseion/spring-security-mwe

Versions (Spring Boot 5.7.2):
Spring Security: 5.7.2
Spring Boot Test: 2.7.1
Spring Test 5.3.21

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions