在Springboot单元测试中,MockMvc返回403 Forbidden



在Springboot单元中,Test总是返回403错误,我使用AutoConfigureMockMvc尝试了各种不同的配置,其中安全性为false,不包括安全性自动配置,得到403错误。有人能帮我吗。

这是我的安全实现

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource(name = "userService")
private UserDetailsService userDetailsService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationEventPublisher(authenticationEventPublisher())
.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.anonymous()
.disable()
.authorizeRequests()
.antMatchers("/api-docs/**")
.permitAll();
}
@Bean
public DefaultAuthenticationEventPublisher authenticationEventPublisher() {
return new DefaultAuthenticationEventPublisher();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}

共享Api实现类,添加了PreAuthorize-Admin,以查看所有用户

@RestController
@RequestMapping("/api/userInfo")
public class UserController {
private final Logger LOG = Logger.getLogger(getClass());
private String serviceMsg = "serviceMsg";
@Autowired
private UserService userService;
@Autowired
private UserServiceUtil util;

@PreAuthorize("hasAnyRole('ADMIN')")
@RequestMapping(method = RequestMethod.GET, produces = "application/json" )
@ApiOperation(value = "Get details of all RA2 users in a paginated JSON format")
public Page<User> listUser(Pageable pageable) {
return userService.getUserSummary(pageable);
}

这是我的JUnit测试,正在发送get请求并返回403错误。

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
@ContextConfiguration
@AutoConfigureMockMvc(addFilters = false)
public class UserControllerTest {

@Configuration

@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class TestConfiguration {
@Bean
@Primary
public UserService getUserService(){
return Mockito.mock(UserService.class);
}

@Bean
@Primary
public UserServiceUtil getUserServiceUtil(){
return Mockito.mock(UserServiceUtil.class);
}
}
@Autowired
private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext ;


private String serviceMsg = "serviceMsg";
@Autowired
private UserService userService;
@Autowired
private UserServiceUtil util;

private User admin;
private User user;

@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext ).apply(springSecurity()).build();
}
@WithMockUser(username = "test",authorities ="ADMIN")
@Test
public void getuserList() throws Exception {
List<User> list = new ArrayList<User>();
list.add(new User());
Page<User> page = new PageImpl<User>(list, null, list.size());
Mockito.when(userService.getUserSummary(any(Pageable.class))).thenReturn(page);
this.mockMvc.perform(get("/api/userInfo?page=1&size=10").with(csrf()).contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isOk()).andDo(MockMvcResultHandlers.print());
}
```

使用@WithMockUser:时,authoritiesroles之间存在差异

/**
* <p>
* The roles to use. The default is "USER". A {@link GrantedAuthority} will be created
* for each value within roles. Each value in roles will automatically be prefixed
* with "ROLE_". For example, the default will result in "ROLE_USER" being used.
* </p>
* <p>
* If {@link #authorities()} is specified this property cannot be changed from the
* default.
* </p>
* @return
*/
String[] roles() default { "USER" };
/**
* <p>
* The authorities to use. A {@link GrantedAuthority} will be created for each value.
* </p>
*
* <p>
* If this property is specified then {@link #roles()} is not used. This differs from
* {@link #roles()} in that it does not prefix the values passed in automatically.
* </p>
* @return
*/
String[] authorities() default {};

使用authorities设置的任何内容都不会得到任何前缀。

由于控制器需要ROLE_ADMIN,请尝试使用roles

除此之外,我还将尝试在这个测试中使用一个使用@WebMvcTest的切片Spring上下文。此类测试不需要使用@SpringBootTest启动整个Spring上下文。

删除了@SpringBootTest并添加了@WebMvcTest和角色,但获得了403。


@RunWith(SpringRunner.class)
@WebMvcTest(controllers = UserController.class)
@ActiveProfiles("test")
@ContextConfiguration
@AutoConfigureMockMvc(addFilters = false)
public class UserControllerTest {

@Configuration

@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class TestConfiguration {
@Bean
@Primary
public UserService getUserService(){
return Mockito.mock(UserService.class);
}

@Bean
@Primary
public UserServiceUtil getUserServiceUtil(){
return Mockito.mock(UserServiceUtil.class);
}
}
@Autowired
private MockMvc mockMvc;

@Autowired
private WebApplicationContext wac;
@Autowired
private UserService userService;
@Autowired
private UserServiceUtil util;

@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).apply(springSecurity()).build();
}
@WithMockUser(username = "Ram",roles ="ADMIN")
@Test
public void getuserList() throws Exception {
List<User> list = new ArrayList<User>();
Page<User> page = new PageImpl<User>(list, null, list.size());
Mockito.when(userService.getUserSummary(any(Pageable.class))).thenReturn(page);
this.mockMvc.perform(get("/api/userInfo?page=1&size=10").with(csrf()).contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isOk()).andDo(MockMvcResultHandlers.print());
}
}

最新更新