Explore Spring 4 Features
The recent Spring Version is 4, which is fully integrated with Java 8.
It has Got a lot of features in it bucket now.
In this Blog I am going to explore some of its features with some insight.
First thing that I will start with is: The Spring Java Config.
Recently I have been working on Spring Java Config, I have been trying to migrate one of my existing
Spring Projects (Which had Spring-Security 3.2, Aspects and other features) into a fully Java Based Configuration.
My objective is,there is going to be no XML configuration, even web.xml .
Spring Java config, though it is not a part of Spring 4. It has been introduced in Spring 3.2 .
I will be creating a project with no .xml files bearing any Spring based configuration.
All the configuration will be moved to Java.
In the cloud there are actually a lot of posts bearing a lot of useful information
regarding this Spring Java Based configuration and lot of them are really useful but
I really had hard time in configuring Java config in Spring with AbstractAnnotationConfigDispatcherServletInitializer,
when I am configuring Both Spring Security(Using AbstractSecurityWebApplicationInitializer ) and Spring MVC at the same time.
With AbstractAnnotationConfigDispatcherServletInitializer Only Spring MVC is working Fine
but somehow Spring Security is not in action So ultimately I had to resort to WebApplicationInitializer.
I found it quite handful and readable and easily configurable.
So, lets start with that.
The WebApplicationInitializer can be considered as synonymous to web.xml
The WebApplicationInitializer implementation that has been in effect is:
Next comes the Configuration class for dispatcher-servlet.xml .
This configuration class implements WebMvcConfigurerAdapter. The usage of this adapter classes has been done for following cases:
1) Registration of Custom WebArgumentResolvers .
2) Registration of Formatters and Converters.
3) ConfigureContentNegotiation support.
4) Adding Interceptors. etc.
The WebMvcConfigurerAdapter class is:
java configuration file for spring-security.xml .
We add this annotation to the @Configuration class to have the have the Spring Security
configuration defined WebSecurityConfigurerAdapter base class and overriding individual methods.
This annotation automatically enables CSRF support. So we have disabled it using configure(HttpSecurity http). Lets explore all the features the last two configuration Files one be one.
First start with WebMvcConfigurerAdapter implementation.
The @Import({SpringCustomPermissionEvaluatorConfig.class}) imports the Configuration in SpringCustomPermissionEvaluatorConfig. The content of SpringCustomPermissionEvaluatorConfig is:
By using @Import we can import some external configuration in the enclosing class.
@EnableWebMvc configures Spring MVC related configurations and is synonymous to
@ComponentScan({"com.springjavaconfig.controller","com.springjavaconfig.service"}) is similar to
@ImportResource("classpath:/aspect-config.xml") we can import configurations defined in xml in a Java config.
(This is another important and interesting feature we will experience its magic when we will explore Aspects configuration)
In my Next post I will continue from the point I am leaving here.
Till then Happy Coding.
It has Got a lot of features in it bucket now.
In this Blog I am going to explore some of its features with some insight.
First thing that I will start with is: The Spring Java Config.
Recently I have been working on Spring Java Config, I have been trying to migrate one of my existing
Spring Projects (Which had Spring-Security 3.2, Aspects and other features) into a fully Java Based Configuration.
My objective is,there is going to be no XML configuration, even web.xml .
Spring Java config, though it is not a part of Spring 4. It has been introduced in Spring 3.2 .
I will be creating a project with no .xml files bearing any Spring based configuration.
All the configuration will be moved to Java.
In the cloud there are actually a lot of posts bearing a lot of useful information
regarding this Spring Java Based configuration and lot of them are really useful but
I really had hard time in configuring Java config in Spring with AbstractAnnotationConfigDispatcherServletInitializer,
when I am configuring Both Spring Security(Using AbstractSecurityWebApplicationInitializer ) and Spring MVC at the same time.
With AbstractAnnotationConfigDispatcherServletInitializer Only Spring MVC is working Fine
but somehow Spring Security is not in action So ultimately I had to resort to WebApplicationInitializer.
I found it quite handful and readable and easily configurable.
So, lets start with that.
The WebApplicationInitializer can be considered as synonymous to web.xml
The WebApplicationInitializer implementation that has been in effect is:
public class SpringApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { System.out.println(" ********* Application StartUP in Progress ********** "); AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(SpringWebApplicationConfig.class); context.register(SpringSecurityApplicationConfig.class); //context.register(SpringCustomPermissionEvaluatorConfig.class); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/config/*"); /** * Register Character Encoding Filter */ FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class); characterEncodingFilter.setInitParameter("encoding", "UTF-8"); characterEncodingFilter.setInitParameter("forceEncoding", "true"); characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*"); //End of Character Encoding Filter /** * Register Spring security filter */ FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter("springSecurityFilterChain", DelegatingFilterProxy.class); springSecurityFilterChain.addMappingForUrlPatterns(null, false, "/*"); /** * Register Http Custom Filter */ FilterRegistration.Dynamic customSpringSecurityFilter = servletContext.addFilter("securityFilter", SecurityFilter.class); customSpringSecurityFilter.addMappingForUrlPatterns(null, false, "/config/*"); // Register Spring Social filter so that we can disconnect from providers /*FilterRegistration.Dynamic hiddenHttpMethodFilter = servletContext.addFilter("hiddenHttpMethodFilter", HiddenHttpMethodFilter.class); hiddenHttpMethodFilter.addMappingForUrlPatterns(null, false, "/*"); */ /** * Registration of Context Loader Listener */ servletContext.addListener(new ContextLoaderListener(context)); System.out.println(" ********* Application StartUP Completed ********** "); } }From the contents in the above Files it is Quite evident how all the congurations has been done.
Next comes the Configuration class for dispatcher-servlet.xml .
This configuration class implements WebMvcConfigurerAdapter. The usage of this adapter classes has been done for following cases:
1) Registration of Custom WebArgumentResolvers .
2) Registration of Formatters and Converters.
3) ConfigureContentNegotiation support.
4) Adding Interceptors. etc.
The WebMvcConfigurerAdapter class is:
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { public void addFormatters(FormatterRegistry registry) {} public void configureMessageConverters(ListSo, from the above class definition it is quite evident what actually is WebMvcConfigurerAdapter. Now the implementation class for WebMvcConfigurerAdapter is:> converters) {} public Validator getValidator() { return null; } public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {} public void configureAsyncSupport(AsyncSupportConfigurer configurer) {} public void addArgumentResolvers(List argumentResolvers) {} public void addReturnValueHandlers(List returnValueHandlers) {} public void configureHandlerExceptionResolvers(List exceptionResolvers) {} public MessageCodesResolver getMessageCodesResolver() { return null; } public void addInterceptors(InterceptorRegistry registry) {} public void addViewControllers(ViewControllerRegistry registry) {} public void addResourceHandlers(ResourceHandlerRegistry registry) {} public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {} }
@Configuration @Import({SpringCustomPermissionEvaluatorConfig.class}) @EnableWebMvc @ComponentScan({"com.springjavaconfig.controller","com.springjavaconfig.service"}) @ImportResource("classpath:/aspect-config.xml") public class SpringWebApplicationConfig extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers( ListBefore going into the details of WebMvcConfigurerAdapter implementation lets view theargumentResolvers) { // TODO Auto-generated method stub argumentResolvers.add(dataInjectArgResolver()); super.addArgumentResolvers(argumentResolvers); } @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(addressFormatter()); registry.addFormatterForFieldAnnotation(customDateAnnotationFormatterFactory()); } @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean public MultipartResolver multipartResolver() { org.springframework.web.multipart.commons.CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); commonsMultipartResolver.setMaxUploadSize(100000); return commonsMultipartResolver; } @Bean public HandlerMethodArgumentResolver dataInjectArgResolver() { return new CustomHandlerArgumentResolver(); } @Bean public Formatter addressFormatter() { return new AddressFormatter(); } @Bean public AnnotationFormatterFactory customDateAnnotationFormatterFactory() { return new CustomDateAnnotationFormatterFactory(); } @Bean public DataInjectObject dataInjectObject() { DataInjectObject dataInjObj = new DataInjectObject(); dataInjObj.setId(999); dataInjObj.setName("KOOOOOLLLL"); return dataInjObj; } }
java configuration file for spring-security.xml .
@Configuration @EnableWebSecurity public class SpringSecurityApplicationConfig extends WebSecurityConfigurerAdapter{ @Autowired public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user1").password("user1").roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() /*.antMatchers("/config/admin").hasRole("USER")*/ .antMatchers("/j_spring_security_check").permitAll() .antMatchers("/**").hasRole("USER") .and() .formLogin(); http.csrf().disable(); /* http.csrf().csrfTokenRepository(customCSRFTokenRepository()); http.csrf().requireCsrfProtectionMatcher(customCSRFRequestMatcher()); */ http.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler()); } @Bean public CustomCSRFRequestMatcher customCSRFRequestMatcher() { return new CustomCSRFRequestMatcher(); } @Bean public CustomAccessDeniedHandler customAccessDeniedHandler() { return new CustomAccessDeniedHandler(); } @Bean public CustomCSRFTokenRepository customCSRFTokenRepository() { return new CustomCSRFTokenRepository(); } }The annotation @EnableWebSecurity configures the Spring security configuration.
We add this annotation to the @Configuration class to have the have the Spring Security
configuration defined WebSecurityConfigurerAdapter base class and overriding individual methods.
This annotation automatically enables CSRF support. So we have disabled it using configure(HttpSecurity http). Lets explore all the features the last two configuration Files one be one.
First start with WebMvcConfigurerAdapter implementation.
The @Import({SpringCustomPermissionEvaluatorConfig.class}) imports the Configuration in SpringCustomPermissionEvaluatorConfig. The content of SpringCustomPermissionEvaluatorConfig is:
@Configuration @EnableGlobalMethodSecurity(prePostEnabled=true) public class SpringCustomPermissionEvaluatorConfig extends GlobalMethodSecurityConfiguration { /* * All the Method level secured Beans to be configured Here. * */ protected MethodSecurityExpressionHandler createExpressionHandler() { return expressionHandler(); } @Bean protected MethodSecurityExpressionHandler expressionHandler() { return defaultExpressionHandler(); } @Autowired public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user1").password("user1").roles("USER"); } @Bean public PriviledgeEvaluator priviledgeEvaluator() { return new CustomPriviledgeEvaluator(); } @Bean public CustomMethodSecurityExpressionHandler defaultExpressionHandler() { CustomMethodSecurityExpressionHandler methodSecurityExpressionHandler = new CustomMethodSecurityExpressionHandler(); methodSecurityExpressionHandler.setPermissionEvaluator(null); methodSecurityExpressionHandler.setPriviledgeEvaluator(priviledgeEvaluator()); return methodSecurityExpressionHandler; } }This configuration file corresponds to enabling global method security with custom Privilege Evaluator and Expression Handler.
By using @Import we can import some external configuration in the enclosing class.
@EnableWebMvc configures Spring MVC related configurations and is synonymous to
@ComponentScan({"com.springjavaconfig.controller","com.springjavaconfig.service"}) is similar to
@ImportResource("classpath:/aspect-config.xml") we can import configurations defined in xml in a Java config.
(This is another important and interesting feature we will experience its magic when we will explore Aspects configuration)
In my Next post I will continue from the point I am leaving here.
Till then Happy Coding.
Is this article still relevant to Spring Security 4.1?
ReplyDeleteThanks for this useful article. More than two years have passed, but I had the exact same problems as you had bringing Spring Security into action using an AbstractAnnotationConfigDispatcherServletInitializer...
ReplyDeleteThanks Andree for your feedback.
Delete