Проблема с перенаправлением в HttpFilter

У меня есть страница login.html, как показано ниже.

<h2>Hello, please log in:</h2>
<br><br>
<form action="j_security_check" method=post>
    <p><strong>Please Enter Your User Name: </strong>
    <input type="text" name="j_username" size="25">
    <p><p><strong>Please Enter Your Password: </strong>
    <input type="password" size="15" name="j_password">
    <p><p>
    <input type="submit" value="Submit">
    <input type="reset" value="Reset">
</form>

Также у меня есть страница с ошибкой, как показано ниже.

<h2>Login Incorrect, please log in:</h2>
<br><br>
<form action="j_security_check" method=post>
    <p><strong>Please Enter Your User Name: </strong>
    <input type="text" name="j_username" size="25">
    <p><p><strong>Please Enter Your Password: </strong>
    <input type="password" size="15" name="j_password">
    <p><p>
    <input type="submit" value="Submit">
    <input type="reset" value="Reset">
</form>
</html>

Оба настроены в web.xml и работают нормально. Теперь у меня есть фильтр, в котором я выполняю некоторые проверки (для минимизации кода я проверяю только имя пользователя == admin здесь), и если проверка не удалась, я перенаправляюсь на error.html, как показано ниже.

public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest)req;
        if(request.getUserPrincipal() != null){
            boolean result = validateUser(request.getUserPrincipal().getName());
            if(!result){
                HttpSession session  = request.getSession(false);
                session.invalidate();
                request.logout();
                request.getRequestDispatcher("/error.html").forward(req, resp);
                return;
            }
        }
        chain.doFilter(req, resp);

    }

Код для validateUser выглядит следующим образом:

public boolean validateUser(String name){
        boolean result = false;
        if("admin".equalsIgnoreCase(name)){
            result = true;
        }
        return  result;
    }

Отображение фильтра в web.xml похоже на

    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>com.listener.MyListener</listener-class>
  </listener>

  <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.Filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
      <!-- Roles -->
  <security-role>
    <description>Any rol </description>
    <role-name>*</role-name>
  </security-role>

      <!-- Resource / Role Mapping -->
  <security-constraint>
    <display-name>Area secured</display-name>
    <web-resource-collection>
      <web-resource-name>protected_resources</web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
      <description>User with any role</description>
      <role-name>*</role-name>
    </auth-constraint>
  </security-constraint>

  <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>Tomcat SALES Application</realm-name>
    <form-login-config>
            <form-login-page>/login.html</form-login-page>
            <form-error-page>/error.html</form-error-page>
        </form-login-config>
  </login-config>
</web-app>

Итак, теперь, когда пользователь вводит действительный идентификатор пользователя и пароль, а имя пользователя не является администратором, пользователь переходит к error.html. Но после этого, когда пользователь вводит правильные учетные данные, отображается пустая страница с указанным ниже URL-адресом.

http://localhost:8080/webapps2/j_security_check

Почему возникает эта проблема?


person robin    schedule 08.12.2015    source источник
comment
Вы проанализировали журнал консоли? Выбрасываются ли какие-либо исключения?   -  person Hardik Modha    schedule 09.12.2015
comment
Не могли бы вы опубликовать код для метода validateUser? Надеюсь, вы проверяете имя пользователя с помощью метода equals как if(username.equals("admin")){//valid} else {//invalid - redirect to error page}   -  person Hardik Modha    schedule 09.12.2015
comment
не могли бы вы опубликовать определение фильтра в своем дескрипторе развертывания? или вы используете аннотации?   -  person jsfviky    schedule 09.12.2015
comment
@HardikModha В console.log нет исключений. Код validateUser обновлен в вопросе, но я не думаю, что это имеет здесь какое-то значение.   -  person robin    schedule 11.12.2015
comment
@jsfviky Вопрос обновляется содержанием содержимого дескриптора развертывания,   -  person robin    schedule 11.12.2015
comment
@robin, пожалуйста, опубликуйте также весь свой дескриптор развертывания, вчера я попробовал его, и он работает. Просто хочу убедиться в своих ролях безопасности, ограничениях и относительных сопоставлениях.   -  person jsfviky    schedule 12.12.2015
comment
@jsfviky как вы перенаправляете на страницу с ошибкой?   -  person robin    schedule 14.12.2015


Ответы (1)


Вот почему возникает проблема: протокол для входа в систему:

  1. Клиент отправляет запрос на защищенный ресурс.
  2. Контейнер отправляет клиенту настроенную страницу входа в форму.
  3. Клиенты заполняют форму входа и нажимают «Отправить».
  4. Форма входа отправляет на сервер запрос j_security_check.
  5. Контейнер обрабатывает запрос проверки j_security и аутентифицирует пользователя.

    5а. Если учетные данные пользователя верны, контейнер перенаправляет запрос на защищенный ресурс с шага 1.

    5б. Если учетные данные пользователя неверны, контейнер перенаправляется на настроенную страницу формы-ошибки.

В вашем приложении, если пользователь не является администратором, вы в основном выполняете шаги 4 и 5 и переходите к 5b. Затем вы отправляете еще одну проверку j_security, которая теперь не является частью входа в систему.

Я думаю, что для вашего сценария вы должны изменить страницу формы входа, чтобы разрешить отправку только в том случае, если пользователь является «администратором».

person mmulholl    schedule 14.12.2015
comment
В моем случае я выполняю шаги 4 и 5, и только если логин действителен, элемент управления придет к фильтру, где я проверяю, является ли имя пользователя администратором или нет. Проверка администратора предназначена только для примера, но в реальном сценарии мне нужно выполнить много проверок. Поэтому я не смогу сделать это на странице формы входа. - person robin; 15.12.2015