DEV Community

Salad Lam
Salad Lam

Posted on

How to alter instance which built from Spring Security Configurer

Notice

I wrote this article and was originally published on Qiita on 16 September 2019.


Interface org.springframework.security.config.annotation.ObjectPostProcessor

On Spring Security configurer/builder, they are designed for to accept one or more instance contains ObjectPostProcessor interface. Below is the definition.

public interface ObjectPostProcessor<T> { <O extends T> O postProcess(O object); } 
Enter fullscreen mode Exit fullscreen mode

postProcess() method is for alter instance which pass into it.

There is a ObjectPostProcessor implementation class: org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor. The job of this class

  1. initialized instance (including inject prerequisite instance by using ApplicationContext) which passed into it
  2. it call SmartInitializingSingleton, DisposableBean interface methods of instance which processed before when same methods being called from ApplicationContext against it

A singleton instance of AutowireBeanFactoryObjectPostProcessor bean is created and be inject into configurer/builder when created. (This is the first ObjectPostProcessor if that configurer/builder accepts more than one ObjectPostProcessor)

Some configurer/builder can accept more than one ObjectPostProcessor. So alter instance which built from these configurer/builder is possible.

Example

First get a copy of my notice board example application. Add below file into info.saladlam.example.spring.noticeboard.support package.

package info.saladlam.example.spring.noticeboard.support; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.config.annotation.ObjectPostProcessor; public class CustomizeObjectPostProcessor implements ObjectPostProcessor<Object> { private static final Logger log = LoggerFactory.getLogger(CustomizeObjectPostProcessor.class); private String fromClass; public CustomizeObjectPostProcessor(String fromClass) { this.fromClass = fromClass; } public <T> T postProcess(T object) { log.info("Instance pass into {}: {}", this.fromClass, object.getClass().getName()); return object; } } 
Enter fullscreen mode Exit fullscreen mode

Then alter configure() method in class info.saladlam.example.spring.noticeboard.config.WebSecurityConfig to following.

 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // must put more restricted rule at first .antMatchers("/manage/*/approve").hasAuthority("ADMIN") .antMatchers("/manage/**").hasAuthority("USER") .and() .httpBasic().disable() .formLogin() .loginPage("/login") .loginProcessingUrl("/loginHandler") .failureUrl("/login?error=true") .permitAll() .and() .logout().logoutSuccessUrl("/"); http.authorizeRequests().withObjectPostProcessor(new CustomizeObjectPostProcessor("authorizeRequests")); http.formLogin().addObjectPostProcessor(new CustomizeObjectPostProcessor("formLogin")); http.httpBasic().addObjectPostProcessor(new CustomizeObjectPostProcessor("httpBasic")); http.logout().addObjectPostProcessor(new CustomizeObjectPostProcessor("logout")); } 
Enter fullscreen mode Exit fullscreen mode

Finally you may see following in log message.

2019-09-16 12:25:54.503 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into formLogin: org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint 2019-09-16 12:25:56.121 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into httpBasic: org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint 2019-09-16 12:25:57.009 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into httpBasic: org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler 2019-09-16 12:25:58.145 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into logout: org.springframework.security.web.authentication.logout.LogoutFilter 2019-09-16 12:25:59.732 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into authorizeRequests: org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler 2019-09-16 12:26:00.798 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into authorizeRequests: org.springframework.security.access.vote.AffirmativeBased 2019-09-16 12:29:01.005 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into authorizeRequests: org.springframework.security.web.access.intercept.FilterSecurityInterceptor 2019-09-16 12:29:03.527 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into formLogin: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 2019-09-16 12:29:03.933 INFO 5512 --- [ restartedMain] i.s.e.s.n.s.CustomizeObjectPostProcessor : Instance pass into httpBasic: org.springframework.security.web.authentication.www.BasicAuthenticationFilter 
Enter fullscreen mode Exit fullscreen mode

By designs CustomizeObjectPostProcessor class, you may alter instance pass into it.

Appendix: list of class instance created by Spring Security configurer/builder

Spring Security configurer/builder Class instance built
org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer org.springframework.security.authentication.dao.DaoAuthenticationProvider
org.springframework.security.config.annotation.web.configurers.CsrfConfigurer org.springframework.security.web.csrf.CsrfFilter
org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer org.springframework.security.web.access.ExceptionTranslationFilter
org.springframework.security.config.annotation.web.configurers.HeadersConfigurer org.springframework.security.web.header.HeaderWriterFilter
org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy, org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy, org.springframework.security.web.session.SessionManagementFilter
org.springframework.security.config.annotation.web.configurers.SecurityContextConfigurer org.springframework.security.web.context.SecurityContextPersistenceFilter
org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer org.springframework.security.web.savedrequest.RequestCacheAwareFilter
org.springframework.security.config.annotation.web.configurers.AnonymousConfigurer org.springframework.security.authentication.AnonymousAuthenticationProvider
org.springframework.security.config.annotation.web.configurers.ServletApiConfigurer org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
org.springframework.security.config.annotation.web.configurers.LogoutConfigurer org.springframework.security.web.authentication.logout.LogoutFilter
org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler, org.springframework.security.access.vote.AffirmativeBasedorg.springframework.security.web.access.intercept.FilterSecurityInterceptor
org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter

Top comments (0)