Spring安全测试:测试注解@Secured(或@PreAuthorize)



我遇到了一个问题(当然:)。我有一个带有SpringSecurity和SpringMVC(带有Rest API)的spring4.2应用程序,我想测试Rest方法上存在的annotation@Secured(ROLE_FOO)的有效性。所以我需要为此安装spring安全测试库。好啊然后我继续学习一些教程(或文档),比如官方教程:http://docs.spring.io/autorepo/docs/spring-security/4.1.0.RC1/reference/htmlsingle/

这是我的测试代码(我正在尝试删除所有"未成功"的代码。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
public class UserResourceIntTest {
    private MockMvc restUserMockMvc2;
   @Autowired
    private WebApplicationContext context;
....//Injection, Mocks declarations here
@Before
    public void setup() {


        this.restUserMockMvc2 = MockMvcBuilders.webAppContextSetup(context).apply(SecurityMockMvcConfigurers.springSecurity()).build();

    }

    @Test
    @WithMockUser(roles="ROLE_VIEWER")
    public void testGetUserListe() throws Exception {
        //here getAuthentication() returns null !!! why ???
        SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//      restUserMockMvc2.perform(get("/api/users/liste")
//              .principal(SecurityContextHolder.getContext().getAuthentication()))
//                .accept(MediaType.APPLICATION_JSON))
//                .andExpect(status().isForbidden());
//                .andExpect(content().contentType("application/json"));
    }

这里是我想要测试的方法:

@RestController
@RequestMapping("/api")
public class UserResource {
    @RequestMapping(value = "/users/liste", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    @Transactional(readOnly = true)
    @Secured({ AuthoritiesConstants.TC_ADMIN })
    public ResponseEntity<List<ManagedUserDTO>> getUserListe(Pageable pageable, Principal principal) throws URISyntaxException {
        //doSomething...
    }

,你能告诉我考试的原因吗

SecurityContextHolder.getContext().getAuthentication()

返回null??@WithMockUser应该自动验证用户(因此是主体)

感谢

EDIT1:测试的设置部分(仅涉及安全说明):

@Inject
private FilterChainProxy springSecurityFilterChain;
@Inject
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
@Before
public void setup() {
....
this.restUserMockMvc2 = MockMvcBuilders
                .standaloneSetup(userResource2)
                .alwaysDo(print())              .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
                .setCustomArgumentResolvers(pageableArgumentResolver)
                .build();
...
}

编辑2:只是为了明确类定义:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        WithSecurityContextTestExecutionListener.class})
public class UserResourceIntTest {
}

问题是Spring Security的WithSecurityContextTestExecutionListener没有被执行,因为@IntegrationTest覆盖了默认的TestExecutionListeners。

很可能你不需要@IntegrationTestMockMvc,所以你应该能够完全删除它并解决你的问题。

或者,您可以通过显式地将WithSecurityContextTestExecutionListener添加到类中来解决此问题,例如:

@TestExecutionListeners(listeners = { WithSecurityContextTestExecutionListener.class, IntegrationTestPropertiesListener.class,
        DirtiesContextBeforeModesTestExecutionListener.class,
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class })
@IntegrationTest
public class UserResourceIntTest {

最新更新