Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to represent the Spring Security "custom-filter" using Java configuration?

What is the equivalent Java configuration for the Spring Security <custom-filter> tag?

<http>   <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/> </http> 

I tried

http.addFilter( new MyUsernamePasswordAuthenticationFilter() ) 

where the class extends the default filter, but it always employs the formLogin default.

My filter:

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication;  import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{      // proof of concept of how the http.addFilter() works      @Override     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)             throws AuthenticationException {         if (!request.getMethod().equals("POST")) {             throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());         }          System.out.println("running my own version of UsernmePasswordFilter ... ");          String username = obtainUsername(request);         String password = obtainPassword(request);          if (username == null) {             username = "";         }          if (password == null) {             password = "";         }          username = username.trim();          UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);          // Allow subclasses to set the "details" property         setDetails(request, authRequest);          return this.getAuthenticationManager().authenticate(authRequest);     } } 

The relevant configuration piece:

@Configuration @EnableWebMvcSecurity  // annotate class configuring AuthenticationManagerBuilder @ComponentScan("com.kayjed") public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {      @Override     protected void configure(HttpSecurity http) throws Exception {        http         .authorizeRequests()             .antMatchers("/resources/**","/signup").permitAll()             .anyRequest().authenticated()             .and()         .formLogin()             .loginPage("/login")             .permitAll()             .and()         .logout()             .permitAll();        http.addFilter(new MyUsernamePasswordAuthenticationFilter());     }      ... } 

Running the MVC app in the debugger always shows the login attempts authentication from the default UsernamePasswordAuthenticationFilter instead of my intention of employing the MyUsernamePasswordAuthenticationFilter class.

Anyways, I am not trying to get someone to debug code; rather, I would love to see a good example using Java configuration that performs the equivalent of the custom-filter element in the XML approach. The documentation is a bit terse.

like image 391
user3722706 Avatar asked Jun 09 '14 14:06

user3722706


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.

Which filter is configured to implement Spring Security?

Spring Security's web infrastructure is based entirely on standard servlet filters. It doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so it has no strong links to any particular web technology.

What is security filter in Java?

Overview. The purpose of the security filter is to enforce authorization policies for the web application. In other words, the security filter makes sure that users only access the resources for which they are authorized.

What is configure method in Spring Security?

The configure(final HttpSecurity http) method overrides the default HttpBuilder configuration. Because it's empty, it leaves the application without authorization or authentication.

How to configure a custom filter with spring security filter chain?

Let’s configure our custom filter with Spring security filter chain. Spring security provides few options to register the custom filter. We can use one of them based on our requirement. addFilterAfter (filter, class) –Adds a filter after the position of the specified filter class.

Does spring security support Java based configuration?

Spring Security provides support for Java Based Configuration from Spring Security 3.2. Java developers can easily configure Spring Security in the web application by Java based without the use of any XML. Spring Security’s web infrastructure is nothing but it is collection of standard servlet filters.

How do I define a security configurer in spring?

To start defining our configurer, first we need to extend the AbstractHttpConfigurer class: Here, the main method we need to override is the configure () method – which contains the security configuration that this configurer will apply to. In our example, we've registered a new filter after the last Spring Security filter.

What is springsecurityfilterchain in Java?

Java configuration creates a Servlet Filter known as the springSecurityFilterChain which is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, etc) within your application.


1 Answers

A few issues you may need to keep in mind:

  1. Your filter needs to be added before the standard UsernamePasswordAuthenticationFilter

     http.addFilterBefore(customUsernamePasswordAuthenticationFilter(),         UsernamePasswordAuthenticationFilter.class) 
  2. If you extend UsernamePasswordAuthenticationFilter your filter will return immediately without doing anything unless you set a RequestMatcher

     myAuthFilter.setRequiresAuthenticationRequestMatcher(     new AntPathRequestMatcher("/login","POST")); 
  3. All the configuration you do in http.formLogin().x().y().z() is applied to the standard UsernamePasswordAuthenticationFilter not the custom filter you build. You will need to configure it manually yourself. My auth filter initialization looks like this:

     @Bean public MyAuthenticationFilter authenticationFilter() {     MyAuthenticationFilter authFilter = new MyAuthenticationFilter();     authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));     authFilter.setAuthenticationManager(authenticationManager);     authFilter.setAuthenticationSuccessHandler(new MySuccessHandler("/app"));     authFilter.setAuthenticationFailureHandler(new MyFailureHandler("/login?error=1"));     authFilter.setUsernameParameter("username");     authFilter.setPasswordParameter("password");     return authFilter; } 
like image 75
Aner Avatar answered Sep 23 '22 08:09

Aner