Reputation: 2907
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:
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.return ;
and will after this filter work for other pages?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
Reputation: 85781
For question 1:
Filter#doFilter
will do these things:
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