【问题标题】:How do I integration test Spring Boot with basic auth?如何使用基本身份验证集成测试 Spring Boot?
【发布时间】:2016-12-11 22:23:04
【问题描述】:

我有一个简单的 spring boot (1.3.5) 应用程序,它有一个简单的集成测试,在我引入 spring-boot-starter-security 之前一直有效。我在 application.properties 中设置了 security.user.name 和 security.user.password 这似乎是我需要密码保护我的端点(如果可能的话,我宁愿不要通过添加不必要的角色或安全配置来使事情复杂化)。但是现在集成测试失败了。我的测试课:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest(randomPort = true)
public class MyTestsIT {

    private TestRestTemplate template = new TestRestTemplate();
    private URL base;

    @Value("${security.user.name}")
    private String username;

    @Value("${security.user.password}")
    private String password;

    @Value("${local.server.port}")
    private int port;

    @Before
    public void beforeTest() throws MalformedURLException {
        base = new URL("http://" + username + ":" + password + "@localhost:" + port);
    }

    @Test
    public void testHello() throws IllegalStateException, IOException {
        System.err.println(base.toString() + "/hello");
        ResponseEntity<String> response = template.getForEntity(base.toString() + "/hello", String.class);
        assertEquals("Incorrect HTTP status returned", HttpStatus.OK, response.getStatusCode());
        String body = response.getBody();
        assertEquals("Incorrect response string.", "Hello World!", body);
    }
}

println 语句显示正确的 url,与我在 curl 中运行应用程序时使用的相同:

卷曲http://user:password@localhost:8181/hello

返回状态的断言失败并出现 401,我做错了什么?

【问题讨论】:

    标签: spring-security spring-boot


    【解决方案1】:
    @Component
    public class ServerMockUtils  {
    
        @Value("${user.name.auth}")
        private String userNameAuth;
    
        @Value("${password.name.auth}")
        private String passwordNameAuth;
    
        public MappingBuilder makeMappingBuilderSuccess(MappingBuilder mappingBuilder){
    
            return mappingBuilder
                    .withHeader("Accept", matching("application/json"))
                    .withQueryParam("format", equalTo("json"))
                    .withBasicAuth(this.userNameAuth, this.passwordNameAuth);
        }
    }
    
    public class MockForRestControllerConfig {
        @Autowired
        private ServerMockUtils serverMockUtils;
    
        @Value("${api.url.external.server}")
        private String apiUrlToExternalServer;
    
        public void setupStubForProcessingRequest(int portExternalServerMock) {
    
            String addressHost = "127.0.0.1";
    
            configureFor(addressHost, portExternalServerMock);
    
            setupResponseInCaseSuccessProcessingRequest();
        }
    
    
    
        private void setupResponseInCaseSuccessProcessingRequest(){
    
              UrlPathPattern urlPathPattern = urlPathEqualTo(this.apiUrlToExternalServer);
    
            MappingBuilder mappingBuilder = get(urlPathPattern);
    
            MappingBuilder mappingBuilderWithHeader = serverMockUtils.makeMappingBuilderSuccess(mappingBuilder);
    
            int statusOk = HttpStatus.OK.value();
    
            ResponseDefinitionBuilder responseDefinitionBuilder = aResponse().
                    withStatus(statusOk)
                    .withHeader("Content-Type", "application/json")
                    .withBodyFile("json/json.json");
    
            MappingBuilder responseForReturn = mappingBuilderWithHeader.willReturn(responseDefinitionBuilder);
    
            stubFor(responseForReturn);
        }
    
    }
    
        public ResponseEntity<ExternalServerDto> sendRequestToExternalServer(int portExternalServerMock) {
    
            String fullUrlToExternalServer = makeFullUrlToExternalServer(portExternalServerMock);
            UriComponentsBuilder uriComponentsBuilder = buildUriToExternalServer(fullUrlToExternalServer);
            String uriWithParamsToExternalServer = uriComponentsBuilder.toUriString();
    
            HttpHeaders requestHttpHeaders = getHeadersHttpHeaders();
            HttpEntity<Object> requestHttpEntity = new HttpEntity<>(null, requestHttpHeaders);
    
            return testRestTemplate.exchange(
                    uriWithParamsToExternalServer,
                    HttpMethod.GET,
                    requestHttpEntity,
                    ExternalServerDto.class
            );
        }
    
        private String makeFullUrlToExternalServer(int portExternalServerMock) {
    
            String prefixUrlToExternalServer = "http://127.0.0.1:";
            return prefixUrlToExternalServer +
                    portExternalServerMock +
                    this.apiUrlToExternalServer;
    
        }
    
        private HttpHeaders getHeadersHttpHeaders() {
    
            var requestHttpHeaders = new HttpHeaders();
            requestHttpHeaders.add("Accept", MediaType.APPLICATION_JSON_VALUE);
            addBasicAuth(requestHttpHeaders);
    
            return requestHttpHeaders;
        }
    
        private UriComponentsBuilder buildUriToExternalServer(String urlToExternalServer) {
    
            return UriComponentsBuilder.fromHttpUrl(urlToExternalServer)
                    .queryParam("format", "json")
        }
    
        private void addBasicAuth(HttpHeaders httpHeaders) {
    
            String auth = this.userNameAuth + ":" + this.passwordNameAuth;
    
            byte[] encodedAuth = Base64.encodeBase64(
                    auth.getBytes(StandardCharsets.US_ASCII));
    
            String authHeader = "Basic " + new String(encodedAuth);
    
            httpHeaders.add("Authorization", authHeader);
    
        }
    
    • pom.xml
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-rest</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>com.jayway.jsonpath</groupId>
                        <artifactId>json-path</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>com.github.tomakehurst</groupId>
                <artifactId>wiremock</artifactId>
                <version>2.27.2</version>
                <scope>test</scope>
            </dependency>
    

    【讨论】:

      【解决方案2】:

      天啊!我一发布我的问题,我就在Basic authentication for REST API using spring restTemplate 找到了答案。不知道为什么我之前的搜索没有成功。抱歉打扰了,希望这对其他人有帮助。

      @Before
      public void beforeTest() throws MalformedURLException {
          template = new TestRestTemplate(username, password);
          base = new URL("http://localhost:" + port);
      }
      

      【讨论】:

        猜你喜欢
        • 2017-11-12
        • 1970-01-01
        • 2019-04-25
        • 2017-11-02
        • 2017-02-25
        • 2014-09-22
        • 2017-07-31
        • 2011-03-22
        • 2015-11-04
        相关资源
        最近更新 更多