Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a custom filter in spring security?

I want to receive some information per request, so I think instead of having a function for each request and obtaining those information from requests separately, it's better to have a filter.
So every request shall pass that filter and I gain what I want.


The question is: How can I write a custom filter?
Suppose it is not like any predefined spring security filters and it is totally new.

like image 207
Matin Kh Avatar asked Aug 13 '12 05:08

Matin Kh


People also ask

How do I create a custom filter in Spring?

There are a couple of possible methods: addFilterBefore(filter, class) adds a filter before the position of the specified filter class. addFilterAfter(filter, class) adds a filter after the position of the specified filter class. addFilterAt(filter, class) adds a filter at the location of the specified filter class.

How does a Spring Security filter work?

Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them.

Which filter class is required for Spring Security?

Servlet container does not have any information about the Spring's application context, but spring security needs security filters to execute the task.. Since DelegatingFilterProxy is a servlet filter, the application server register it as a normal filter in the context.


2 Answers

You can use the standard Java filter. Just place it after authentication filter in web.xml (this means that it will go later in the filter chain and will be called after security filter chain).

public class CustomFilter implements Filter{      @Override     public void destroy() {         // Do nothing     }      @Override     public void doFilter(ServletRequest req, ServletResponse res,             FilterChain chain) throws IOException, ServletException {              HttpServletRequest request = (HttpServletRequest) req;              Authentication authentication = SecurityContextHolder.getContext().getAuthentication();              Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());             if (roles.contains("ROLE_USER")) {                 request.getSession().setAttribute("myVale", "myvalue");             }              chain.doFilter(req, res);      }      @Override     public void init(FilterConfig arg0) throws ServletException {         // Do nothing     }  } 

Fragment of web.xml:

<!-- The Spring Security Filter Chain --> <filter>     <filter-name>springSecurityFilterChain</filter-name>     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter>  <filter-mapping>     <filter-name>springSecurityFilterChain</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>  <!-- Your filter definition --> <filter>     <filter-name>customFilter</filter-name>     <filter-class>com.yourcompany.test.CustomFilter</filter-class> </filter> <filter-mapping>     <filter-name>customFilter</filter-name>     <url-pattern>/VacationsManager.jsp</url-pattern> </filter-mapping> 

Also you can add handler that will be invoked after successfull login (you need to extend SavedRequestAwareAuthenticationSuccessHandler). Look here how to do this. And I think that this is even better idea.


UPDATED:
Or you can have this filter at the end of your security filters like this:

<security:filter-chain-map>     <sec:filter-chain pattern="/**"             filters="         ConcurrentSessionFilterAdmin,          securityContextPersistenceFilter,          logoutFilterAdmin,          usernamePasswordAuthenticationFilterAdmin,          basicAuthenticationFilterAdmin,          requestCacheAwareFilter,          securityContextHolderAwareRequestFilter,          anonymousAuthenticationFilter,          sessionManagementFilterAdmin,          exceptionTranslationFilter,          filterSecurityInterceptorAdmin,         MonitoringFilter"/> <!-- Your Filter at the End --> </security:filter-chain-map> 

And to have your filter, you may use this:

public class MonitoringFilter extends GenericFilterBean{ @Override public void doFilter(ServletRequest request, ServletResponse response,         FilterChain chain) throws IOException, ServletException {     //Implement this Function to have your filter working } 
like image 79
dimas Avatar answered Sep 22 '22 14:09

dimas


Just throwing this in the mix; how about using custom-filter inside http element:

<security:http auto-config="false" ...>   ...   <security:custom-filter position="FORM_LOGIN_FILTER" ref="MyCustomFilter" /> </security:http> 
like image 31
Ithar Avatar answered Sep 23 '22 14:09

Ithar