RestAssured oAuth2 http status code 401

2019-04-11 20:45发布

问题:

I'm trying to implement integration test using RestAssured library and Spring MVC REST oAuth2 secured endpoint.

This is my test:

@Test
public void testCreateDecision() throws Exception {
    File createDecisionJsonFile = ResourceUtils.getFile(getClass().getResource("/json/decisions/create-decision.json"));

    // @formatter:off
    final String createDecisionRequest = FileUtils.readFileToString(createDecisionJsonFile)
            .replace("{{name}}", "Test decision name")
            .replace("{{description}}", "Test decision description");
    // @formatter:on

    String accessToken = getAccessToken("user", "user");

    // @formatter:off
    given()
        .auth()
        .oauth2(accessToken, OAuthSignature.HEADER)
        .body(createDecisionRequest)
        .contentType("application/json; charset=UTF-8")
    .when()
        .post(format("http://localhost:%d/api/v1.0/decisions/create", port))
    .then()
        .statusCode(200)
        .contentType(ContentType.JSON)
        .body("id", notNullValue())
        .body("createDate", notNullValue());
    // @formatter:on

}

The accessToken is valid but I'm continuously getting 401 http code. What could be wrong with my code ?

回答1:

I know this is an old post, but just wanted to document this in case someone else needed the answer. I was able to implement using the following format:

First retrieve the token (in my case I did not store user tokens, jut got them before each test)

// we need to get the oauth token before we can perform the request
private void authenticateUser(String username, String password) {

    String response =
            given()
                .parameters("username", username, "password", password, 
                           "grant_type", "password", "scope", "read write", 
                           "client_id", "clientapp", "client_secret", "123456")
                .auth()
                .preemptive()
                .basic("clientapp","123456")
            .when()
                .post("/oauth/token")
                .asString();

    JsonPath jsonPath = new JsonPath(response);
    accessToken = jsonPath.getString("access_token");
}

And them on the test I used the retrieved token:

@Test
public void testGetUserDefaultUserOwner() {


    authenticateUser(testData.user1.getLogin(), "1");

    User user = 
        given()
            .auth().oauth2(accessToken)
            .contentType(ContentType.JSON)
            .accept(ContentType.JSON)
        .expect()
            .log().all()
            .statusCode(HttpStatus.OK.value())
        .when()
            .get(USER_RESOURCE, testData.user1.getId())
            .as(User.class);

    assertThat(user).isEqualTo(testData.user1);
}   

I am using Restassured and AssertJ for the tests, and SpringBoot with OAuth2 for the Rest APIs.



回答2:

I have reimplemented my test using OAuth2RestTemplate:

ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();

resourceDetails.setUsername("user");
resourceDetails.setPassword("user");
resourceDetails.setAccessTokenUri(format("http://localhost:%d/oauth/token", port));
resourceDetails.setClientId("clientapp");
resourceDetails.setClientSecret("123456");
resourceDetails.setGrantType("password");
resourceDetails.setScope(asList("read", "write"));

DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();

OAuth2RestTemplate auth2RestTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
auth2RestTemplate.setMessageConverters(asList(new MappingJackson2HttpMessageConverter()));

Assert.assertNotNull(auth2RestTemplate.getAccessToken());

DecisionRequest decisionRequest = new DecisionRequest(name, description, parentDecisionId);

auth2RestTemplate.postForObject(format("http://localhost:%d/api/v1.0/decisions/create", port), decisionRequest, Decision.class);


回答3:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://example.com/404/index.html">here</a>.</p>
</body></html>