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

Wednesday, 25 December 2019

This week 2/2019 - Spring Integration


This is my first meet with Spring Integration. I started with version 4.3 so I will not mention of older version which I don't know.
For whom who don't know what is it Spring Integration. In a nutshell, this is a framework to create flows between betweens input adapters and endpoints.

In a short story I describe what I'd like to reach.

I've got some configuration in XML version which is included in to class version of configuration. I have as well test context (class version) which override some beens - adapters from/to external world). I'd like to translate this XML to have:
  • consistent configuration in production and test code,
  • to be able override production configuration of some adapters (ex. file adapters)
  • to use inline transformations (not included in example).
Below I added a sample of configuration for class version and commented out a equivalent XML code.



  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
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
@Configuration
//@ImportResource("/spring-int.xml")
@EnableIntegration
public class IntConfig {


//    <int:channel id="inChannel"/>

//    <int:transformer input-channel="inChannel"
//                     output-channel="srcEmailChannel"
//                     ref="inTransformer"/>
//    <bean id="inTransformer" class="PublisherTransformer"/>
//

    @Bean
    @Transformer(inputChannel = "inChannel", outputChannel = "srcEmailChannel")
    PublisherTransformer inTransformer() {
        return new PublisherTransformer();
    }

//    <int:channel id="srcEmailChannel">
//        <int:interceptors>
//            <int:wire-tap channel="backup"></int:wire-tap>
//        </int:interceptors>
//    </int:channel>


    @Bean
    public MessageChannel backup() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel srcEmailChannel() {
        final DirectChannel directChannel = new DirectChannel();
        directChannel.addInterceptor(new WireTap(backup()));
        return directChannel;
    }


//    <int:router input-channel="backup" expression="headers.country">
//        <int:mapping value="PL" channel="plChannel"/>
//        <int:mapping value="EN" channel="enChannel"/>
//    </int:router>

    @Bean
    @Router(inputChannel = "backup")
    public AbstractMessageRouter backupRouter() {
        HeaderValueRouter router = new HeaderValueRouter("country");
        router.setChannelMapping("PL", "plChannel");
        router.setChannelMapping("EN", "enChannel");
        return router;
    }


//    <int:channel id="plChannel"/>
//    <int-file:outbound-channel-adapter id="plChannelOutFile"
//                                       directory="/tmp/plChannel/"
//                                       channel="plChannel"
//                                       mode="APPEND"
//                                       charset="UTF-8"/>

    @Bean
    @ServiceActivator(inputChannel = "plChannel")
    MessageHandler plChannelOutFile() {
        final FileWritingMessageHandler fileWritingMessageHandler = 
                new FileWritingMessageHandler(new File("/tmp/plChannel/"));
        fileWritingMessageHandler.setCharset(UTF_8);
        fileWritingMessageHandler.setFileExistsMode(APPEND);
        fileWritingMessageHandler.setExpectReply(false);
        return fileWritingMessageHandler;
    }

//    <int:channel id="enChannel"/>
//    <int-file:outbound-channel-adapter  id="enChannelOutFile"
//                                        directory="/tmp/enChannel/"
//                                        channel="enChannel"
//                                        mode="APPEND"
//                                        filename-generator="fileGenerator"
//                                        charset="UTF-8"/>
//    <bean id="fileGenerator" class="FileNameGen"/>

    @Bean
    @ServiceActivator(inputChannel = "enChannel")
    MessageHandler enChannelOutFile() {
        final FileWritingMessageHandler fileWritingMessageHandler = 
                new FileWritingMessageHandler(new File("/tmp/enChannel/"));
        fileWritingMessageHandler.setCharset(UTF_8);
        fileWritingMessageHandler.setFileExistsMode(APPEND);
        fileWritingMessageHandler.setExpectReply(false); // I don't need return
        fileWritingMessageHandler.setFileNameGenerator(new FileNameGen());
        return fileWritingMessageHandler;
    }


//    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"/>
      // this not complete mail server configutation
      @Bean
      MailSender mailSender() {       
          return new JavaMailSenderImpl();
      }
//
//
//    <int-mail:outbound-channel-adapter channel="srcEmailChannel" mail-sender="mailSender"/>
    @Bean
    @ServiceActivator(inputChannel = "srcEmailChannel")
    MessageHandler messageHandler(MailSender mailSender) {
       return new MailSendingMessageHandler(mailSender);
    }
    @Bean
    PublisherService publisherService() {
        return new PublisherService();
    }
}

