在 Keycloak 的更新用户配置文件中添加自定义验证
Add custom validation in Update User Profile in Keycloak
我在 login-update-profile.ftl
中添加了一个名为 organization
的自定义属性,它能够将用户的输入保存到 Keycloak 中。
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="user.attributes.organization" class="${properties.kcLabelClass!}">${msg("organization")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="user.attributes.organization" name="user.attributes.organization" value="${(user.attributes.organization!'')}" class="${properties.kcInputClass!}" aria-invalid="<#if messagesPerField.existsError('organization')>true</#if>"
/>
</div>
<#if messagesPerField.existsError('organization')>
<span id="input-error-organization" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('organization'))?no_esc}
</span>
</#if>
</div>
</div>
如何为该字段添加验证?我需要使它成为必填字段并满足特定条件(例如字符串的长度)。如果输入无效,将显示错误消息(就像我们在电子邮件或用户名字段中看到的那样)
我通过在 First Broker Login
流中创建 Review Profile
的自定义 SPI 找到了解决方案。以下是步骤:
- 确保您的 keycloak 版本是最新的稳定版本
- 打开 keycloak 的 github 存储库并找到
Review Profile
的相关 Java 代码。在撰写此答案时(keycloak v15.0.2),我们需要 3 个文件:AbstractIdpAuthenticator.java, IdpReviewProfileAuthenticatorFactory.java, and IdpReviewProfileAuthenticator.java
- 确保您能够使用这些文件构建
.jar
的 SPI
- 打开
IdpReviewProfileAuthenticator.java
并添加这个函数:
public List<FormMessage> getCustomAttributeError(String organization) {
List<FormMessage> errors = new ArrayList<>();
// You can add more conditions & parameters to be validated
if(Validation.isBlank(organization)){
errors.add(new FormMessage("organization", "missingOrganizationMessage"));
}
return errors;
}
- 转到
actionImpl
函数并在 profile.update((attributeName, userModel)
和 catch (ValidationException pve)
之间添加以下行:
if(getCustomAttributeError(profile.getAttributes().getFirstValue("organization")).size() > 0){
throw new ValidationException();
}
- 在
catch (ValidationException pve)
中 List<FormMessage> errors
之后添加此行:
List<FormMessage> extraErrors = getCustomAttributeErrors(profile.getAttributes().getFirstValue("organization"));
for(FormMessage error : extraErrors) {
errors.add(error);
}
- 打开
IdpReviewProfileAuthenticatorFactory.java
转到getDisplayType()
函数并将return值更改为"Custom Review Profile"
- 构建
.jar
,将其部署到 keycloak,创建我们命名为 Custom First Broker Login
的 First Broker Login
流的副本,并在 Custom First Broker Login
中替换 Review Profile
Custom Review Profile
- 通过单击它的操作按钮配置
Custom Review Profile
,给它一个别名,然后将 Update Profile on First Login
变成 on
- 将所需的身份提供者与新
Custom First Broker Login
绑定
我在 login-update-profile.ftl
中添加了一个名为 organization
的自定义属性,它能够将用户的输入保存到 Keycloak 中。
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="user.attributes.organization" class="${properties.kcLabelClass!}">${msg("organization")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="user.attributes.organization" name="user.attributes.organization" value="${(user.attributes.organization!'')}" class="${properties.kcInputClass!}" aria-invalid="<#if messagesPerField.existsError('organization')>true</#if>"
/>
</div>
<#if messagesPerField.existsError('organization')>
<span id="input-error-organization" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('organization'))?no_esc}
</span>
</#if>
</div>
</div>
如何为该字段添加验证?我需要使它成为必填字段并满足特定条件(例如字符串的长度)。如果输入无效,将显示错误消息(就像我们在电子邮件或用户名字段中看到的那样)
我通过在 First Broker Login
流中创建 Review Profile
的自定义 SPI 找到了解决方案。以下是步骤:
- 确保您的 keycloak 版本是最新的稳定版本
- 打开 keycloak 的 github 存储库并找到
Review Profile
的相关 Java 代码。在撰写此答案时(keycloak v15.0.2),我们需要 3 个文件:AbstractIdpAuthenticator.java, IdpReviewProfileAuthenticatorFactory.java, and IdpReviewProfileAuthenticator.java - 确保您能够使用这些文件构建
.jar
的 SPI - 打开
IdpReviewProfileAuthenticator.java
并添加这个函数:
public List<FormMessage> getCustomAttributeError(String organization) {
List<FormMessage> errors = new ArrayList<>();
// You can add more conditions & parameters to be validated
if(Validation.isBlank(organization)){
errors.add(new FormMessage("organization", "missingOrganizationMessage"));
}
return errors;
}
- 转到
actionImpl
函数并在profile.update((attributeName, userModel)
和catch (ValidationException pve)
之间添加以下行:
if(getCustomAttributeError(profile.getAttributes().getFirstValue("organization")).size() > 0){
throw new ValidationException();
}
- 在
catch (ValidationException pve)
中List<FormMessage> errors
之后添加此行:
List<FormMessage> extraErrors = getCustomAttributeErrors(profile.getAttributes().getFirstValue("organization"));
for(FormMessage error : extraErrors) {
errors.add(error);
}
- 打开
IdpReviewProfileAuthenticatorFactory.java
转到getDisplayType()
函数并将return值更改为"Custom Review Profile"
- 构建
.jar
,将其部署到 keycloak,创建我们命名为Custom First Broker Login
的First Broker Login
流的副本,并在Custom First Broker Login
中替换Review Profile
Custom Review Profile
- 通过单击它的操作按钮配置
Custom Review Profile
,给它一个别名,然后将Update Profile on First Login
变成on
- 将所需的身份提供者与新
Custom First Broker Login
绑定