Web services 基于用户属性的keydape web服务访问控制

Web services 基于用户属性的keydape web服务访问控制,web-services,security,authentication,keycloak,keycloak-services,Web Services,Security,Authentication,Keycloak,Keycloak Services,我花了很多时间试图找到一种方法,根据用户组或角色限制对由KeyClope保护的web服务的访问。对于该解决方案,我得到的最接近的结果是实现一个自定义验证器脚本,该脚本执行用户属性检查,但是该解决方案有一个很大的缺点:失去了SSO功能 我使用了以下验证器脚本: AuthenticationFlowError=Java.type(“org.keydape.authentication.AuthenticationFlowError”); 函数身份验证(上下文){ 允许的变量组=['foo','bar

我花了很多时间试图找到一种方法,根据用户组或角色限制对由KeyClope保护的web服务的访问。对于该解决方案,我得到的最接近的结果是实现一个自定义验证器脚本,该脚本执行用户属性检查,但是该解决方案有一个很大的缺点:失去了SSO功能

我使用了以下验证器脚本:

AuthenticationFlowError=Java.type(“org.keydape.authentication.AuthenticationFlowError”);
函数身份验证(上下文){
允许的变量组=['foo','bar'];
var username=user?user.username:“匿名”;
var groups=user.getGroups();
var group_array=groups.toArray();
for(组_数组中的变量i){
var gn=group_数组[i].getName();
if(允许的组索引of(gn)>=0){
LOG.info(“授予作为LDAP组成员的用户“'+username+””的访问权限“'+gn+””);
返回context.success();
}    
}
LOG.info(“用户“+”用户名+”的访问被拒绝。因为不是以下任何LDAP组的成员:“+允许的组”);
context.failure(AuthenticationFlowError.IDENTITY\u PROVIDER\u已禁用,context.form().setError(
“用户没有查看此页面所需的LDAP组成员资格”,null).createForm(“error.ftl”);
返回;
}
验证流的屏幕截图:

不幸的是,自定义验证器脚本中的用户对象仅在传递“Username-Password-Form”auth部分时才会填充,否则用户对象为null,因此您无法检查用户属性,例如组或角色。这意味着用户每次都必须为他打算通过KeyClope访问的每个客户端(web服务)键入他们的凭据。 不幸的是,没有SSO功能对我们来说不是一个选项,因为我们正在运行10多个web服务


在仍然使用SSO的情况下,有没有办法通过KeyClope实现基于用户属性的客户端访问限制?我想知道,在“Cookie”auth部分通过后,用户信息是否可以以某种方式检索?我使用的是KeyClope 11.0.2版

您的方法是错误的。身份提供程序(例如,带有OIDC协议的密钥斗篷)提供身份验证,而不是授权。授权应该在您的应用程序代码中完成。应用程序代码必须根据访问令牌中提供的用户详细信息来决定已验证的用户是否有权执行操作(例如,在您的情况下是组成员身份,因此用户组必须在keydrope生成的访问令牌中可用-您已经在keydrope中以角色ldap mapper/group ldap mapper对其进行了本机支持)。我不会用你的方法破解身份验证过程。

到目前为止,你的脚本看起来不错。要恢复SSO功能,你只需要稍微调整你的流。将流分成两个子流(身份验证和授权)很重要。下面我链接了我系统中的一个示例。这样,即使登录是通过cookie或Kerberos完成的,角色检查也可以工作

此外,我还基于复合角色构建了脚本。通过这种方式,我可以轻松地将客户机与所需的角色链接起来。如果您有多个应限制为不同角色的客户机,则无需为每个客户机创建单独的流

AuthenticationFlowError=Java.type(“org.keydape.authentication.AuthenticationFlowError”);
函数身份验证(上下文){
var client=session.getContext().getClient();
var clientRole=client.getRole(“功能:验证”);
如果(!user.hasRole(clientRole)){
LOG.info(“由于用户“+user.username+”不是所需访问角色的成员,因此拒绝对客户端“+client.getName()+”的访问”);
上下文失败(
AuthenticationFlowError.IDENTITY\u提供程序\u已禁用,
context.form().setError(“您无权使用“+client.getName()+”。如果需要访问权限,请与帮助热线联系。”,null)
.createForm(“error.ftl”);
返回;
}
context.success();
}
然后,您只需在要限制的客户端中创建“feature:authenticate”(脚本中指定的名称)角色

…并将领域角色(在我的示例中是从LDAP服务器导入的)链接到上面创建的客户端角色: