Spring Security @WithMockUser不适用于黄瓜测试

时间:2016-04-12 21:15:35

标签: java spring spring-security

我正在使用黄瓜测试来测试我的弹簧启动应用程序,启用弹簧安全性。除非我使用黄瓜测试运行我的测试套件,使用弹簧安全性进行一些测试,例如。

    @WithMockUser(username = "BROWSER", roles =
   {"BROWSER","ADMIN"})

失败。如果我将它们作为简单的junit测试以隔离方式运行,但是在运行黄瓜测试步骤时失败,这些测试确实有效。 问题看起来像春季安全测试模拟行为在我用黄瓜测试运行时不会被应用。

我的黄瓜测试运行类如下

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources", monochrome = true, format =
{"pretty", "html:src/main/resources/static/cucumber"})
public class CucumberTests
{

}

此外,我注意到使用<reuseForks>false</reuseForks>通过Maven运行时也是如此。如果未选中此选项,maven触发的测试用例运行也会失败。

更新

AbstractIntegrationTest类所有测试扩展

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Services.class,loader = SpringApplicationContextLoader.class)
//@IntegrationTest
@WebIntegrationTest(randomPort = true)
public abstract class AbstractIntegrationTest {

另一个不起作用的用例是使用这些注释是黄瓜特征条件,如下面

@When("^I apply a GET on (.*)$")
    @WithMockUser(username = "BROWSER", roles = { "BROWSER", "ADMIN" })
    public void i_search_with_rsql(String query) throws Throwable {
    result = mvc.perform(get(uri, query));
    }

对此有任何帮助或解决方法。

2 个答案:

答案 0 :(得分:2)

WithMockUser不适用于Cucumber。请改用黄瓜钩。

WithMockUser依赖于Spring测试上下文支持中的TestExecutionListener#beforeTestMethod。但是在使用CucumberRunner运行时不会调用它们。这是因为Cucumber运行的是由步骤而不是标准JUnit测试方法组成的方案。

选项1-安全上下文挂钩。您可以使用挂钩设置安全上下文,例如:

@ActiveProfiles("test")
@SpringBootTest(classes = MyServer.class)
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@AutoConfigureCache
public class MyServerContextHooks {

  @Before
  public void onBeforeScenario(final Scenario scenario) {
    // This method does nothing - context setup is done with annotations
  }
}

场景注释示例:

@WithAdminUser
Scenario: Run action as admin
    ...

在方案中使用注释的示例钩子:

public class TestUserHooks {

  @Before("@WithAdminUser")
  public void setupAdminUser() {
    SecurityContextHolder.getContext().setAuthentication(
            UsernamePasswordAuthenticationToken(
                "admin",
                "N/A",
                createAuthorityList("admin")));         
  }
}

选项2-身份验证步骤。另一种方法是使用特殊步骤将用户提供给嘲笑McMvc:

Scenario: Run action as admin
    Given I am logged in as admin
    ...

Stepdef示例:

public class SecurityTestSteps {

  @Autowired
  private MockMvcGlue mockMvc;

  @Autowired
  private OAuth2Mocks oauth2Mocks;

  @Autowired
  private TestUsers users;

  /**
   * Provides a one of predefined role-based authentications for the current request.
   */
  @Given("^I am logged in as (admin|editor|user)$")
  public void given_UserIsAuthenticatedWithRole(final String role) {
    switch (role) {
      case "admin":
        mockMvc.request().with(authentication(oauth2Mocks.auth(users.admin())));
        break;
      case "editor":
        mockMvc.request().with(authentication(oauth2Mocks.auth(users.edtior())));
        break;
      default:
        throw new CucumberException("Unsupported role <" + role + ">");
    }
  }
}

答案 1 :(得分:1)

根据您的意见,您需要确保应用Spring Security。您可以在参考文档的Setting Up MockMvc and Spring Security section中找到相关示例:

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;

// ...

@Before
public void setup() {
    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity()) // ADD THIS!
            .build();
}