【问题标题】:How to pass Spring SecurityContext to RestAssured如何将 Spring SecurityContext 传递给 RestAssured
【发布时间】:2018-05-10 00:54:07
【问题描述】:

我正在尝试为带有方法级安全控制器的 Spring-Boot 应用程序设置 RestAssured 测试。

例如,我有一个使用方法级别安全性的最小控制器


@RestController
public class DummyController {
    @GetMapping("/")
    @PreAuthorize("hasRole('TEST')") // removing this should make the test green
    public String test() {
        return "hello";
    }
}

和一个宽松的安全配置

@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll(); } }

那么这个使用 RestAssured 的简单测试失败了:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @RunWith(SpringRunner.class) public class DummyControllerITest { private static final Logger logger = LoggerFactory.getLogger(DummyControllerITest.class); @LocalServerPort private int port; @Test @WithMockUser(roles = "TEST") public void name() throws Exception { RestAssured.given() .port(port) .when() .get("/") .then() .statusCode(HttpStatus.OK.value()); } }

为什么这个测试会失败,即使模拟用户配置了正确的角色?

我已经对此进行了调试,似乎运行测试的线程中的 SecurityContext 设置正确,而处理 RestAssured 请求的线程中的 SecurityContext 未填充。但是……为什么?

【问题讨论】:

    标签: java spring-boot testing spring-security rest-assured


    【解决方案1】:

    所以我终于弄清楚出了什么问题。这是我发现的:

    注入 SecurityContext 仅在单元测试中有意义,但原始测试试图成为集成测试。

    有两种方法:

    1. 使测试成为适当的单元测试。那么你应该使用RestAssuredMockMvc.given() 而不是RestAssured.given()。例如,

      @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
      @RunWith(SpringRunner.class)
      public class DummyControllerITest {
        @Autowired
        private WebApplicationContext webAppContextSetup;
      
        @Test
        @WithMockUser(roles = "TEST")
        public void name() throws Exception {
            RestAssuredMockMvc.webAppContextSetup(webAppContextSetup);
            RestAssuredMockMvc.given()
                .when()
                    .get("/")
                .then()
                    .statusCode(HttpStatus.OK.value());
            RestAssuredMockMvc.reset();
        }
      }
      

      会起作用,但它只是一个单元测试。

    2. 使测试成为适当的集成测试。这将涉及构建适当的身份验证,并配置测试请求的主体,以便 生产代码 根据需要填充 SecurityContext。使用 RestAssured 走那条路线看起来像这样:

      @Test
      @WithMockUser(roles = "TEST")
      public void name() throws Exception {
          given()
                  .auth().basic("testuser", "password") // ######
                  .port(port)
              .when()
                  .get("/")
              .then()
                  .statusCode(HttpStatus.OK.value());
      }
      

    【讨论】:

      猜你喜欢
      • 2020-11-18
      • 1970-01-01
      • 2014-07-23
      • 2011-04-15
      • 1970-01-01
      • 2012-06-06
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      相关资源
      最近更新 更多