Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - @PreAuthorize does not work in test

I have controller like this

@RestController
@RequestMapping(value="/test")
@PreAuthorize("hasRole('ADMIN')")
public class TestController
{

    @RequestMapping( method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> test ()
    {

        return ResponseEntity.ok("test");
    }

}

I tried to write unit test that will test permissions to access this controllers method.

This is my test

@RunWith(SpringRunner.class)
@ContextConfiguration
 @WebMvcTest(value = TestController.class)
public class AUnitTest
{

    @Autowired
    private MockMvc mockMvc;

    private final String url = "/test";

    @Test
    @WithMockUser(roles="ADMIN")
    public void testAdminUser() throws Exception
    {
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get(this.url );
        MvcResult result = mockMvc.perform(requestBuilder).andReturn();
        assertEquals(HttpStatus.OK.value(), result.getResponse().getStatus());
    }

}

When I remove roles from @WithMockUser and leave empty, by default it will have role USER and then test passes. When I put roles USER and ADMIN, it will also pass because of USER role. But whenever I set role to ADMIN it will fail, even though I set that user needs to have ADMIN role to access controller.

I tried with setting username, password, everything from Spring Security Docs, etc.

Am I missing something?

like image 469
Boris Avatar asked Jul 26 '17 09:07

Boris


People also ask

How does @PreAuthorize work in spring boot?

Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.

What is @PreAuthorize annotation in spring boot?

Spring Security provides method level security using @PreAuthorize and @PostAuthorize annotations. This is expression-based access control. The @PreAuthorize can check for authorization before entering into method. The @PreAuthorize authorizes on the basis of role or the argument which is passed to the method.

Does SpringBootTest start application?

With the @SpringBootTest annotation, Spring Boot provides a convenient way to start up an application context to be used in a test.

What is the use of @EnableGlobalMethodSecurity?

The global method security functionality is disabled by default. To enable it, you use the @EnableGlobalMethodSecurity annotation over the configuration class of your application. You can apply authorization rules that the application checks before the call to a method.


1 Answers

Try to add @EnableGlobalMethodSecurity(prePostEnabled = true) to test class.

Or add config sth like that:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class Config {
    ...
}
like image 133
mystdeim Avatar answered Sep 20 '22 03:09

mystdeim