Как применить фильтр до ограничения безопасности в 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, но у них есть вики-страница о том, как это сделать.