【问题标题】:How control access and rights in JSF?在 JSF 中如何控制访问和权限?
【发布时间】:2012-09-13 00:56:28
【问题描述】:

我想在用户登录我的系统后控制访问。

例如:

administrator : can add, delete and give rights to employee
employee : fill forms only
...

因此,在知道用户拥有哪些权限后,检查数据库,我想限制该用户可以看到和执行的操作。 有一种简单的方法吗?

编辑

@WebFilter("/integra/user/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest req = (HttpServletRequest) request;
        Authorization authorization = (Authorization) req.getSession().getAttribute("authorization");

        if (authorization != null && authorization.isLoggedIn()) {
            // User is logged in, so just continue request.
            chain.doFilter(request, response);
        } else {
            // User is not logged in, so redirect to index.
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/integra/login.xhtml");
        }
    }

    // You need to override init() and destroy() as well, but they can be kept empty.


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {
    }
}

【问题讨论】:

  • 您如何验证用户身份?通过容器管理的身份验证(j_security_checkrequest.login())还是通过会话属性上的自制 servlet 过滤器?
  • @BalusC,你好,我的朋友!好久没和你说话了。我正在使用你很久以前教我的一个 servlet 过滤器,我将把它贴在这里。
  • 您可以查看jguard.sourceforge.net/mvnsite/docbook/… 我们必须创建一个自定义 EL 函数来检查用户是否具有特定角色(例如用于渲染属性)
  • 我自己对此很好奇。无法真正回忆接缝 3 安全性的范围或 codi 中的类似概念,但它们可能有用。 Deltaspike 将为 v 0.4(下一个)iirc 添加这个。我也看过 apache shiro 但决定反对它。我决定暂时停止我的身份验证逻辑并等待 deltaspike 的 v.04

标签: jsf jsf-2 servlet-filters login-control


【解决方案1】:

嗯,这是一个相当广泛的主题。当您开始使用自制身份验证时,我将针对自制授权的答案。


如果模型设计合理,Java/JSF 中的角色检查本身就相对简单。假设一个用户可以拥有多个角色(在现实世界的应用程序中经常出现这种情况),您最终希望拥有类似的东西:

public class User {

    private List<Role> roles;

    // ...

    public boolean hasRole(Role role) {
        return roles.contains(role);
    }

}
public enum Role {

    EMPLOYEE, MANAGER, ADMIN;

}

这样您就可以在您的 JSF 视图中进行如下检查:

<h:selectManyCheckbox value="#{user.roles}" disabled="#{not user.hasRole('ADMIN')}">
    <f:selectItems value="#{Role}" />
</h:selectManyCheckbox>
<h:commandButton value="Delete" rendered="#{user.hasRole('ADMIN')}" />

在您的过滤器中:

String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/integra/user/admin/") && !user.hasRole(Role.ADMIN)) {
    res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}

最困难的部分是将这个 Java 模型转换为一个健全的数据库模型。根据具体的业务需求,有几种不同的方法,每种方法都有自己的(缺点)优势。或者您可能已经有一个数据库模型,您必须在该模型上建立您的 Java 模型(因此,您需要自底向上设计)?

无论如何,假设您使用的是 JPA 2.0(您的问题历史至少证实了这一点)并且您可以自顶向下设计,最简单的方法之一是将 roles 属性映射为 @ElementCollection针对user_roles 表。由于我们使用的是Role 枚举,因此不需要第二个role 表。同样,这取决于具体的功能和业务需求。

在通用 SQL 术语中,user_roles 表可能如下所示:

CREATE TABLE user_roles (
    user_id BIGINT REFERENCES user(id),
    role VARCHAR(16) NOT NULL,
    PRIMARY KEY(user_id, role)
)

然后将其映射如下:

@ElementCollection(targetClass=Role.class, fetch=FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name="user_roles", joinColumns={@JoinColumn(name="user_id")})
@Column(name="role")
private List<Role> roles;

这基本上就是您在 User 实体中需要更改的全部内容。


除了自制的身份验证(登录/注销)和授权(角色检查)之外,还提供了 Java EE container managed authentication,您可以使用它 login by j_security_check or HttpServletRequest#login()filter HTTP requests by &lt;security-constraint&gt; in web.xmlcheck the logged-in user by #{request.remoteUser}its roles by #{request.isUserInRole('ADMIN')} 等。

然后还有PicketLinkSpring SecurityApache Shiro等几个3rd 方框架,不过这都是不可能的:)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 2018-03-19
  • 2010-10-03
  • 1970-01-01
  • 2012-05-04
  • 2019-11-15
  • 2019-04-24
  • 2014-03-03
相关资源
最近更新 更多