========================
I am using Spring security @Secured at controller and it works fine when I test it in the browser, logging in with different users with different roles can see / cannot see different url (200 vs 403). but it fails at junit. it already returns 200 no matter what the role is. here is my setting.
@RestController
@RequestMapping(value = "/users")
class UserController {
@GetMapping("/admin")
@Secured({"ROLE_ADMIN"})
ResponseEntity<User> adminOnly() {
return new ResponseEntity<>(
User.builder().data("admin only page").build(),
HttpStatus.OK);
}
@GetMapping("/role")
@Secured({"ROLE_USER"})
ResponseEntity<User> user() {
return new ResponseEntity<>(
User.builder().data("Hello World! I am role user.").build(),
HttpStatus.OK);
}
in junit.
@Test
public void test() throws Exception {
this.mockMvc.perform(get("/users").with(user("u1").password("p1").roles("USER")))
.andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
this.mockMvc.perform(get("/users/admin").with(user("u1").password("p1").roles("USER")))
.andDo(print()).andExpect(status().isForbidden());
}
I expect the 2nd test to be 403 but it returns 200.
MockHttpServletRequest:
HTTP Method = GET
Request URI = /users/admin
Parameters = {}
Headers = {}
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Strict-Transport-Security=[max-age=31536000 ; includeSubDomains], Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"data":"admin only page"}
Forwarded URL = null
Redirected URL = null
Cookies = []
anything i'm missing?
I also tried to remove all the @Secured and replaced them with the following. still cannot get 403 in junit.
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/users/user").hasAnyRole("ROLE_USER")
.antMatchers("/users/admin").hasAnyRole("ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout()
.permitAll();
using authorities does not work either. now it always returns 403.
in config.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/users/user").hasAuthority("USER")
.antMatchers("/users/admin").hasAnyAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("u1").password("p1").authorities("USER").and()
.withUser("u2").password("p2").authorities("ADMIN", "ACTUATOR");
}
}
in junit.
this.mockMvc.perform(get("/users/admin").with(user("u1").password("p1")
.authorities(Collections.singletonList(new SimpleGrantedAuthority("USER")))))
.andDo(print()).andExpect(status().isForbidden());