2016-03-30 89 views
1

我有一個問題(當然:))。我有Spring Security和Spring MVC(帶Rest API)的Spring 4.2應用程序,我想測試REST方法中註釋@Secured(ROLE_FOO)的有效性。 所以我需要爲此安裝spring-security-test庫。好。 然後,我跟進一些教程(或DOC)之類的官員之一:http://docs.spring.io/autorepo/docs/spring-security/4.1.0.RC1/reference/htmlsingle/春季安全測試:測試註釋@Secured(或@PreAuthorize)

這裏我的測試代碼(我'嘗試刪除所有「uneccessary」代碼

@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 = "https://stackoverflow.com/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(); 

... 

} 

EDIT2:只是要清除類定義:

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

什麼版本的彈簧測試您使用的是:

或者,你可以明確地將WithSecurityContextTestExecutionListener到類像解決呢?從參考文獻「Spring Security的測試支持需要spring-test-4.1.3.RELEASE或更高版本」。 –

+0

沒有在pom.xml中指定的版本。關於彈簧,唯一指定的版本是在pom.xml中的頂部: 彈簧引導起動父 org.springframework.boot 1.3.1.RELEASE

+0

對不起,在我的Maven依賴項(jar文件)中,我使用了spring-test-4.2.4.RELEASE。 –

回答

1

問題是Spring Security的WithSecurityContextTestExecutionListener沒有被執行導致@IntegrationTestoverriding the default TestExecutionListeners

最有可能你不需要@IntegrationTestMockMvc,所以你應該能夠完全移除它並解決你的問題。

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

謝謝你,但仍然無法正常工作。事實上,我沒有錯誤,但設置一個虛擬角色並不意味着錯誤http 401。測試總是通過。我的設置配置:參見EDIT1用於測試設置代碼。 –