【发布时间】:2016-09-24 04:37:49
【问题描述】:
我发现“The Login Page: Angular JS and Spring Security”非常有帮助,可以将 CSRF 保护添加到使用 Spring(安全等)实现 AngularJS 应用程序使用的 REST API 的 Web 应用程序中。 AngularJS 应用程序使用基于表单的登录 (JSESSIONID) 进行身份验证。这是这项工作的精髓:
- 登录页面隐藏输入栏
_csrf -
CsrfHeaderFilter将XSRF-TOKENcookie 添加到响应中 -
HttpSessionCsrfTokenRepository与setHeaderName("X-XSRF-TOKEN")
这一切正常(据我观察)。
我相信这会导致以下流程:
- 重定向到登录页面
- 登录页面包含
_csrf - 登录响应包含
XSRF-TOKENcookie - Angular 使用 cookie 值作为 REST 请求的
X-XSRF-TOKEN标头 - 幸福!
第 2 位似乎是普通的 Spring Security CSRF。 3.和4.似乎an attempt适应AngularJS CSRF support。
同样,这一切都可以正常工作,从测试登台实例开始。但是,一些集成测试被破坏,特别是使用 RestAssured 的测试。我还没有找到这种设置的 RestAssured 的好例子。 This 是我能找到的所有文档。
它建议使用formAuthConfig().withAutoDetectionOfCsrf() 或withCsrfFieldName("_csrf"),并在登录页面上做一个显式的get。使用它似乎处理登录罚款。但我不明白我如何告诉 RestAssured 转向使用 X-XSRF-TOKEN 标头。
我没有成功地完成了这段代码的很多变体,但我目前有这个:
FormAuthConfig baseConfig = new FormAuthConfig(loginPage, "username", "password");
FormAuthConfig config = baseConfig.sendCsrfTokenAsHeader();
config = config.withCsrfFieldName("X-XSRF-TOKEN");
RestAssured.authentication = RestAssured.form(userName, password, config);
given().auth().form("admin", "admin", baseConfig.withCsrfFieldName("_csrf"))
.when().get(loginPage)
.then().statusCode(200);
expect().statusCode(200)
.when().get(...); // line 246
这将获得以下输出:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 401 Unauthorized</title>
</head>
<body>
<h2>HTTP ERROR 401</h2>
<p>Problem accessing /application_name/rest/something. Reason:
</p>
<pre> Unauthorized</pre>
<hr/>
<i>
<small>Powered by Jetty://</small>
</i>
<hr/>
</body>
</html>
java.lang.IllegalArgumentException: Couldn't find the CSRF input field with name X-XSRF-TOKEN in response. Response was:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 401 Unauthorized</title>
</head>
<body>
<h2>HTTP ERROR 401</h2>
<p>Problem accessing /application_name/rest/something. Reason:
</p>
<pre> Unauthorized</pre>
<hr/>
<i>
<small>Powered by Jetty://</small>
</i>
<hr/>
</body>
</html>
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:74)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
at com.jayway.restassured.internal.filter.FormAuthFilter.filter(FormAuthFilter.groovy:85)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:49)
at com.jayway.restassured.filter.FilterContext$next.call(Unknown Source)
at com.jayway.restassured.internal.RequestSpecificationImpl.invokeFilterChain(RequestSpecificationImpl.groovy:994)
<snip>
at com.jayway.restassured.internal.ResponseSpecificationImpl.get(ResponseSpecificationImpl.groovy)
at com.company.application_name.AbstractJettyJsonRestTest.getCollection(AbstractJettyJsonRestTest.java:246)
at com.company.application_name.JsonRestIntegrationTest.testSomething(JsonRestIntegrationTest.java:74)
<snip>
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
非常感谢您的帮助!
【问题讨论】:
-
我认为您需要在 RestAssured static.javadoc.io/com.jayway.restassured/rest-assured/2.4.1/com/… 中使用 RequestSpecification@
-
谢谢你,但恐怕你不明白我是一个非常有经验的 RestAssured 用户,在问这个问题之前付出了很多努力,所以只是指出我所述库中最核心的类(接口)对我没有帮助,除非我在这里遗漏了一些东西。无论如何,再详细一点会有所帮助,谢谢!
标签: java angularjs spring-security csrf-protection rest-assured