简体   繁体   English

Java servlet过滤器无法登录

[英]Java servlet filter not working on login

I've written a filter class to add a P3P header to every page. 我编写了一个过滤器类来为每个页面添加一个P3P标头。 I added this to my web.xml: 我把它添加到我的web.xml:

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

It adds the header to every page request, but it doesn't work when the user first logs in. The user submits the form to j_security_check , but the response doesn't include the header. 它会为每个页面请求添加标头,但在用户首次登录时不起作用。用户将表单提交给j_security_check ,但响应不包含标头。 How can I make my filter apply to the login request? 如何使我的过滤器适用于登录请求?

The login request forwards to the appropriate page. 登录请求转发到适当的页面。 By default, filters only apply to REQUEST dispatches. 默认情况下,过滤器仅适用于REQUEST调度。 You need to modify the web.xml as follows: 您需要修改web.xml,如下所示:

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

EDIT: I thought this had fixed it, but I was mistaken. 编辑:我认为这已经解决了,但我错了。

Doesn't work in Tomcat. 在Tomcat中不起作用。

I ended up having to use Tomcat valves. 我最终不得不使用Tomcat阀门。

Don't know about tomcat, but it works for me in jetty, just put your filter before spring filter : 不知道tomcat,但它在jetty中适用于我,只需将您的过滤器放在spring过滤器之前:

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

My web.xml 我的web.xml

<filter>
        <description>
        FBIS Filter</description>
        <display-name>Fbisfilter</display-name>
        <filter-name>Fbisfilter</filter-name>
        <filter-class>fbis.filter.Fbisfilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Fbisfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

and myfilter is 和myfilter是

package fbis.filter;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sqlconnection.SQLConnect;
import com.sun.security.auth.UserPrincipal;

import fbis.interfaces.abstractclasses.Connections;

/**
 * Servlet Filter implementation class Fbisfilter
 */
public class Fbisfilter extends Object implements Filter,Connections {
    public void destroy() {
    //  System.out.println("Filter Service finished");
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpresponse = (HttpServletResponse) response;
        System.out.println("FILTER INSIDE");
    // place your code here
        HttpSession session = httpRequest.getSession(true);
        String usrid = httpRequest.getParameter("txtuname");
        String pwd = httpRequest.getParameter("txtpassword");
        PreparedStatement pstmt;
        try {
            pstmt = con
                    .prepareStatement("SELECT l.Userid,n.First_name from Login_details_dtls l join New_Registration_dtls n on l.Userid=n.Userid where n.Userid=? AND l.pwd=?");
        pstmt.setString(1, usrid);
        pstmt.setString(2, pwd);
        ResultSet rs = pstmt.executeQuery();
        if (rs.next()) {
            session.setAttribute("usr", rs.getString("Userid"));
            session.setAttribute("usrname", rs.getString("First_name"));
        }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        chain.doFilter(httpRequest, httpresponse);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        System.out.println("Filter Service has started");
    }

}

Most servletcontainers indeed does not allow hooks on /j_security_check requests due to security reasons. 由于安全原因,大多数servletcontainer确实不允许挂钩/j_security_check请求。 Some older versions will do, but that should be fixed in newer versions. 一些旧版本可以,但应该在较新版本中修复。

The best way to hook on this anyway would be to check the presence of the user principal in the HttpSession which you've manually put there if absent. 无论如何,最好的方法是检查HttpSession中是否存在用户主体,如果不存在,你手动放在那里。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    UserPrincipal user = httpRequest.getUserPrincipal();
    HttpSession session = httpRequest.getSession();
    if (user != null && session.getAttribute("user") == null) {
        session.setAttribute("user", user);

        // First-time login. You can do your intercepting thing here.
    }
    chain.doFilter(request, response);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM