Aleksander Monk
Aleksander Monk

Reputation: 2907

Servlet jsp, authentication filters

I have database in which I have information about user(username, password, role). I want to grant access to some pages only for logged in users with role "ROLE_USER" or "ROLE_ADMIN". (admin has both roles)

How I'm trying to do it:

I have filter in which I'm cheking is user logged in or no, etc.

@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();
        }


    }

I check if user is logged in, than get user's role. And for each role I will have some pages. Now I have only for anonymous (not logged in) user. I have few questions:

  1. I check if user is logged in and if not fc.doFilter(req, resp); . As I understand it must go to next "chain". And here I have only one "chain" so it must close doFilter. But it doesn't. Filter will end in other place.
  2. Can I end filter with just return ; and will after this filter work for other pages?
  3. Why after

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

    doFilter still works? We have new page , so it must stop this doFilter and make new doFIlter for new page.

Upvotes: 0

Views: 887

Answers (1)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85781

For question 1:

Filter#doFilter will do these things:

  • Pass the request and response to the next filter in the chain.
  • If there's no other filter in the chain, it will pass the request and response to the relevant Servlet to attend the request.
  • After attending the request, it will continue working with the last filter in the chain.

If you need to restrict access to a page, then do not use doFilter because this means that you accept the request from the client. Instead, use a forward or a redirect, depending on your requirements.

For question 2:

Yes, you can. It's a method, after all. Make sure you have written proper content in the response before calling return; in the doFilter. One way to write the response is using RequestDispatcher#forward or a redirect.

For question 3:

Because that's just a call of a method. Imagine you have a method like this:

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);
}

And you're asking: why the method didn't stop after calling the System.out.println LoC inside the if?. Simple: because nothing stopped the execution of the method.

Upvotes: 1

Related Questions