我有一个 PUT 映射控制器方法,该方法应仅限于具有 ROLE_BUYER 角色的用户。但是,在测试期间,它会向没有该角色的用户返回 200 OK。控制器方法被调用,但@AuthenticationPrincipal
和HttpServletRequest.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
还是测试本身的问题?