2013-03-01 59 views
1

我正在嘗試使用Wink RestClient在Rest服務端點上進行功能測試。我使用mock進行單元測試,但是我想在功能上測試它作爲終端消費者。Apache Wink客戶端 - 使用表單驗證測試REST服務

我知道有些人會反對我稱之爲REST端點,同時使用基於表單的身份驗證,但那是我目前的體系結構。

我想測試的大部分資源都是受保護的資源,應用程序(運行在Tomcat6上)受表單身份驗證的保護。 (如下面的web.xml片段)。

我到目前爲止嘗試過的一種方法是首先調用一個不受保護的資源,以獲取包含JSESSIONID的set-cookie頭,並在頭中使用該JSESSIONID(通過Resource.cookie())隨後的請求,但不會產生成果。

web.xml 

<login-config> 
    <auth-method>FORM</auth-method> 
    <form-login-config> 
     <form-login-page>/login.html</form-login-page> 
     <form-error-page>/login.html?failure=true</form-error-page> 
    </form-login-config> 
</login-config> 

My Wink RestClient代碼如下所示。所有響應都是200,但我注意到的兩件事情是,調用/ j_security_check /時的響應不包括jsessionid cookie,並且對受保護資源的調用表示我登錄失敗。調用j_security_check的有效負載是從先前攔截的成功的瀏覽器請求中直接獲取的。

ClientConfig config = new ClientConfig(); 
config.setBypassHostnameVerification(true); 
RestClient restClient = new RestClient(config); 

Resource unprotectedResource = restClient.resource(BASE_URL + "/"); 
unprotectedResource.header("Accept", "*/*"); 
ClientResponse clientResponse = unprotectedResource.get(); 
String response = clientResponse.getEntity(String.class); 

// get jSession ID 
String jSessionId = clientResponse.getHeaders().get("set-cookie").get(0); 
jSessionId = jSessionId.split(";")[0]; 
System.out.println(jSessionId); 

// create a request to login via j_security_check 
Resource loginResource = restClient.resource(BASE_URL + "/j_security_check/"); 
loginResource.accept("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
loginResource.header("referer", "http://localhost:8080/contextroot/"); 
loginResource.cookie(jSessionId); 
loginResource.header("Connection", "keep-alive"); 
loginResource.header("Content-Type", "application/x-www-form-urlencoded"); 
loginResource.header("Content-Length", "41"); 

ClientResponse loginResponse = loginResource.post("j_username=*****&j_password=*************"); 

/* the loginResponse, as this point, does not have the jsessionid cookie, my browser client does */ 

Resource protectedResource = restClient.resource(BASE_URL + "/protected/test/"); 
systemResource.accept("application/json"); 
systemResource.cookie(jSessionId); 

ClientResponse systemResponse = systemResource.get(); 
response = clientResponse.getEntity(String.class); 
System.out.println(response); 

任何使用Wink RestClient運行form-auth保護的資源的想法或經驗將不勝感激。我想我會接受其他框架,我聽說過REST-Assured和其他框架,但由於應用程序使用Wink,而RestClient似乎爲我提供了我所需要的,所以我想我會堅持使用它。

+0

原來j_security_check用[#302臨時移動]響應 - 當我攔截請求與嗅探器並將JSESSIONID cookie附加到重定向的請求上,這都很好。問題是我似乎無法從眨眼的RestClient對象(或資源或響應)對象獲取該對象。重定向發生在幕後。任何人都知道如何指示Resource.post()方法在重定向時停止,或者ClientResponse捕獲重定向?我目前還看不到方法。 – rogodeter 2013-03-01 23:11:32

回答

1

發現問題,並將該溶液

j_security_check是在迴應我的POST請求(認證),用#302 /重定向。隨後是眨眼RestClient,但是我的JSESSIONID cookie沒有被追加到它。這導致了響應(來自重定向的URL)包含一個帶有新標題的set-cookie標頭。我之後的第一次調用中插入JSESSIONID的調用失敗,因爲該cookie已過期。我需要做的就是指示RestClient不遵循重定向。如果重定向是必要的,我會自己構建,包含適當的cookie。

Chromium和Firefox將cookie從原始請求傳送到重定向的請求,所以它都很好。

下面是一些代碼,工作對我來說,使用JUnit4,RESTClient實現從Apache眨眼項目(和傑克遜ObjectMapper)

@Test 
public void testGenerateZipEntryName() throws JsonGenerationException, JsonMappingException, IOException 
{ 
    final ObjectMapper mapper = new ObjectMapper(); 

    final String BASE_URL = "http://localhost:8080/rest"; 

    // Configure the Rest client 
    ClientConfig config = new ClientConfig(); 
    config.proxyHost("localhost"); // helpful when sniffing traffic 
    config.proxyPort(50080);   // helpful when sniffing traffic 
    config.followRedirects(false); // This is KEY for form auth 
    RestClient restClient = new RestClient(config); 


    // Get an unprotected resource -- to get a JSESSIONID 
    Resource resource = restClient.resource(BASE_URL + "/"); 
    resource.header("Accept", "*/*"); 
    ClientResponse response = resource.get(); 
    // extract the jSession ID, in a brittle and ugly way 
    String jSessId = response.getHeaders().get("set-cookie").get(0).split(";")[0].split("=")[1]; 


    // Get the login resource *j_security_check* 
    resource = restClient.resource(BASE_URL + "/j_security_check"); 
    resource.cookie("j_username_tmp=admin; j_password_tmp=; JSESSIONID=" + jSessId); 
    resource.header("Content-Type", "application/x-www-form-urlencoded"); 
    resource.header("Content-Length", "41"); 

    // Verify that login resource redirects us 
    response = resource.post("j_username=admin&j_password=***********"); 
    assertTrue(response.getStatusCode() == 302); 


    // Grab a public resource 
    resource = restClient.resource(BASE_URL + "/"); 
    resource.cookie("j_username_tmp=admin; j_password_tmp=; JSESSIONID=" + jSessId); 
    response = resource.get(); 
    // verify status of response 
    assertTrue(response.getStatusCode() == 200); 


    // Grab a protected resource 
    resource = restClient.resource(BASE_URL + "/rest/system"); 
    resource.cookie("j_username_tmp=admin; j_password_tmp=; JSESSIONID=" + jSessId); 

    // Verify resource returned OK 
    response = resource.contentType("application/json").accept("*/*").get(); 
    assertTrue(response.getStatusCode() == 200); 

    // Deserialize body of protected response into domain object for further testing 
    MyObj myObj = mapper.readValue(response.getEntity(String.class), MyObj.class); 
    assertTrue(myObj.customerArchived() == false); 
} 
+0

鑑於缺乏良好的Apache Wink客戶端示例,您的幫助最大。 – 2016-05-14 05:59:13

相關問題