本文介绍了Playframework 安全模块:你如何“登录"?在 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 设置为请求对象,然后调用您的 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 安全模块:你如何“登录"?在 FunctionalTest 中测试安全控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 14:47