On my web application, i have 2 main sections
- User
- Admin
I am using java session filter to check for user session and allow access to specific part of the website. Hence user have access to only the user pages section and administrator have access to admin section.
The session filter for Users is already implemented and it works fine. it checks for user(username and password from database – mysql) and gives access to the restricted subfolder, where I’ve xhtml pages.
if i wanted filters to check for admin section authentication(admin username and password are stored in db) and allow them access based upon their user level.
do i need to create 1 more filter – admin?
currently here is my implementation for User:
package com.shadibandhan.ControllerLayer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Cookie;
/**
*
* @author MUDASSIR
*/
public class SessionFilter implements Filter {
private ArrayList<String> urlList;
private String toGoTo = null;
private boolean userCookieExists = false;
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("****************************************");
System.out.println("***Session Filter Servlet initialized***");
System.out.println("****************************************");
String urls = config.getInitParameter("avoid-urls");
System.out.println("The urls to avoid are = " + urls);
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
System.out.println("This is the doFilter method");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String contextRelativeURI = null;
String contextRelativeURIForAdmin = null;
contextRelativeURI = request.getRequestURI().substring(request.getContextPath().length());
String contextPath = request.getContextPath();
String remoteHost = request.getRemoteHost();
String url = contextPath + contextRelativeURI;
System.out.println("-----------------> Servlet path is = " + contextRelativeURI);
System.out.println("-----------------> Context path is " + contextPath);
System.out.println("-----------------> URL is " + url);
System.out.println("-----------------> Remote Host is " + remoteHost);
boolean allowedRequest = false;
if (urlList.contains(contextRelativeURI)) {
allowedRequest = true;
}
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
System.out.println("Session is not present");
response.sendRedirect(contextPath);
return;
}
if (null != session) {
System.out.println("Session is present");
System.out.println("\nSession no. is = " + session.getId());
if (session.getAttribute("logged-in") == "true") {
System.out.println("Session logged-in attribute is true, " + session.getAttribute("sessionUsername") + " is logged in.");
RequestDispatcher dispatcher = request.getRequestDispatcher(contextRelativeURI);
dispatcher.forward(request, response);
return;
} else {
System.out.println("Session logged-in attribute is not true");
response.sendRedirect(contextPath);
return;
}
}
}
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
}
This is my web.xml mapping for the filter
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
com.shadibandhan.ControllerLayer.SessionFilter
</filter-class>
<init-param>
<param-name>avoid-urls</param-name>
<param-value></param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/com.shadibandhan.Restricted/*</url-pattern>
</filter-mapping>
Now, do i put the admin pages in the restricted folder also ? or i put them in another separate folder ?
I also seen the servlet authentication method mentioned here which recommends changes in the tomcat-users.xml file but i’ve my usernames and passwords in the db.
Please suggest recommended methods.
Well, the best way of securing a web application is using the container managed authentication so your application doesn’t need to handle the authentication and authorisation mechanism. That mechanism is called JAAS in the Java world.
Using the container managed authentication usually requires a bit of configuration on the servlet application – apart the changes required in your web application – but you’ll be more secure. Since you said that you were using Tomcat then I will give you the best answer I can based on that servlet container, others are configured in a different way.
1. Configure the Tomcat Realm
Fist of all, forget about the
tomcat-users.xml(it’s insecure) and decide how you are going to store your authentication data, an LDAP server? a database? which database?. Once you have decided you will need to modify yourserver.xmlfile underconffolder in Tomcat to add a new realm. The type of realm to create will depend in your previous decision.And let’s state the obvious:Add users to the storage.
2. Configure the web application
You’ll need now to configure the authentication method in your web application side. This is done modifying the
web.xmlfile under/WEB-INF.You may choose between Basic authentication or Form based authentication. I prefer using the latter as it allows me to provide with a customised form to the end users.
Some of the links I’m providing here describe the process step by step. They also include information regarding how to limit access to parts of your application to different kind of users, i.e.:
3. Knowing the user
After all that configuration your application should be able to know the username by means of the
getRemoteUser()method inHttpServletRequest.EDIT:
I’d suggest to use same table for admins and users and just make the difference between them using roles. If your
adminentity needs additional fields that shouldn’t be available for regular users then link both tables and just deal with theadminone whenHttpServletRequest.isUserInRole("ADMIN")returnstrue.