Reputation: 19
I just wrote my first servlet filter and am already ahving problems. What I wanted to do was to make the filter handle authentication so that if a protected page was being requested, the filter would cut in and redirect to a login page. If the login succeeded, the filter would then redirect the user to the original page requested.
To give an example, one of the pages in question is a blog page. When a user clicks on "Leave a comment", he is redirected by the filter to a login page if he hasn't logged in already. Up until here, the filter does it's job. Then the user logs in and the username/password is checked. If they're ok, a session variable is set in the jsp and the page redirected to the comments page again. That request goes through the filter where I check the session variable. But no matter what, the session I get from the request seems to be a new one with no attributes set. I've tried calling request.getSession(false) and that seems to always return null. So not giving me the same session back that my jsp pages share.
I'm using tomcat 7.0.2. I don't know if this is tomcat specific or that there is just some very obvious thing that I'm missing.
Hope you cna help me.
Gisli
-- Update --
Here is my code. Guess that would be quite helpful :).
Basically, I have a login page, a blog page and a comments page. On the blog page, I have this link:
<a href="?page=blogg/komment.jsp?id=<%=blog.getID()%>"> Leave comment </a>
In my filter, I have this:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse)res;
HttpSession session = request.getSession(false);
Object userObj = null;
if( session != null ) {
userObj = session.getAttribute( "username" );
}
String contextPath = request.getContextPath();
String queryString = request.getQueryString();
String url = request.getRequestURI();
String page = request.getParameter("page");
String user = "<user>";
if( userObj != null )
user = userObj.toString();
if( page == null )
page = "<page>";
if( userObj == null && page.indexOf( "blogg/komment.jsp" ) != -1 ) {
session.setAttribute( "destPage", page );
response.sendRedirect( "index.jsp?page=blogg/login.jsp" );
}
System.out.println( ", Time "
+ new Date().toString() + " " + page + " " + user);
chain.doFilter(req, res);
}
So far, so good. This does redirect me to the login page. There, I do this:
String user = request.getParameter( "username" );
String pass = request.getParameter( "password" );
if( blog.confirmUser( user, pass ) ) {
session.setAttribute( "username", user );
Object destPageObj = session.getAttribute( "destPage" );
String destPage = "xxx";
if( destPageObj != null )
destPage = destPageObj.toString();
response.sendRedirect( "index.jsp?page=" + destPage );
%>
User exists
<%
}
else {
%>
User does not exist
<%
}
The string "User exists" is never supposed to be printed out, but it always appears and I get the login page back.
This is what I don't understand. I set the session variable "username" so that when the next request hits the filter, that variable should contain a value. But it always seems to be empty. In fact, when I called getSession(false) in the filter, I always got null back. Even though the session variable is supposed to always exist in the JSP if it hasn't expried.
I have tried passing session variables between pages and that works perfectly. But to set a session variable in a page and read it back in the next redirect always fails.
I feel like there's something terribly obvious that's staring me in the face and I've just worked too long on this to see it!
Hope you guys can help!
-- Further update --
Too little space to write as a comment :). What I want to do is this. I wanted to make my jsp pages independent of the login page. I.e. I wanted the filter to act as intermediary. So that when I send a user to my comments page, I don't need to worry about if he's logged in or not. If he's not logged in, the filter should redirect him to a login page and then send him on to the original destination. My blog is not the only thing that will require authentication and I wanted to have this logic all in the same place.
I don't want to pass the username/password, as request parameters for security reasons. I want both to remain as session attributes.
I don't understand what you mean when you say that what I'm doing in the login page should be done in the filter. I need a page to ask the user for his username and password and I don't want to send those along with the request. I saw an example here, link which is exactly what I want to do. Except that this doesn't work for some reason because I can't seem to be able to access the same session where I stored the username.
If I've totally got it wrong, could you point me to a web page where this is done properly? I've spent hours googling and all I have found are examples that seem to work for everyone but me :).
Upvotes: 0
Views: 6032
Reputation: 19
I resolved this after a lot of googling and digging around.
One thing I failed to mention, was that I had Tomcat running behind a proxy. And the proxy was not delivering the session cookie. In my virtual host definition, I had this:
<IfModule proxy_module>
ProxyRequests Off
ProxyPass / http://b6.is:8080/B6/
ProxyPassReverse / http://b6.is:8080/B6/
</IfModule>
So, everything is passed to the B6 webapp from the root.
All I had to do to translate the cookie path as well was to add this line:
ProxyPassReverseCookiePath /B6 /
Now it works perfectly.
Upvotes: 1