Servlet jsp,身份验证过滤器

时间:2015-02-02 21:59:17

标签: java jsp servlets servlet-filters

我有数据库,其中有关于用户(用户名,密码,角色)的信息。我想仅为具有角色“ROLE_USER”或“ROLE_ADMIN”的登录用户授予对某些页面的访问权限。 (管理员有两个角色)

我是怎么做的:

我有过滤器,我正在检查是用户登录还是没有,等等。

@WebFilter(urlPatterns={"/*"})
public class AuthorizationFilter implements Filter
{
    public boolean isUser=false;
    public boolean isAdmin=false;

    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain fc) throws IOException, ServletException
    {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        HttpSession session = httpReq.getSession();
        HttpServletResponse res = (HttpServletResponse) resp;
        if (httpReq.getSession().getAttribute("user") == null)
        {
            fc.doFilter(req, resp);
        }
        String login = (String) session.getAttribute("user");

        Connection con = Connector.getSimpleConnection();
        PreparedStatement pst = null;
        String sql = "select ROLE from user_roles where username = ?";
        try
        {
            pst = con.prepareStatement(sql);
            pst.setString(1, login);
            ResultSet rs = pst.executeQuery();
            while(rs.next())
            {
                if (rs.getString("ROLE").equals("ROLE_USER"))
                {
                    isUser = true;
                }
                else
                {
                    if (rs.getString("ROLE").equals("ROLE_ADMIN"))
                    {
                        isAdmin = true;
                    }
                }
            }

            if (isAdmin)
            {
                System.out.println("ADmin");
                fc.doFilter(req, resp);
            }
            if (isUser)
            {
                System.out.println("User");
                fc.doFilter(req, resp);
            }
            else
            {
                String path = httpReq.getServletPath();
                System.out.println(path);
                if (path.equals("/") || path.equals("/login") ||
                        path.equals("/welcome.jsp") || (path.equals("/register")))
                {
                    RequestDispatcher dis = httpReq.getRequestDispatcher(path);
                    dis.forward(httpReq, resp);
                    fc.doFilter(req, resp);
                }
                else
                {
                    RequestDispatcher dis = httpReq.getRequestDispatcher("/");
                    dis.forward(httpReq, resp);
                }

            }

        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }


    }

我检查用户是否已登录,而不是获取用户的角色。对于每个角色,我都会有一些页面。现在我只为匿名(未登录)用户。我几乎没有问题:

  1. 我检查用户是否已登录,如果不是fc.doFilter(req, resp);。据我所知,它必须转到下一个“链”。在这里,我只有一个“链”,所以它必须关闭doFilter。但事实并非如此。过滤器将在其他地方结束。
  2. 我可以仅使用return ;结束过滤,并在此过滤器之后为其他页面工作吗?
  3. 为什么在

    之后
     RequestDispatcher dis = httpReq.getRequestDispatcher("/");
     dis.forward(httpReq, resp);
    

    doFilter还能运作吗?我们有新页面,因此必须停止此doFilter并为新页面创建新的doFIlter。

1 个答案:

答案 0 :(得分:1)

问题1:

Filter#doFilter将执行以下操作:

  • 将请求和响应传递给链中的下一个过滤器。
  • 如果链中没有其他过滤器,它会将请求和响应传递给相关的Servlet以参加请求。
  • 在参与请求后,它将继续使用链中的最后一个过滤器。

如果您需要限制对页面的访问,请不要使用doFilter,因为这意味着您接受来自客户端的请求。相反,请根据您的要求使用转发或重定向。

问题2:

是的,你可以。毕竟,这是一种方法。在return;中调用doFilter之前,请确保您已在回复中写入了正确的内容。编写响应的一种方法是使用RequestDispatcher#forward或重定向。

问题3:

因为这只是对方法的调用。想象一下,你有这样的方法:

public void foo(int x) {
    if (x < 10) {
        System.out.println("x is less than 10, it's not acceptable.");
    }
    System.out.println("x value is: " + x);
}

你问:为什么在调用System.out.println 中的if LoC后方法没有停止。简单:因为没有什么能阻止方法的执行。