java - 如何在 JBoss EAP6/AS7 中应用安全约束前的过滤器

标签 java jakarta-ee jboss security jaspic

编辑: 对于某些上下文,我使用自定义安全域并手动调用 request.login。我没有使用标准的 FORM 身份验证。

编辑: 看来我真正想要的是一种复制 <login-config> 的方法使用自定义的功能 <security-domain>在 jboss 而不是 j_security_check 中配置。

我需要能够在我的网络应用程序中做两件截然不同的事情。首先,我需要能够确定用户是否经过身份验证,如果没有,我想将他们重定向到登录页面。我正在为此使用过滤器。其次,我需要确定用户是否具有正确的角色才能查看我的 webapp 中的某些页面。似乎 web.xml 文件中的 security-constraint 标记是完成这项工作的合适工具,但这条规则总是先应用,然后再应用任何过滤器。这意味着用户在被拒绝访问页面之前永远不会有机会登录,因为他没有适当的角色。

我能想到的唯一解决方案是手动检查过滤器中的用户角色,而不是使用安全约束,但这并不是一个好的解决方案。我想知道我是否遗漏了什么,因为这似乎是一个非常常见的用例。作为引用,我的过滤器和示例安全约束粘贴在下面。

编辑: 我使用过滤器检查授权的原因是因为您只能为特定错误定义一个错误页面(在本例中为 403 访问被拒绝)。例如,角色为“customer”的人试图访问 searchCustomer 页面。我的安全约束将该页面限制为角色为“admin”或“user”的用户,因此生成 403 错误并将用户重定向到配置的错误页面 error.xhtml。第二个未登录的用户试图访问 main.xhtml。因为他没有登录,他缺少 3 个允许的角色之一,所以他也收到 403 错误并被重定向到 error.xhtml。但是,因为他没有登录,我宁愿将他重定向到登录页面。我看不出有什么方法可以使用安全约束和错误页面来区分这两个用例。

<security-constraint>
    <display-name>SecureApplicationConstraint</display-name>
    <web-resource-collection>
        <web-resource-name>SecureApplication</web-resource-name>
        <description>SecureApplication</description>
        <url-pattern>/main.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
        <role-name>user</role-name>
        <role-name>customer</role-name>
    </auth-constraint>
</security-constraint>
    <security-constraint>
    <display-name>SearchCustomerPage</display-name>
    <web-resource-collection>
        <web-resource-name>SecureApplication</web-resource-name>
        <description>SecureApplication</description>
        <url-pattern>/searchCustomer.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
        <role-name>user</role-name>
    </auth-constraint>
</security-constraint>
<error-page>
    <error-code>403</error-code>
    <location>/error.xhtml</location>
</error-page>

过滤器:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;   
    String uri = req.getRequestURI();

    if ((null != req.getUserPrincipal()) 
            || uri.endsWith("login.xhtml")
            || uri.endsWith("error.xhtml")
            || uri.contains(ResourceHandler.RESOURCE_IDENTIFIER)) {
        chain.doFilter(request, response);
    } else {
        HttpServletResponse res = (HttpServletResponse) response;
        res.sendRedirect(req.getContextPath() + "/login.xhtml?from=" + URLEncoder.encode(uri, "UTF-8"));
        return;
    }
}

最佳答案

您可以使用 Java EE 6 中的 JASPI/JASPIC API 执行此操作。

出于某种原因或其他 JBoss 要求您先激活此 API,但他们有一个关于如何执行此操作的 wiki 页面。

关于java - 如何在 JBoss EAP6/AS7 中应用安全约束前的过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11970514/

相关文章:

java - JBoss Wildfly 与 Jersey Web 服务部署错误 JBAS011859 : Naming context is read-only

java - JBoss Seam - @In 注释不能与不同属性的访问器方法同时使用吗?

java - Spring数据和Java泛型: How to combine multiple repository interfaces into one?

java - JWT 的 REST 安全性

java - Hibernate 与 MySQL 插入查询不一致

java - 使用 response.addCookie 时如何阻止 Jetty 更改 HTTP Expires header ?

java - Jboss 无法实例化类“org.jboss.logmanager.handlers.PeriodicRotatingFileHandle

java - 如何向表达式求解器添加运算顺序?

java - 无法解析插件 Java Spring

java - 通过 Glassfish Server 在 Java Servlet 中构建 Excel 表格