3

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

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

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

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

编辑: 我使用过滤器检查授权的原因是因为您只能为特定错误定义一个错误页面(在这种情况下,403 访问被拒绝)。例如,具有“客户”角色的人尝试访问 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;
    }
}
4

1 回答 1

3

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

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

于 2012-08-16T08:29:29.093 回答