2017-07-26 61 views
2

我想測試主頁控制器的Spring Security +彈簧引導檢查控制

@RequestMapping("/") 
@ResponseBody 
String home() { 
    return "Hello World!"; 
} 

我使用的是用戶名「用戶」和測試,通過默認密碼春天的安全,但@PreAuthorize不工作

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
@PreAuthorize("hasRole('ADMIN')") 
public class HomeControllerTest { 

    @Autowired 
    private TestRestTemplate restTemplate; 

    @Test 
    @WithMockUser(username = "user", password = "test", roles = "ADMIN") 
    public void home() throws Exception { 
     String body = this.restTemplate.getForObject("/", String.class); 
     assertThat(body).isEqualTo("Hello World!"); 
    } 

} 

結果

預期結果:

< 「[你好!世界]」>

實際結果:

< 「{」 時間戳 「:1501100448216,」 狀態 「:401,」 錯誤 「:」未經授權 「 」信息:全 認證才能訪問這個資源 「 」路徑「」「: 」/「}]」>

我缺少的東西?

+1

您正在調用一個真正的控制器,所以使用'@ WithMockUser'幾乎是你這裏絕無僅有。這隻有在你直接調用控制器上的'home()'方法時纔有效。假設您有基本的身份驗證設置用於登錄,您應該根據您的請求發送憑據。你的測試用例中的'@ PreAuthorize'也無法實現。 –

回答

1

嘗試以下添加到您的測試類:

@TestExecutionListeners(mergeMode = MergeMode.MERGE_WITH_DEFAULTS, listeners = { 
     WithSecurityContextTestExecutionListener.class 
}) 

而下面的依賴,如果你沒有的話:

<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-test</artifactId> 
    <scope>test</scope> 
</dependency> 

春季安全需要一個額外的偵聽器不存在在默認情況下的測試中,所以您需要通過在merge模式中指定@TestExecutionListeners註釋來告訴spring添加它,以便它將合併當前列出的聽衆和要添加的聽衆 - 在這種情況下,WithSecurityContextTestExecutionListener

+0

謝謝,但它沒有奏效,我收到了相同的結果:/ –

+0

也試着在'@ WithMockUser'中的'roles'中添加'ROLE_ADMIN'。默認情況下,Spring安全檢查前綴'ROLE'(但在'@ PreAuthorize'保持爲'ADMIN') – Tom

0

您使用invaild密碼,因爲

默認的AuthenticationManager具有單個用戶(「用戶」的用戶名和隨機密碼,在INFO級別打印時應用程序啓動時)doc

您可以創建自定義用戶並進行測試againe

@Bean 
public UserDetailsService userDetailsService() throws Exception { 
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); 
    manager.createUser(User.withUsername("admin").password("passAdmin").roles("USER", "ADMIN").build()); 
    return manager; 
}