【问题标题】:How can I update keycloak's user details programmatically (java), without using rest admin api?如何在不使用 rest admin api 的情况下以编程方式(java)更新 keycloak 的用户详细信息?
【发布时间】:2017-11-24 07:34:21
【问题描述】:

我想更新用户详细信息。例如我从 keycloak 管理控制台在“演示”领域创建了用户(k1)。我有一个 java 客户端,我想更新用户(k1)的详细信息。更改用户 k1 的电子邮件地址。

我确实使用了管理客户端(Rest API),如下所示。

public void updateEmail(final String newEmailAddress) {
    try {
        final AccessToken accessToken = getToken();
        Keycloak keycloak = KeycloakBuilder.builder().serverUrl(this.getDeployment().getAuthServerBaseUrl())
                .realm(this.getDeployment().getRealm()).username("k1").password("123").clientId(ADMIN_CLIENT)
                .resteasyClient(new ResteasyClientBuilder().connectionPoolSize(10).build()).build();

        UserResource userResource = keycloak.realm(this.getDeployment().getRealm()).users()
                .get(accessToken.getSubject());
        UserRepresentation user = userResource.toRepresentation();
        user.setEmail(newEmailAddress);
        userResource.update(user);

    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

但我想在不使用管理客户端的情况下做同样的事情。

【问题讨论】:

  • 没有 REST 客户端怎么办?这是不可能的,或者您使用控制台或 REST 端点...
  • 我正在使用管理员帐户来更新用户的电子邮件。即keycloak 管理客户端。我需要另一种方式。
  • 您是否找到了更多关于让用户在不使用管理员凭据的情况下使用访问令牌更新其信息的推荐方法的信息?我一直在四处寻找,暂时找不到。
  • 这个答案中有两个选项,update-own-profile,用户服务或帐户配置文件主题。

标签: java rest keycloak


【解决方案1】:

我使用以下方法做到了。

    public void updateEmail(final String newEmailAddress)
        throws ClientProtocolException, IOException, HttpFailure, VerificationException {

    List<NameValuePair> formparams = new ArrayList<>();

    formparams.add(new BasicNameValuePair("stateChecker", "QW1iwts0YS8pC0JDosACq-2ZAJHtTW8HWN7KSgTV8rc"));
    formparams.add(new BasicNameValuePair("email", "5somebody@gmail.com"));
    formparams.add(new BasicNameValuePair("firstName", "1some"));
    formparams.add(new BasicNameValuePair("lastName", "1body"));

    KeycloakDeployment deployment = this.getDeployment();

    HttpPost post = new HttpPost("http://localhost:8080/auth/realms/demo/account/");
    ClientCredentialsProviderUtils.setClientCredentials(deployment, post, formparams);
    post.setHeader("Accept", "application/json");
    post.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    post.setHeader("Authorization", "Bearer " + this.getTokenString(10, TimeUnit.SECONDS));

    UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
    post.setEntity(form);

    HttpResponse response = deployment.getClient().execute(post);

    if (response.getStatusLine().getStatusCode() == 200) {
        print(response.getEntity().getContent());
    } else {
        print(response.getEntity().getContent());
        System.out.println(response.getStatusLine().toString());
    }
}

要完成上述操作,我需要更改我的 account.ftl(位于 *:*\keycloak-demo-3.1.0.Final\keycloak\themes\base\ account\account.ftl) 如下

    <#if stateChecker??>
        <input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker?html}">
    <#else>
        <input type="hidden" id="stateChecker" name="stateChecker" value=" ">
    </#if>

更改背后的原因是,我收到如下错误:

无法处理模板:org.keycloak.theme.FreeMarkerException:无法处理模板 account.ftl

【讨论】:

    【解决方案2】:

    您可以使用 jsoup-1.6.0.jar 来更新任何用户的详细信息,如下所示。

    public boolean updateAccountDetails(String name, String value) 
    {
    String url= getKeycloakAdapter().getDeployment().getAccountUrl();
    
    Document document = Jsoup.connect(url).get();
    if (document != null) {
      String formQuery = String.format("form[action^=%s]", url);
      Elements form = document.select(formQuery);
      if (!form.isEmpty()) {
        Elements inputs = form.select("input[value], input:not([disabled])");
        Element saveAction = form.select("button[value=Save]").first();
        inputs.add(saveAction);
        Map<String, String> mandatoryArguments = new HashMap<>();
        for (Element input : inputs) {
          mandatoryArguments.put(input.attr("name"), input.attr("value"));
        }
        mandatoryArguments.put(attributeName, newValue);
        Response response = Jsoup.connect(accountUrl)
            .data(mandatoryArguments)
            .method(Method.POST)
            .execute();
    
        Document finalDoc = response.parse();
        if (finalDoc != null) {
          Elements finalForm = finalDoc.select(formQuery);
          if (finalForm != null) {
            String newValueQuery = String.format("input[name=%s], input[value=%s]", name, value);
            Elements finalInputs = finalForm.select(newValueQuery);
            if (finalInputs != null) {
              return !finalInputs.isEmpty();
            }
          }
        }
      }
    }
    throw new IOException("Account page not found");
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-08
      • 2017-05-20
      • 2019-10-14
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-06-24
      • 2011-08-21
      相关资源
      最近更新 更多