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>
Related
I'm trying to set the SameSite attribute of the JSESSIONID cookie in our JHipster gateway, and upon trying to verify in Chrome, there is nothing showing up under the SameSite column for it.
Possibly of note: we're currently not deployed and running the application locally on HTTP (a localhost address). Running in TLS mode also has the same problem, however.
These are two things I've tried in order to get this working:
The second approach from the first answer here How to enable samesite for jsessionid cookie - a filter that is used in JHipster's SecurityConfiguration.java file in the configure() method.
import java.io.IOException;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
public class SameSiteFilter implements javax.servlet.Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
addSameSiteCookieAttribute((HttpServletResponse) response); // add SameSite=strict cookie attribute
}
private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}
#Override
public void destroy() {
}
}
A CookieSerializer which we got from an internal partner:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.CookieSerializer;
#Configuration
class CookieConfiguration {
#Bean
public static CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setSameSite("Lax");
return serializer;
}
}
Neither of these work. Is there something else we can try for this particular flavor of Spring?
In case you are using Tomcat (i.e. not WebFlux), the following configuration will add SameSite=strict to all cookies, including JSESSIONID:
#Configuration
public class SameSiteCookieConfiguration implements WebMvcConfigurer {
#Bean
public TomcatContextCustomizer configureSameSiteCookies() {
return context -> {
final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
cookieProcessor.setSameSiteCookies("strict");
context.setCookieProcessor(cookieProcessor);
};
}
}
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 wrote a custom Failure Handler in my Spring app
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler{
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
request.setAttribute("X-Http-Method-Override", "POST");
response.setHeader("X-Http-Method-Override", "POST");
redirectStrategy.sendRedirect(request, response, "/login");
}
}
What i'm trying to do is : in case of the failure login, i want to redirect to another page /login but with the POST method not GET method.
I tried to add attribute and setHeader but couldn't get what i want.
No!!! you cant't have a post redirect without a hack. for reference you can have a look at
https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect
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.
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.