如何在不使用rest admin api的情况下以编程方式(java)更新keycloak的用户详细信息?

时间:2017-06-21 11:54:37

标签: java rest keycloak

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

我使用了Admin客户端(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();
    }
}

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

2 个答案:

答案 0 :(得分:-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

答案 1 :(得分:-1)

您可以使用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");

}