I'm developing a project using AspectJ where I use a filter for the http requests and responses. Basically I'm turning this project into a .jar and using this jar in a benchmark app where I perform some security tests. When I declare the filter on the benchmark app and on its web.xml it works fine, but if I put it in the project I'm developing (the jar file), then the benchmark app won't detect it... I've been told that if you use the latest version of web.xml, you don't need to declare the filter on web.xml and it should detect it automatically but it's not working. How can I get this to work?
The version I'm using in web.xml is this:
<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_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
filter class:
package main.java.filter;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import main.java.Configuration;
import main.java.HashTableCreation;
/**
* Servlet Filter implementation class MyFilter
*/
#WebFilter("/MyService/*")
public class MyFilter implements Filter
{
/**
* Default constructor.
*/
public MyFilter() {
}
/**
* #see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* #see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("###### FILTER before NO DRIVER...");
// HttpServletRequest req = (HttpServletRequest) request;
//
// String loggedIn = (String) req.getSession().getAttribute("login");
//
// if (loggedIn == null)
// {
// req.getRequestDispatcher("notLoggedIn.jsp").forward(request, response);;
// }*/
chain.doFilter(request, response);
System.out.println("###### FILTER after...");
}
/**
* #see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("Initializing filter...");
}
}
When you have a jar file in this case, it's simply a library. The servlet container isn't looking in your jar file for a web.xml file. That's simply not how it works. As you describe, your web.xml file must reference the filter explicitly otherwise the servlet container won't know to load it.
If you're trying to use annotation-based loading, per the spec, referenced in this post, it must be in WEB-INF/classes or in WEB-INF/lib as a jar.
Related
I want to create "pre" function. and in this function to check the session,
When some function in controller is called, I want that my "pre" function will called before it. and from the "pre" function I will pass the user to logIn page or to do the function.
something like this pseudo code:
if(!session)
return "redirect:login";
else
//calling to the selected function,
I saw some solutions to create this function, but the solution was to create it by: #ModelAttribute. and the problem is that with #ModelAttribute I didn't find any way to pass to another function in my controller.
More than, the selected function is always called after my #ModelAttribute finish,
How can I do that? there is a way to do something like this?
You can achieve that by using a servlet Filter. Here is a code snippet:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class RestrictionFilter implements Filter {
private static final String ACCES_PUBLIC = "/loginPage.jsp";
private static final String ATT_SESSION_USER = "user";
public void init( FilterConfig config ) throws ServletException {
}
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain ) throws IOException,
ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
final HttpSession session = request.getSession();
/**
* check if user is not connected.
*/
if (session.getAttribute( ATT_SESSION_USER ) == null) {
/* Redirection to login page */
response.sendRedirect( request.getContextPath() + ACCES_PUBLIC );
} else {
/** access granted for the user*/
chain.doFilter( request, response );
}
}
public void destroy() {
}
}
Then add the filter to your web.xml like below:
<filter>
<filter-name>RestrictionFilter</filter-name>
<filter-class>yourPackage.RestrictionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RestrictionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I have integrated an application on tomcat to use Jasig Cas. Now i have made the entire application(SampleApp) to be authenticated by CAS. But there is a certain URL that i need to bypass this authentication i.e. (SampleApp/HomeListener).
I have written a new application Filter for this. But what parameter do i need to modify in the Servlet request object to achieve this.
Filter
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class PatternFilter implements Filter {
private FilterConfig config;
public void destroy() {
//nothing here
}
/**
* Filters the HTTP requests
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filter) throws IOException, ServletException {
filter.doFilter(request, response);
}
public void init(FilterConfig filterConfiguration) throws ServletException {
// TODO Auto-generated method stub
config = filterConfiguration;
}
}
You do not need to write your own filter. Try adding the "ignorePattern" parameter to your authentication filter configuration in your web.xml.
<init-param>
<param-name>ignorePattern</param-name>
<param-value>http://<your url pattern to bypass>/(.*)</param-value>
</init-param>
My aim: Inject any text into response.
My Tries: On various small projects I had successfully implemented a filter which alters the response.
My Approach: You may find all code at the bottom of my questions !
The problem I am facing is HttpServletResponseWrapper.toString() is returning "" when I put my code to huge web application( My project has many filter, security, spring and struts framework together, jsp and FTL views). When used on simple project the HttpServletResponseWrapper.getStatus() returns 304. But when used on my big application, the status returned is 200 (indicating the request succeeded normally). What happens at the end is un-altered response rendered to browser.
I would appreciate if I get any pointers to this issue from you. Thanks in advance. Below is the code I am using:
LogFilter.java
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class LogFilter implements Filter {
public void init(FilterConfig config)
throws ServletException{
}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws java.io.IOException, ServletException {
System.out.println("BEFORE filter");
ServletOutputStream out = response.getOutputStream();
CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
System.out.println("status : "+responseWrapper.getStatus());
String servletResponse = new String(responseWrapper.toString());
out.write((servletResponse + " filtered all data without any issues <B>Hahaha :)</B>").getBytes()); // Here you can change the response
System.out.println("AFTER filter, original response: "
+ servletResponse.toString());
}
public void destroy() {
}
}
CharResponseWrapper.java
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response) {
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter() {
return new PrintWriter(output);
}
}
web.xml
.
.
.
.
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.<<hidden>>.web.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
.
.
.
Thank you very much #JBNizet. You are correct, I must override getOutputStream which I missed to implement. After searching more, I got an example at check answers. And it is working now. I am closing my question!
I have this code for filtering cache pages but facing some problems while compiling:
package bean.log.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//import javax.servlet.annotation.WebFilter;
public class LoginFilter implements Filter
{
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
try
{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("userHash") == null)
{
response.sendRedirect("/scape/applicationservices/fileshare/vm/login/login.jsp"); // No logged-in user found, so redirect to login page.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0);
}
else
{
chain.doFilter(req, res); // Logged-in user found, so just continue request.
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
After compiling the same I get following error:
D:\programs\MyPackage\bean\log\filter>javac LoginFilter.java
LoginFilter.java:14: bean.log.filter.LoginFilter is not abstract and does not ov
erride abstract method destroy() in javax.servlet.Filter
public class LoginFilter implements Filter
^
1 error
So I made changes in my code as below then it compiled but I am not getting desired result .The changes I made are:
I put #Override and implements Filter in comment and added public void init and public void destroy method
package bean.log.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//import javax.servlet.annotation.WebFilter;
public class LoginFilter // implements Filter
{
//#Override
public void init( )
{
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
try
{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("userHash") == null)
{
response.sendRedirect("/timescape/applicationservices/fileshare/vm/login/login.jsp"); // No logged-in user found, so redirect to login page.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0);
}
else
{
chain.doFilter(req, res); // Logged-in user found, so just continue request.
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void destroy( )
{
}
}
How to cofigure filter in web.xml
I configured it like below
<web-app>
<welcome-file-list>
<welcome-file>/WEB-INF/index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>noCacheFilter</filter-name>
<filter-class>bean.log.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>/scape/applicationservices/fileshare/vm/apps/*</url-pattern>
</filter-mapping>
</web-app>
I want this filter to restrict user to go back after LOGOUT to previous cache pages which are in my apps directory so I use that url-pattern.
how to achieve this filter to be worked.
A Java EE filter has to implement the interface you mentioned above: javax.servlet.Filter. Your problem doesn't lie in the Filter itself but in your Java usage. In this language when some non-abstract class implements the interface it or its parent has to implement all the declared methods. It means, that when the interface declares methods init(), doFilter() and destroy() then your class has to implement all of them even when the implementation should be empty. It means that you have to combine your both solutions:
uncomment implements Filter
let uncommented methods init() and destroy()
possibly uncomment #Override if you are using Java 6 or later
After that your filter should be fine, at least it should be executed when the web container processes some page matching URL specified in your web.xml mapping.
Anyway I guess that the logout URL is not usually so complicated so I would expect the mapping URL to be something like /logout. As I already mentioned the filter is executed only with pages matching the URL.
I'm trying to create a simulation for our web Portal and need to add custom HTTP headers. I am to assume the user has already been authenticated and these headers are just for storing user information (ie, "test-header: role=user; oem=blahblah; id=123;").
I've setup a filter to extract the header information but I can't find a way to inject the header information. They don't want it to be stored in cookies and maybe they will want to setup a global filter to include the headers on every page; is it possible to do something like this with the filter interface or through any other methods?
You would need to utilize HttpServletRequestWrapper and provide your custom headers in when the various getHeader* methods are called.
Maybe you can store that information in the session:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* #author rodrigoap
*
*/
public class UserInfoFilter implements Filter {
/**
* #see javax.servlet.Filter#destroy()
*/
public void destroy() {
// TODO
}
/**
* #see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest))
throw new ServletException("Can only process HttpServletRequest");
if (!(response instanceof HttpServletResponse))
throw new ServletException("Can only process HttpServletResponse");
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpRequest.getSession().setAttribute("role", "user");
httpRequest.getSession().setAttribute("id", "123");
filterChain.doFilter(request, response);
}
/**
* #see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException {
// TODO
}
}
You can use addHeader.