如何在不使用 rest admin api 的情况下以编程方式(java)更新 keycloak 的用户详细信息?
Posted
技术标签:
【中文标题】如何在不使用 rest admin api 的情况下以编程方式(java)更新 keycloak 的用户详细信息?【英文标题】:How can I update keycloak's user details programmatically (java), without using rest admin api? 【发布时间】: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,用户服务或帐户配置文件主题。 【参考方案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");
【讨论】:
以上是关于如何在不使用 rest admin api 的情况下以编程方式(java)更新 keycloak 的用户详细信息?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不登录 jwt django rest-framework 的情况下获取请求数据
如何在不使用 PHP 将文件写入磁盘的情况下将文件发布到 REST 服务器?
在不使用 Azure SDK 的情况下使用 REST API 将流上传到 Azure Blob 存储