【问题标题】:Does Java EE security model support ACL?Java EE 安全模型是否支持 ACL?
【发布时间】:2011-04-06 00:05:47
【问题描述】:

我使用了带有 Glassfish v3.0.1 的 Java EE 6,我想知道 Java EE 安全模型是否支持 ACL,如果支持,它的粒度有多细?

已编辑
我通过 glassfish v3 使用 jdbc 领域实现安全性,该领域在运行时通过查看 password 字段和授权通过查看 role 字段来查看数据库中的表 USER 以检查身份验证。角色字段仅包含 2 个 ADMINISTRATORDESIGNER。所以它是用户和角色之间的一对一映射。在托管 bean 级别,我实现了这个

private Principal getLoggedInUser()
{
    HttpServletRequest request =
            (HttpServletRequest) FacesContext.getCurrentInstance().
                getExternalContext().getRequest();
    if(request.isUserInRole("ADMINISTRATORS")){
        admin = true;
    }else{
        admin = false;
    }
    return request.getUserPrincipal();
}

public boolean isUserNotLogin()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser == null)
    {
        return true;
    }
    return false;
}

public String getLoginUserName()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser != null)
    {
        return loginUser.getName();
    }
    return "None";
} 

通过调用isUserInRole,我可以确定用户是否为admin,然后JSF将适当地render内容。但是,这还不够细粒度(真正的快速背景信息:有多个项目,一个项目包含多个图纸)。因为如果你是DESIGNER,你可以看到所有项目的所有图纸(如果我只希望tom 处理项目A,而peter 将处理项目B,@987654334 @可以监督AB这两个项目。我希望在运行时,当我创建用户时,我可以专门设置他/她可以看到什么项目。有没有办法做到这一点? 注意:不止两个项目,以上示例仅用于演示

【问题讨论】:

    标签: java security jakarta-ee glassfish acl


    【解决方案1】:

    Java EE 安全模型对可能具有一个或多个“角色”的“主体”进行身份验证。

    在另一个维度中,您拥有需要可配置的“权限”或“功能”的服务和资源。

    在配置中,您可以确定哪些“主体”或“角色”具有哪些“权限”或“能力”。

    换句话说,是的,它支持 ACL,并且可以根据您的需要进行细粒度,但是您必须习惯该术语。

    Vineet 的回答是为每个项目 ID 创建“角色”的绝佳建议。由于无论如何都必须将人员分配到项目中,因此可以直接将人员添加到这些组中。或者,定时脚本可以根据角色更新组成员资格。后一种方法可能更可取,因为如果这些决策在一个地方而不是分散在管理代码中,则更容易验证安全性。

    或者,您可以使用“粗粒度”角色,例如设计师并利用数据库(或程序逻辑)来限制登录用户的视图

    SELECT p.* FROM projects p, assignments a WHERE p.id = a.projectId AND a.finishdate < NOW();
    

    @Stateless class SomeThing {
    
        @Resource SessionContext ctx;
    
        @RolesAllowed("DESIGNER")
        public void doSomething(Project project) {
            String userName = ctx.getCallerPrincipal.getName();
    
            if (project.getTeamMembers().contains(userName) {
                // do stuff
            }
        }
    
    }
    

    请注意,这里的粗粒度访问控制是通过注释而不是代码完成的。这可以将大量难以测试的样板代码移出代码并节省大量时间。

    有类似的功能可以渲染网页,您可以根据当前用户通常使用标签来渲染部分屏幕。

    另外,由于安全性是一个广泛涉及的问题,我认为使用提供的功能来获取上下文比传递像 isAdmin 这样的一系列布尔标志更好,因为这很快就会变成很乱。它增加了耦合,并且使类更难进行单元测试是另一回事。

    在许多 JSF 实现中,有一些标签可以帮助呈现可选的东西。以下是 Richfaces 和 seam 的示例:

    <!-- richfaces -->
    <rich:panel header="Admin panel" rendered="#{rich:isUserInRole('admin')}">
      Very sensitive information
    </rich:panel>
    
    <!-- seam -->
    <h:commandButton value="edit" rendered="#{isUserInRole['admin']}"/>.
    

    Here is an article 解释如何将其添加到 ADF

    【讨论】:

    • 我用jdbc领域写了一些代码来保证安全,但它只使用Principal,我不知道如何使用PermissionsCapabilities,你认为我可以发布一些代码吗?征求您的专家意见?
    • 这总是有帮助的,如果不是来自我,那么来自这里更有知识的人。
    • 我刚刚更新了我的帖子。如果你不介意,请指导我。非常感谢
    • 似乎您的第一个解决方案是创建一个ASSIGNMENT 的表,该表具有userIdprojectId 属性,告诉特定用户分配了哪些项目。我认为这是个好主意,我实际上也有同样的想法。他们的原因是我传递布尔值isAdmin,所以我可以使用JSF render 属性来确定我是否应该显示组件。 @RolesAllowed,禁止某些用户访问某些方法,但我认为我仍然必须使用布尔值 isAdmin,除非您有更好的方法来基于角色呈现组件。
    • 我添加了几个我看到的示例,用于从上下文中获取角色,而不是将其作为参数传递。 YMMV
    【解决方案2】:

    Java EE 安全模型实现了 RBAC(基于角色的访问控制)。对于 Java EE 程序员来说,这实际上意味着可以将访问资源的权限授予用户。资源可能包括文件、数据库甚至代码。因此,不仅可以限制对数据库中文件和表等对象的访问,还可以限制对可执行代码的访问。

    现在,可以将权限分组到最终链接到用户/主题的角色中。简而言之,这就是 Java EE 安全模型。

    根据您的问题描述,您似乎希望将两个不同的项目区分为两个不同的资源,因此有两个单独的权限对象或两个单独的角色来解释相同的问题。鉴于您已经拥有管理员、设计师等角色(更恰当地称为用户组),这在 Java EE 中无法轻松实现。原因是您根据资源的附加属性 - 项目 ID 来区分角色中用户对资源的访问。这在技术上属于称为 ABAC(基于属性的访问控制)的领域。

    在 Java EE 中实现 ABAC 的一种方法是在角色名称中携带授予角色的属性/属性。所以代替下面的代码:

    if(request.isUserInRole("DESIGNERS")){
        access = true;
    }else{
        access = false;
    }
    

    您应该执行以下操作。请注意用作分隔符的“:”字符,以将角色名称与随附的属性区分开来。

    if(request.isUserInRole("DESIGNERS"+":"+projectId)){
        access = true;
    }else{
        access = false;
    }
    

    当然,您的登录模块的某些部分应该被修改(在配置中或在代码中)以返回包含项目 ID 的角色,而不是简单的角色名称。请注意,所有这些建议的更改都需要针对问题进行全面审查 - 例如,应该禁止分隔符作为角色名称的一部分,否则很有可能执行权限提升攻击。

    如果证明上述实现很少,您可以查看像 Shibboleth 这样提供 ABAC 支持的系统,尽管我从未见过它在 Java EE 应用程序中使用。

    【讨论】:

    • 所以如果Designer 拥有多个项目的权限,那么我想它需要一些解析,但我想这没什么大不了的。但是我不确定当你谈论privilege escalation attacks时我是否理解。我认为角色名称支持看起来像这样:DESIGNERS:1234,但后来你说`一个应该不允许分隔符成为角色名称的一部分`。你能详细说明一下吗?
    • 如果您允许通过应用程序创建角色,那么确保角色名称不包含特殊字符(在这种情况下为分隔符)变得很重要。例如,如果内部角色名称(带有项目 ID)是 DESIGNERS:1234,那么如果您允许使用该名称构建角色名称,但可以访问项目 5678,则内部角色名称将为 DESIGNERS:1234:5678 .根据应用程序的编码方式,有可能获得对具有此类角色的人员的访问权限,从而获得对 1234 项目的访问权限,从而实现权限提升。
    • @Harry,如果您确实打算构建它,请记住,您将构成采用这种方法的极少数人。我建议您查看现成的解决方案,例如 Spring Security(如果您可以取消基于 Java EE 的访问控制)、jGuard 或 Shibboleth。提权攻击是我能想到的可能的攻击之一,但它不一定是唯一的。
    • 请查看ibm.com/developerworks/websphere/techjournal/0710_pattcorner/… 上的 IBM developerWorks 文章,该文章解决了与您类似的问题。
    • 当我研究的时候,我碰到了那篇文章,但因为是 2007 年,所以我放弃了。另外,我指的是 Acegi 框架,它是当今的 Spring 安全性。但是我读过很多地方说 Spring 安全性并不真正适合 Java EE。你怎么看?这是我读到的关于 Java EE 和 Spring Security 的帖子:stackoverflow.com/questions/2244819/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多