In Springboot unit Test always return 403 error,I've tried a variety of different configurations using AutoConfigureMockMvc with secure false and excluding security auto configuration getting 403 errror. Can anyone help me on this.
Here is my Security Implementation
@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;
}
}
Sharing Api Implementation Class, added PreAuthorize -Admin, to view all users
@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);
}
And Here is my JUnit Test,am Sending get request and return 403 error.
@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());
}
```
There is a difference between authorities
and roles
when you use @WithMockUser
:
/**
* <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 {};
Whatever you set with authorities
does not get any prefix.
As your controller expects ROLE_ADMIN
, try using roles
instead.
In addition to this, I would also try to use a sliced Spring Context using @WebMvcTest
for this test. Starting the whole Spring Context using @SpringBootTest
is not required for such tests.
Removed @SpringBootTest and added @WebMvcTest and roles, but getting 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());
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.