我遇到了一个问题(当然:)。我有一个带有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。
很可能你不需要@IntegrationTest
和MockMvc
,所以你应该能够完全删除它并解决你的问题。
或者,您可以通过显式地将WithSecurityContextTestExecutionListener
添加到类中来解决此问题,例如:
@TestExecutionListeners(listeners = { WithSecurityContextTestExecutionListener.class, IntegrationTestPropertiesListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class })
@IntegrationTest
public class UserResourceIntTest {