如何使用 Rest Assured 从 KeyCloak 服务获取承载令牌

Posted

技术标签:

【中文标题】如何使用 Rest Assured 从 KeyCloak 服务获取承载令牌【英文标题】:How to get Bearer Token from KeyCloak Service using Rest Assured 【发布时间】:2021-03-02 20:51:10 【问题描述】:

我正在尝试找到使用 Keycloak 获取承载令牌的正确格式。

使用 Postman,我可以毫无问题地获取令牌。如果我点击codeJava - OkHttp 我得到了这个 sn-p:

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();

当我尝试在 Rest Assured 中为请求建模时,我收到 400 错误但不清楚原因:

 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;

    

很明显我哪里出错了吗?我应该将键/值传递给 .body() 吗?

【问题讨论】:

友情提示:如果您代码中的这些客户端机密是真实的,您应该尽快停用客户端机密。现在,每个人都可以使用这些信息对您的 keycloak 进行身份验证。 @Sebu 谢谢;我已经事先将它们全部匿名了 【参考方案1】:

您正在混合客户端 ID/秘密并使用基本身份验证。此外,scope 似乎对客户端凭据流无效。所以试试代码:

        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)

【讨论】:

以上是关于如何使用 Rest Assured 从 KeyCloak 服务获取承载令牌的主要内容,如果未能解决你的问题,请参考以下文章

rest-assured的日志使用介绍

rest-assured之静态导入及简单使用实例

如何使用 Rest Assured 在 Json 中构造空数组列表

如何使用 Rest Assured 在 GET url 中传递查询字符串参数?

REST API 自动化测试 利器Rest Assured(API接口自动化测试框架体系)

如何使用 Rest Assured 概念在控制台中显示 Json Array Response 正文