【发布时间】:2020-09-08 13:17:48
【问题描述】:
我有一个简单的 Spring Boot 应用程序,它使用 keycloak SSO 和自定义用户存储提供程序。 身份验证在没有用户角色的情况下工作正常。 但我需要知道如何将现有用户角色与自定义用户存储提供程序进行映射。 有谁知道如何将现有用户角色与 keycloak 用户存储提供程序映射?
【问题讨论】:
标签: spring-boot single-sign-on keycloak
我有一个简单的 Spring Boot 应用程序,它使用 keycloak SSO 和自定义用户存储提供程序。 身份验证在没有用户角色的情况下工作正常。 但我需要知道如何将现有用户角色与自定义用户存储提供程序进行映射。 有谁知道如何将现有用户角色与 keycloak 用户存储提供程序映射?
【问题讨论】:
标签: spring-boot single-sign-on keycloak
终于找到了一种映射角色的方法。
将角色添加到领域并覆盖 AbstractUserAdapterFederatedStorage.getRoleMappingsgetRoleMappings() 方法。
public Set<RoleModel> getRoleMappings() {
Set<RoleModel> roles = new HashSet();
Iterator rolesItr = userEntity.getRoles().iterator();
while(rolesItr.hasNext()) {
roles.add(realm.getRole(((Role)rolesItr.next()).getName()));
}
return roles;
}
【讨论】:
如果您使用的是user storage SPI,您很可能需要实现 UserLookupProvider 接口 (org.keycloak.storage.user.UserLookupProvider)。
例如,该接口中的方法之一是UserModel getUserByUsername(String username, RealmModel realm)
如您所见,该接口中的方法返回一个UserModel 对象。
UserModel 实现了RoleMapperModel 接口。您只需调用 UserModel::grantRole 方法并传递您想要的角色。
例子:
假设您有一个class MyUserDao {...},它从您的数据库中检索用户作为class MyUserModel {...} 实例。
public UserModel getUserByUsername(String username, RealmModel realm) {
Optional<MyUserModel> myUserOpt = myUserDao.getUserByUsername(username);
if (!myUserOpt.isPresent())
throw new AccessDeniedException();
MyUserModel myUser = myUserOpt .get();
UserModel keycloakUser = mapToKeycloakUserModel(myUser);
for (String roleName: myUser.getRoles())
userModel.grantRole(KeycloakModelUtils.getRoleFromString(realm, roleName));
return keycloakUser;
}
private UserModel mapToKeycloakUserModel(MyUserModel myUser) {...}
请注意,您必须使用 org.keycloak.models.utils.KeycloakModelUtils::getRoleFromString 加载角色,否则 UserModel::grantRole 将尝试重新创建角色,您最终会遇到异常。
【讨论】: