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 会被自动移除。

相关文章
相关标签/搜索