Как применить фильтр до ограничения безопасности в JBoss EAP6/AS7

Изменить: В некоторых случаях я использую собственный домен безопасности и вручную вызываю request.login. Я не использую стандартную аутентификацию FORM.

Редактировать: кажется, что то, что я действительно ищу, это способ воспроизвести <login-config> функциональность с использованием пользовательских <security-domain> настроен в jboss вместо j_security_check.

Мне нужно иметь возможность делать две разные вещи в моем веб-приложении. Во-первых, мне нужно иметь возможность определить, аутентифицирован ли пользователь, и если нет, я хочу перенаправить его на страницу входа. Я использую фильтр для этого. Во-вторых, мне нужно определить, есть ли у пользователя нужная роль для просмотра определенных страниц в моем веб-приложении. Похоже, что тег безопасности с ограничением в файле web.xml будет подходящим инструментом для этой работы, но это правило всегда применяется в первую очередь, перед любым фильтром. Это означает, что пользователю никогда не предоставляется возможность войти в систему до того, как ему будет отказано в доступе к странице, потому что ему не хватает соответствующей роли.

Единственное решение, которое я смог придумать, - это вручную проверять роли пользователей в фильтре, а не использовать ограничение безопасности, но это не похоже на хорошее решение. Мне интересно, есть ли здесь что-то, чего мне не хватает, так как кажется, что это довольно распространенный вариант использования. Для справки, мой Фильтр и пример ограничения безопасности вставлены ниже.

Редактировать: причина, по которой я использую фильтр для проверки авторизации, заключается в том, что вы можете определить только одну страницу ошибки для конкретной ошибки (в данном случае 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;
    }
}

1 ответ

Решение

Вы можете сделать это, используя JASPI/JASPIC API в Java EE 6.

По той или иной причине JBoss требует, чтобы вы сначала активировали этот API, но у них есть вики-страница о том, как это сделать.

Другие вопросы по тегам