0

I'm trying to find the correct format for obtaining a Bearer Token using Keycloak.

Using Postman, I can obtain the token with no issue. If I click on code and Java - OkHttp I get this snippet:

OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=amc-front-shop-service&client_secret=18hsudf9-0132-4r6d-804f-b134837d0d29");
Request request = new Request.Builder()
  .url("https://kc.services.enderby.com/auth/realms/FE-SHOP/protocol/openid-connect/token")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();
Response response = client.newCall(request).execute();

When I try and model the Request in Rest Assured, I get a 400 error but unclear why:

 private static RequestSpecification keycloakServiceRequestSpec;
    private static String access_token;

    private void setKeycloakServiceSpecs() {
        keycloakServiceRequestSpec = new RequestSpecBuilder()
                .setContentType(ContentType.URLENC)
                .build();
    }

    @Test
    public String getAccessToken() {

        setKeycloakServiceSpecs();

        String clientId = "18hsudf9-0132-4r6d-804f-b134837d0d29";
        String clientSecret = "amc-front-shop-service";

        Response response =

        given()
                .auth().preemptive().basic(clientId, clientSecret)
                        .contentType("application/x-www-form-urlencoded")
                .formParam("grant_type", "client_credentials")
                .formParam("scope", "openid")
        .when()
                .post("https://kc.services.enderby.com/auth/realms/FE-SHOP/protocol/openid-connect/token").
         then().
                assertThat().statusCode(200).extract().response();

        String json = response.getBody().asString();
        JsonPath jsonPath = new JsonPath(json);

        access_token =  jsonPath.getString("access_token");

        logger.info("Oauth Token:" +  access_token);

        return access_token;

    }

Is it obvious where I am going wrong? Should I pass the key/values into a .body() ?

Steerpike
  • 1,712
  • 6
  • 38
  • 71
  • 2
    just a friendly reminder: if these client secrets in your code are real, you should deactivate the client secrets as fast as possible. right now, everybody could use these information to authenticate to your keycloak. – Sebu Nov 19 '20 at 13:20
  • @Sebu thank you; I have anonymized them all beforehand – Steerpike Nov 19 '20 at 13:32

1 Answers1

0

You are mixing client id/secret and also using basic auth. Also scope doesn't seems to be valid for client credentials flow. So try code:

        String clientSecret = "18hsudf9-0132-4r6d-804f-b134837d0d29";
        String clientId = "amc-front-shop-service";

        Response response =

        given()
                .auth().preemptive()
                .contentType("application/x-www-form-urlencoded")
                .formParam("grant_type", "client_credentials")
                .formParam("client_id", clientId)
                .formParam("client_secret", clientSecret)
Jan Garaj
  • 25,598
  • 3
  • 38
  • 59