-1

我有一个 PUT 映射控制器方法,该方法应仅限于具有 ROLE_BUYER 角色的用户。但是,在测试期间,它会向没有该角色的用户返回 200 OK。控制器方法被调用,但@AuthenticationPrincipalHttpServletRequest.getRemoteUser()都是null

控制器:

@PutMapping("{bookId}/borrow/{userId}")
public boolean borrowBook(@PathVariable("bookId") long bookId, @PathVariable("userId") long userId, @AuthenticationPrincipal(errorOnInvalidType=true) UserDetails user) {
    return bookService.borrowBook(bookId,userId);
}

安全配置:

@EnableWebSecurity 
public class LibrarySecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers(HttpMethod.PUT,"/**").hasRole("LIBRARIAN")
            .mvcMatchers(HttpMethod.GET,"/**").permitAll()
            .and().csrf().disable();
    }   
}

测试方法:

@Test
public void borrowBookwithNormalUser() throws Exception {

    var userId = gilbert.getId();
    assertThat(gilbert.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_LIBRARIAN"))).isFalse();

    mockMvc.perform(
        MockMvcRequestBuilders
            .put("/books/2/borrow/"+userId)
            .with(SecurityMockMvcRequestPostProcessors.user(gilbert))
    ).andExpect(
        MockMvcResultMatchers.status().isForbidden()
    );

}

这是测试设置:

@SpringBootTest
public class BookControllerTests {

    @Autowired
    private WebApplicationContext context;

    @Autowired
    private UserDetailsService uds;

    private MockMvc mockMvc;
    private LibraryUser gilbert;

    @BeforeEach
    public void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .build();
        gilbert = (LibraryUser)uds.loadUserByUsername("gilbert");
    }

LibraryUser是一个实现UserDetails.

@Entity
public class LibraryUser implements Serializable, UserDetails {

   @Id
   private long id;    

   @Column(unique=true)
   private String username

   private String password;

   private boolean library = false;

   public Collection<? extends GrantedAuthority> getAuthorities() {
       var res = new ArrayList<GrantedAuthority>();
       res.add(new SimpleGrantedAuthority("ROLE_USER"));
       if(librarian) {
           res.add(new SimpleGrantedAuthority("ROLE_LIBRARIAN"));
       }
       return res;
   }
}

是测试本身的问题WebSecurityConfigurerAdapter还是测试本身的问题?

4

1 回答 1

0

感谢@Toerktumlare,我发现问题出在我的测试设置中。它不见了.apply(SecurityMockMvcConfigurers.springSecurity())。这是完整的测试设置:

@BeforeEach
public void setup() {
    mockMvc = MockMvcBuilders
        .webAppContextSetup(context)
        .apply(SecurityMockMvcConfigurers.springSecurity())
        .build();
    gilbert = (LibraryUser)uds.loadUserByUsername("gilbert");
}

PS:不确定,这是否应该是编辑/评论/答案。

于 2021-09-10T09:27:12.287 回答