As you can see all of used channels must be defined manualy in XML version. In class version I defined only those which I'd like add some additional behaviour.

Is it true that in Java we can't change Spring Integration configuration with simple editor an restart applicaton - we need compile this configuration but we have plenty of possibilities to do.

Starting from version 5.0 there is additional implementation supporting mixed configuration in test, ex.
  • @SpringIntegrationTest
  • MockIntegrationContext
However this works in other way than overrding bean definition as I did it. This stops current MessageHandler lifecycle and replace condext with mocked bean.

In version 5 it was added as well DSL to make configuration more readable. More information in [1]


Sunday, 13 January 2019

This week 1/2019 - STM32 microcontroller

Today I'd like to write about my first experiences with STMicroelectronic. My set is Nucleo board with STM32F466RE chipset - 160Mhz with 512k flesh memory.
I started from looking for articles and YouTube tutorials about hardware platrorm. I didn't know difference between Raspberry PI and Andurino. I found a few interesting [in resources] and then I decided to buy STM32 hardware platform with at least 256kB flash memory.
Next step was to choose IDE. I'd like to use IntelliJ because daily I work in this IDE, unfortunately JetBrains has other tool with separate licence and not so popular as other IDEs. Finally I chosen Atollic TrueSTUDIO for STM32 9.2.0 especially it is supported by tool STM32Cube MX.
STM32Cube MX is a tool to generate project for selected IDE with C code initializing selected by developer modules and ports of STM32 processor.
To create and load first program on microchip we need to install compiler. I am using Linux system that's why I executed commands:
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install binutils-arm-linux-gnueabi
sudo apt-get install libnewlib-arm-none-eabi
My hardware platform has integrated ST-link and storage where I can copy my binary file and load it automatically on my STM microchip. No additional tool needed.
At the beginning I used external libraries libopencm3 [5] with examples. However there is no tool to generate initializing methods like STM32Cube MX what it is useful at the beginning.
I watched presentation [10] and I was inspired to create code in C++. Bartosz convincing that C++ takes similar resources. In come cases is even much better then code from C compiler.


Till now I created following projects basing on examples:
  1. Change GPIO port state. Both sources of code have example of blinking LED. I used my own external LED to blink.
  2. Read GPIO port state. We can read state of each pin. For pin 1 it will be value 0 or 1, for pin 2 value 0 or 2 and so on. I closed selected pin with 3.3V source.
  3. Communicate via serial port USART. I get connected using ST-link integrated with nucleo board and by external ST-link module.
  4. Read system time. This operation looks different than in OS Linux system. We need to open timer module of chip and then we can read counter.
  5. Ethernet connection. I have Ethernet module with chip ENC28J60. I connected it to SPI connectors however I couldn't run it. :( After spend some time I found correct example and adopted it in my project [8]. It works fine. However I don't know why one request is processed 4 times. Maybe clock of buffer reader is too fast. I must check it.
  6. DAC - set voltage on output an modulate speaker.
  7. ADC - read voltage on input in range 0-3,3V.
  8. Store and read data from flash memory [9]. I have to change memory mapper file.


Resources:
  1. How to start
  2. STM32 tutorial
  3. List of useful links
  4. STM32 HAL layer - documentation
  5. Alternative library with examples - libopencm3
  6. STM32Cube MX tutorial
  7. Setting STM32 clock speed
  8. Ethernet module - ENC28J60
  9. Read/store data in memory
  10. Bartosz Szurgot - C++ vs C the embedded perspective