Sunday, 29 December 2019

This week 3/2019 - WebApp with Spring Security

Yesterday I did small exercise. I upgraded one of my old applications from xml (web.xml) configuration to class version as a first step to later upgrading.
There was no problems until I run application and all world could see everything what only an authorized user should see.

I couldn't find simple example which I could I adopt to my needs so I decided to describe this by my self.

Some examples proposed to extend AbstractSecurityWebApplicationInitializer, other proposed to import just import security configuration but it wasn't work as I expected. I created servlet initializer as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class StockDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{MySecurityConfig.class, MyRootConfig.class};
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[]{MyServletConfig.class};
  }

  @Override
  protected String[] getServletMappings() {
    return new String[]{"/"};
  }

  protected Filter[] getServletFilters() {
    return new Filter[]{new DelegatingFilterProxy("springSecurityFilterChain")};
  }

}


MySecurityConfig I extended with WebSecurityConfigurerAdapter and implemented configure method as below:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@EnableWebSecurity
@Configuration
@ComponentScan("org.my")
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  private final MyLogoutSuccessHandler myLogoutSuccessHandler;
  private final MyAuthenticationProviderImpl myAuthenticationProvider;

  public SecurityConfig(final MyLogoutSuccessHandler myLogoutSuccessHandler,
                        final MyAuthenticationProviderImpl myAuthenticationProvider) {
    this.myLogoutSuccessHandler = myLogoutSuccessHandler;
    this.myAuthenticationProvider = myAuthenticationProvider;
  }


  @Autowired
  public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(myAuthenticationProvider);
  }

  @Override
  public void configure(final WebSecurity web) {
    web.ignoring()
       .antMatchers("/css/**")
       .antMatchers("/img/**");
  }


  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    formLogin(http);
    logout(http);
    headers(http);
    authorizeRequests(http);
    sessionManagement(http);
  }
.......
}


MyServletConfig looks like


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@EnableWebMvc
@Configuration
@ComponentScan({"org.**.mvc"})
public class StockServletConfig implements WebMvcConfigurer {

  @Override
  public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/img/**").addResourceLocations("/img/");
    registry.addResourceHandler("/css/**").addResourceLocations("/css/");
  }

  @Bean
  ViewResolver viewResolver() {
    return new InternalResourceViewResolver("/WEB-INF/jsp/", ".jsp");
  }

  @Bean
  PropertiesFactoryBean propertiesFactoryBean() {
    final PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    propertiesFactoryBean.setLocation(new ClassPathResource("version.properties"));
    return propertiesFactoryBean;
  }

  @Bean
  ObjectMapper customObjectMapper() {
    return new CustomObjectMapper();
  }

  @Bean
  LocaleResolver localeResolver() {
    final SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
    sessionLocaleResolver.setDefaultLocale(ENGLISH);
    return sessionLocaleResolver;
  }

  @Bean
  public LocaleChangeInterceptor localeChangeInterceptor() {
    final LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName("lang");
    return localeChangeInterceptor;
  }

  @Override
  public void addInterceptors(final InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
  }

  @Override
  public void configureMessageConverters(final List<HttpMessageConverter<?>> messageConverters) {
    messageConverters.add(new MappingJackson2HttpMessageConverter(customObjectMapper()));
  }
}


Now I am analysing MyServletConfig and it is possible to do it other way - by adding some specific interceptor. Nevertheless current solution works:)

Any other better ideas ???

--
I used in example Spring/Spring Security 5.2.1 and Apache Tomcat 8.5.50

No comments:

Post a Comment