Playframework Secure模块:您如何“登录"网站?在FunctionalTest中测试安全控制器? [英] Playframework Secure module: how do you "log in" to test a secured controller in a FunctionalTest?
问题描述
编辑:我正在使用Play!版本1.2(正式发布)
EDIT: I'm using Play! version 1.2 (production release)
我想测试由安全模块保护的控制器操作 类,因此我需要在测试控制器之前登录(否则,我将被重定向到登录页面).
I want to test controller actions that are secured by Secure module class, so I need to log in prior to testing my controller (otherwise I will be redirected to the login page).
在尝试执行安全操作之前,我已尝试登录.这是我的FunctionalTest的样子:
I've tried to log in prior to calling a secured action. Here's what my FunctionalTest looks like:
@Test
public void someTestOfASecuredAction() {
Map<String, String> loginUserParams = new HashMap<String, String>();
loginUserParams.put("username", "admin");
loginUserParams.put("password", "admin");
// Login here so the following request will be authenticated:
Response response = POST("/login", loginUserParams);
// The following is an action that requires an authenticated user:
Map<String, String> params;
params.put("someparam", "somevalue");
response = POST("/some/secured/action", params);
assertIsOk(response); // this always fails because it is a 302 redirecting to /login
}
单步执行代码,我已验证登录帖子是否有效-它将导致重定向响应,其位置设置为首页(表明登录成功).
Stepping through the code, I've verified that the login post works - it causes a redirect response with location set to the home page (which indicates a successful login).
但是在随后的对安全操作的调用中,我总是被重定向到 "/login"页面-表示我的上次登录不符合第二个POST请求.
But then in the subsequent call to a secured action, I am always redirected to the "/login" page - indicating that my previous login did not stick for the second POST request.
查看FunctionalTest的源代码,我看到有一个@Before拦截器可以清除所有cookie.我尝试在我自己的中间超类中覆盖此拦截器(以保留cookie),但这也不起作用.
Looking into the source code of FunctionalTest I saw there was an @Before interceptor that clears all cookies. I tried overriding this intercepter in my own intermediary superclass (to preserve the cookies), but that didn't work either.
编辑:我把play.mvc.Before拦截器与org.junit.Before混淆了-前者与Play一起使用!控制器,后者用于JUnit测试. FuncitonTest中的@Before是一个JUnit拦截器,因此它应该对cookie产生任何影响(因为它在测试运行之前就被运行了一次).
EDIT: I was confusing the play.mvc.Before interceptor with org.junit.Before - the former for use with Play! controllers, the latter for JUnit tests. The @Before in the FuncitonTest is a JUnit interceptor, so it should have any affect on cookies (since it gets run once prior to the test being run).
我不想为每个安全动作都编写Selenium测试-因为几乎所有安全动作都将被执行.有没有一种方法可以欺骗" Secure模块,使其相信您已通过身份验证?还是可以通过其他一些非常明显的方式来处理FunctionalTest中的这种(看似常见的)场景?
I do not want to have to write a Selenium test for every secured action - since almost all will be secured. Is there a way to "fool" the Secure module into believing you're authenticated? Or maybe some other very obvious way for handling this (seemingly common) scenario in a FunctionalTest?
预先感谢
标记
编辑:工作代码,Codemwnci的答案标记为正确
EDIT: Working code, Codemwnci's answer marked as correct
Codemwnci的答案是正确的.这是我的解决方法,用于将Cookie从一个请求保留到另一个请求:
Codemwnci's answer is correct. Here is my workaround for preserving the cookies from one request to the next:
@Test
public void someTestOfASecuredAction() {
Map<String, String> loginUserParams = new HashMap<String, String>();
loginUserParams.put("username", "admin");
loginUserParams.put("password", "admin");
Response loginResponse = POST("/login", loginUserParams);
Request request = newRequest();
request.cookies = loginResponse.cookies; // this makes the request authenticated
request.url = "/some/secured/action";
request.method = "POST";
request.params.put("someparam", "somevalue");
Response response = makeRequest(request);
assertIsOk(response); // Passes!
}
推荐答案
我认为@Before拦截器的作用肯定有误解.它在执行测试之前执行.如果您的测试随后使您登录,则此事件将在执行@Before代码之后发生,并且安全模块的结果应保存到Cookie中.
I think there must be a misunderstanding of what the @Before interceptor does. It executes before your test is executed. If your test then logs you in, then this event happens AFTER the @Before code has been executed and the results of the secure module should be saved to the Cookie.
因此,我只能假定未随以下请求发送Cookie,因此,我建议尝试以下操作...
Therefore, I can only assume that the Cookie is not being sent with the following request, therefore, I would suggest trying the following...
登录后立即从Response对象中获取安全cookie所使用的cookie.创建一个Request对象,并将Cookie设置为request对象,然后调用POST方法,传入您的请求对象.
get the cookie used by the secure cookie from the Response object immediately following your login. Create a Request object and set the Cookie to the request object, then call your POST method, passing in your request object.
我尚未测试此代码,因此不确定如何混合预构建的请求对象并传递URL,但是不确定还有什么建议.
I have not tested this code, so not sure how it is going to react to mixing a pre-built request object, and passing in a URL, but not sure what else to suggest.
这篇关于Playframework Secure模块:您如何“登录"网站?在FunctionalTest中测试安全控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!