Reputation: 129
hi I am working on one web application and facing issue while invoking servelets mentioned in web.xml.
Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>com.tpg.fileserver.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>AuthorizationFilter</filter-name>
<filter-class>com.tpg.fileserver.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthorizationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
The issue is that when i m trying to run my application I want the Authroization Filter to run first and then The File Servelet. Right now what is happening is the reverse of what i want. I also tried using 0 for File Servelet but that didnt helped.Below mentioned is my Filter Class code.
public class AuthorizationFilter implements Filter {
private static final String kNotAuthorizedUrl = "/NotAuthorized.html";
private static final String kTrustedHostsFileName = "trusted_hosts.txt";
private static final String kPublicFilesFileName = "public_files.txt";
private static final String TRUSTED_HOSTS = "TRUSTED_HOSTS";
private static final String PUBLIC_FILES = "PUBLIC_FILES";
private static Properties itsProperties = null;
public static final String kPropertySingleSignOnURL = "sso-url";
private static final String kPropertiesFileName = "metadata.properties";
private static boolean itsInitialized = false;
private static synchronized void initialize() {
if (!itsInitialized) {
try {
ProductMetadataAPI.setProduct(Version.kProductName, Version.kPhysical);
System.out.println("Inside Initialize");
PersistenceAPI.isDebugging = true;
JNDIConnectionFactory connFactory = new JNDIConnectionFactory("DataSource"); // IDB
SingleSignOnAuthenticator.setAuthenticationUrl(ConfigurationUtils.getProperties().getProperty(kPropertySingleSignOnURL));
SecurityAPI.setSecurity(
SecurityAPI.makeSecurity(
new StandardFactory(),
new PersistenceRepository(connFactory),
new CommonsBase64Codec(),
new SingleSignOnAuthenticator()));
itsInitialized = true;
} catch (Throwable e) {
LoggerClass.logErr(e);
}
}
}
private void requestAuthentication(HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.addHeader("WWW-Authenticate", "BASIC Realm=\"Single Sign-on\"");
LoggerClass.logInfoMsg("SSO not set. redirecting to siteminder......");
}
public void doFilter(ServletRequest inRequest, ServletResponse inResponse, FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest request = (HttpServletRequest) inRequest;
HttpServletResponse response = (HttpServletResponse) inResponse;
System.out.println("Before Setting Serervlet Context");
ConfigurationUtils.setCurrentServletContext(request.getSession().getServletContext());
System.out.println("After Setting Serervlet Context");
initialize();
if (request instanceof HttpServletRequest && (request.getMethod().equals("GET") || request.getMethod().equals("POST"))) {
String remoteHost = "", authorization = "", userName = "", password = "";
HttpServletRequest r = (HttpServletRequest)request;
Enumeration<String> e = r.getHeaderNames();
while (e.hasMoreElements()) {
String headerName = e.nextElement();
LoggerClass.logInfoMsg(headerName + "=" + r.getHeader(headerName));
}
LoggerClass.logDebugMsg("Proxy-Client-IP is :" + r.getHeader("Proxy-Client-IP"));
LoggerClass.logDebugMsg("Remote-Address-IP is :" + r.getRemoteAddr());
remoteHost = r.getHeader("Proxy-Client-IP");
if (remoteHost == null) {
remoteHost = r.getRemoteAddr();
LoggerClass.logDebugMsg("Remote-Address-IP ["+remoteHost + "] is requesting " + r.getRequestURI());
}else{
LoggerClass.logDebugMsg("Proxy-Client-IP ["+remoteHost + "] is requesting " + r.getRequestURI());
}
authorization = r.getHeader("Authorization");
if (authorization != null) {
final int index = authorization.indexOf(' ');
if (index > 0) {
final String[] credentials = StringUtils.split(new String(Base64.decodeBase64(authorization.substring(index))), ':');
if (credentials.length == 2) {
userName = credentials[0].toUpperCase();
password = credentials[1];
}
}
}
if (isSiteminderAuthenticationPresent(r)) {
LoggerClass.logInfoMsg("Inside Siteminder Logic ......");
chain.doFilter(request, response);
return;
} else if (isPublic(request) || isTrusted(remoteHost)) {
LoggerClass.logInfoMsg("Inside Public/Trusted Host Logic ......");
chain.doFilter(request, response);
return;
} else if (!isBasicAuthenticationPresent(userName, password)) {
LoggerClass.logInfoMsg("Failed in Basic Authentication Present.....");
requestAuthentication(response);
} else if (!isBasicAuthenticationValid(r.getSession(), userName, password)) {
LoggerClass.logInfoMsg("Failed in Basic Authentication Validation.....");
requestAuthentication(response);
} else {
chain.doFilter(request, response);
}
}
response.sendRedirect(request.getContextPath() + kNotAuthorizedUrl);
} catch (Exception e) {
LoggerClass.logErr(e);
throw new RuntimeException(e);
}
}
}
Below mentioned is my Servlet Partial Code :
public class FileServlet extends HttpServlet
{
public FileServlet()
{
System.out.println("In fileServlet");
this.itsRootDir = Common.getRequiredProperty(Common.kPropertyRootDir);
// some business logic
}
@Override public void doGet(HttpServletRequest inRequest, HttpServletResponse inResponse)
throws ServletException, IOException
{
String theRelFileName = Common.extractFileName(inRequest, false);
String theFileName = this.itsRootDir + theRelFileName;
File theFile = new File(theFileName);
//Some more Business Logic
}
}
Below present are the Sysout logs I got in application logs. Here I noticed one strange thing. First the call is going to File Servlet, Then Authorization Filter and then again to File Servlet.
[8/8/14 0:54:05:109 EDT] 0000002b SystemOut O In fileServlet
[8/8/14 0:54:05:161 EDT] 0000002b SystemOut O In Authoriazation Filter
[8/8/14 0:54:05:232 EDT] 0000002b SystemOut O In fileServlet
Upvotes: 3
Views: 5343
Reputation: 129
The answer for the above mentioned issue was that the constructor present in FileServlet was invoking before the filter was executed. To solve this problem I have changed the constructor to a public method which is being called in doget() method of Servlet. After this changed the filter was invoking first and then the servlet was being invoked.
Upvotes: 0
Reputation: 8946
The filters
are always initialized during webapp's
startup in the order as they are definied in web.xml
.
The servlets
are by default initialized during the first HTTP request on their url-pattern
only.
So in this case first The webapp's web.xml
will be parsed and every Filter
found in web.xml
will be created once and kept in server's memory
Now when a request comes from url pattern like /*
the container looks for the pattern finds the mapping for servlet
so initializes the servlet
. Then to process the request the filter
gets invoked.
To solve this you can change the url pattern of servlet.When the user enters some url pattern like /*
redirect to filter class and if he authenticates successfully then redirect to servlet specified with some other url pattern
or else redirect to error page
Upvotes: 1