【问题标题】:Issue with redirection in HttpFilterHttpFilter 中的重定向问题
【发布时间】:2015-12-08 12:30:41
【问题描述】:

我有一个如下所示的 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>

因此,现在当用户输入有效的用户 ID 和密码且用户名不是管理员时,用户将导航到 error.html。但是在此之后,当用户输入正确的凭据时,它会显示带有以下 URL 的空白页面

http://localhost:8080/webapps2/j_security_check

为什么会出现这个问题?

【问题讨论】:

  • 你分析过控制台日志吗?有没有抛出异常?
  • 能否请您发布validateUser 方法的代码?希望您使用 equals 方法验证用户名 if(username.equals("admin")){//valid} else {//invalid - redirect to error page}
  • 能否请您在部署描述符中发布过滤器定义?还是你在使用注释?
  • @HardikModha console.log 中没有异常。 validateUser 代码在问题中已更新,但我认为这在这里没有任何意义。
  • @jsfviky 问题用部署描述符内容更新,

标签: java servlets filter


【解决方案1】:

这就是问题发生的原因:登录协议是:

  1. 客户端发送对受保护资源的请求。
  2. 容器将配置好的表单登录页面发送给客户端。
  3. 客户填写登录表单并点击提交。
  4. 登录表单向服务器发送 j_security_check 请求。
  5. 容器处理 j_security 检查请求并验证 用户。

    5a。如果用户凭据良好,则容器会将请求从步骤 1 重定向到受保护的资源。

    5b。如果用户凭据错误,容器将重定向到配置的表单错误页面。

在您的应用程序中,如果用户不是“管理员”,您基本上会接管第 4 步和第 5 步,然后继续执行 5b。然后,您发送另一个 j_security 检查,该检查现在不是登录的一部分。

我认为,对于您的场景,您应该将登录表单页面更改为仅在用户是“管理员”时才允许提交。

【讨论】:

  • 在我的情况下,我正在执行第 4 步和第 5 步,并且只有当登录有效时,控件才会过滤检查用户名是否为 admin 的位置。管理员检查仅用于示例,但在实际场景中我必须执行许多检查。所以我无法在登录表单页面中执行此操作
猜你喜欢
  • 1970-01-01
  • 2014-02-23
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多