如何在 Wildfly 10/ JB EAP 7 中进行身份验证后动态修改经过身份验证的用户的安全角色?



我在 Wildfly 10/JBoss EAP 7.0.8 上运行一个 JEE 应用程序,其中用户通过 JAAS 登录模块进行身份验证。 我的安全域定义如下:

<security-domain name="webapp" cache-type="default">
<authentication>
<login-module code="org.sso.keycloak.KeycloakLoginModule" flag="optional" module="deployment.ear">
<module-option name="keycloak-config-file" value="${keycloak.config}"/>
</login-module>
<login-module code="security.jboss.ServerLoginModule" flag="requisite" module="deployment.ear">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="unauthenticatedIdentity" value="nobody"/>
</login-module>
</authentication>
</security-domain>

然后,我的登录模块计算给定用户的角色,并通过 getRoleSets(( 方法返回它,该方法是登录模块的一部分。

身份验证过程工作正常,但是我现在有一个要求,即在经过身份验证的用户已经过身份验证后,我需要更改他们的角色。

如果我尝试为已经经过身份验证的用户再次调用 request.login((,它会抛出用户已登录的异常。

从请求对象中检索主体不会授予我访问其角色或组的权限。 我也找不到从SecurityContext中检索信息的方法。

如何为已经过身份验证的用户修改/添加角色?

经过相当多的挖掘,我想出了一个功能齐全的解决方案,但我不确定它是否干净。 无论如何,如果将来有其他人需要灵感,我会在这里发布它。

我很不安,没有一个更干净的机制来做到这一点。 此外,我不确定当并行发出多个线程/EJB 请求时,这是否会导致并发问题。 此外,我没有针对群集部署进行测试或验证,以确保在所有不同节点之间正确传播/更新安全角色/上下文。

RedHat 建议不要这样做,并且不支持 JBoss 平台。

// get the group containing the security roles from the user's current security context
Optional<Group> rolesGroup = SecurityContextAssociation.getSubject().getPrincipals(Group.class).stream().filter(p->"Roles".equals(p.getName())).findFirst();
if( rolesGroup.isPresent()){
Group roles = rolesGroup.get();
// remove all security roles from the current security context
Collections.list(roles.members()).stream().forEach(principal -> roles.removeMember(principal) );
// add the user's newly calculated security roles back into the user's security context
Arrays.stream(newRoles).forEach( roleName -> roles.addMember(new SimplePrincipal(roleName)));
}

最新更新