rest-assured之認證受權(Authentication)

  rest-assured支持多種認證受權方案,好比:OAuth、digest(摘要認證)、certificate(證書認證)、form(表單認證)以及preemptive(搶佔式基礎認證)等。咱們能夠單獨爲某一個請求設置認證受權:html

1 given().auth().basic("username", "password"). ..

咱們也能夠爲全部的請求定義一個認證受權:java

1 RestAssured.authentication = basic("username", "password");

1、基礎認證git

  這裏有兩種基礎認證方式:搶佔式基礎認證(preemptive basic authentication)和受質詢式基礎認證(challenged basic authentication)。github

1.搶佔式基礎認證(preemptive basic authentication)web

  服務器某些狀況下在給出未受權響應以前會發送一個基礎認證憑證,從而減小額外的鏈接開銷。這是很是典型的,咱們大多數狀況下都是使用這個,除非咱們是在測試服務器的極限。好比說:spring

1 given().auth().preemptive().basic("username", "password").when().get("/secured/hello").then().statusCode(200);

2.受質詢式基礎認證(challenged basic authentication)api

  當咱們使用受質詢式基礎認證時,除非服務端明確的索要認證憑證,不然rest-assured將不會提供認證憑證。這就意味着爲了進行質詢,rest-assured將會額外的發送一個請求到服務端,而後接着會發送相同的請求,但此時會在header中設置認證憑證:安全

1 given().auth().basic("username", "password").when().get("/secured/hello").then().statusCode(200);

2、摘要認證(Digest Authentication)服務器

  目前只支持 受質詢式基礎認證(challenged basic authentication)的摘要認證:maven

1 given().auth().digest("username", "password").when().get("/secured"). ..

3、表單認證(Form Authentication)

  表單認證在互聯網上是很是受歡迎的一種認證。最典型的例子就是用戶在web網頁上填寫證書(username and password 用戶名和密碼),而後點擊登陸按鈕發起請求。下面是一個很是簡單的HTML頁面,用來展現這種表單認證:

 1 <html>
 2   <head>
 3     <title>Login</title>
 4   </head>
 5 
 6   <body>
 7     <form action="j_spring_security_check" method="POST">
 8       <table>
 9         <tr><td>User:&nbsp;</td><td><input type='text' name='j_username'></td></tr>
10         <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
11           <tr><td colspan='2'><input name="submit" type="submit"/></td></tr>
12        </table>
13         </form>
14       </body>
15  </html>

假如,服務端指望用戶輸入用戶名( j_username )和密碼( j_password ),而後點擊submit按鈕去登陸,那麼咱們可使用rest-assured來測試一下這樣的須要進行表單認證的服務:

1 given().
2         auth().form("John", "Doe").
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

雖然這種作法可能不是最佳的。那麼當咱們在rest-assured中使用這樣的表單認證時究竟發生了什麼呢?rest-assured在使用這種表單認證時須要發送一個額外的請求到服務端獲取登陸頁面,而後rest-assured會嘗試解析這個登陸頁面,從而得到登陸和密碼兩個輸入框以及表單提交的路徑(form action url),請求可能會成功或者是失敗,這取決於網頁的複雜程度。這裏有一種更好的方法,那就是在設置表單認證的時候直接給rest-assured提供這些參數信息。上面的例子咱們還能夠這樣作:

1 given().
2         auth().form("John", "Doe", new FormAuthConfig("/j_spring_security_check", "j_username", "j_password")).
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

使用上面這種方式rest-assured就不須要在額外發送請求和解析網頁了。若是咱們想使用默認的Spring Security 屬性,這用到一個叫 springSecurity 的預約義 FormAuthConfig :

1 given().
2         auth().form("John", "Doe", FormAuthConfig.springSecurity()).
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

4、CSRF(跨站請求僞造,Cross-site request forgery的縮寫,也能夠縮寫爲:XSRF)

  當今,服務端爲了防止某些攻擊在響應體中提供 CSRF token值是很是常見的了。rest-assured支持自動解析並提供 CSRF token值給服務端,爲了實現這個功能,rest-assured必須發送一個額外的請求來解析這個網站(或者是網站的部份內容)。

  咱們經過下面的方式能夠啓用 rest-assured 對 CSRF的支持:

1 given().
2         auth().form("John", "Doe", formAuthConfig().withAutoDetectionOfCsrf()).
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

如今rest-assured將會自動嘗試檢車該網站是否包含了CSRF token。爲了幫助rest-assured解析更加順利,咱們可能須要提供一個CSRF域的名字(這裏咱們假設咱們使用的是Spring Security默認值,這樣咱們就可使用預約義的 springSecurity 表單認證配置(FormAuthConfig)):

1 given().
2         auth().form("John", "Doe", springSecurity().withCsrfFieldName("_csrf")).
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

這裏咱們告訴rest-assured去查找一個名爲"_csrf" 的 CSRF域(這樣不但效率變高了,也更不易出錯)。

  默認狀況下,CSRF的值是做爲請求參數發送的,可是咱們也能夠配置CSRF的值做爲header發送,那麼咱們須要這樣作:

1 given().
2         auth().form("John", "Doe", springSecurity().withCsrfFieldName("_csrf").sendCsrfTokenAsHeader()).
3 when().
4         get("/formAuth");
5 then().
6         statusCode(200);

5、OAuth受權

  爲了可以使用OAuth 1 和 OAuth 2(關於查詢請求參數簽名的機制),咱們須要添加 Scribe  到咱們的 classpath 中(若是使用的是 2.1.0版本或者是更老版本的rest-assured,請參考老版的rest-assured指南)。在maven中咱們能夠經過下面的方式來添加依賴:

1 <dependency>
2             <groupId>com.github.scribejava</groupId>
3             <artifactId>scribejava-apis</artifactId>
4             <version>2.5.3</version>
5             <scope>test</scope>
6 </dependency>

1.OAuth 1 認證

  OAuth 1 認證須要添加 scribe 到classpath中,使用 OAuth 1 認證咱們能夠這樣寫:

1 given().auth().oauth(..). ..

2.OAuth 2 認證

  從rest-assured的2.5.0版本開始,咱們使用 OAuth 2 能夠不依賴 scribe :

1 gien().auth().oauth2(accessToken). ..

這將會把 OAuth 2 的 accessToken 放到 header 中,若是想要使用更加顯示化的操做,能夠:

1 given().auth().preemptive().oauth2(accessToken). ..

之因此還存在 given().auth().oauth2(..) 這種寫法是由於須要向後兼容實際上他們作的是相同的事情)。若是咱們須要在一個查詢參數中提空 OAuth2 token 的話,那咱們就須要在classpath 中引入 scribe,而後這樣寫:

1 given().auth().oauth2(accessToken, OAuthSignature.QUERY_STRING). ..

6、自定義受權

  rest-assured容許咱們建立自定義的受權認證提供者。咱們想要實現自定義受權認證的話就須要實現 io.restassured.spi.AuthFilter 這個接口,並做爲過濾器(filter)來使用它。舉個例子,假如咱們的安全機制是由兩個header的值組合在一塊兒造成一個新的叫作 "AUTH"的header(這固然是不安全的)。那麼咱們能夠這樣寫(Java 8語法):

 1 given().
 2         filter((requestSpec, responseSpec, ctx) -> {
 3             String header1 = requestSpec.getHeaders().getValue("header1");
 4             String header2 = requestSpec.getHeaders().getValue("header2");
 5             requestSpec.header("AUTH", header1 + header2);
 6             return ctx.next(requestSpec, responseSpec);
 7         }).
 8 when().
 9         get("/customAuth").
10 then().
11   statusCode(200);

使用 AuthFilter 而不使用 Filter 的緣由是:當咱們執行 given().auth().none(). ... 時 AuthFilter 會被自動移除。

相關文章
相關標籤/搜索