Tuesday, 22 August 2017

Securing webservice in spring boot framework


To add security infrastructure to a spring boot application below are the steps

Basic Security


1.In addition to the Spring boot starter, add spring security starter to the pom.

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-security</artifactId>
      </dependency>

2. Write the Entry class for the Spring boot 

@SpringBootApplication
public class MyApplication {
        public static void main(String[] args){
        SpringApplication.run(MyApplication.class, args);
        }

}

3. Add a controller for the rest webservice 

 @RestController
       public class MySpringSecurityController {

           @RequestMapping(value="/login", method=RequestMethod.GET)
           public String login(){
 
            System.out.println("entry for my app..........");
            return "Success";
        }

Point 2 and 3 are required for setting up any spring booth application. When we add spring security starter in pom, this will add basic spring security infrastructure. If we now build and run the application we can see the basic authentication pop-up when we try to access any webservice endpoint.




Using username-password from database


We need two class for this to implement. 

1.   A configuration class that should extend WebSecurityConfigurerAdapter and use @EnableWebSecurity annotation


Following is achieved with this
1.1 Require the user to be authenticated prior to accessing any URL within our application
1.2 Enables HTTP Basic and Form based authentication
1.3 Spring Security will automatically render a login page and logout success page for you

  WebSecurityConfigurerAdapter: Provides a convenient base class for creating a WebSecurityConfigurer instance. The implementation allows customization by overriding methods.
  
   Important method that we may like to override are 

  1.1 ConfigureGlobal(AuthenticationManagerBuilder auth)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Autowired
     public void configureGlobal(AuthenticationManagerBuilder auth) 
       throws Exception {
         auth.inMemoryAuthentication().withUser("manas")
           .password("manas").roles("USER");
    }
                  }

      
Above method may be used to configure an user on memory. This can be used in simulation scenario.

        1.2 configure(HttpSecurity http)

 protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().fullyAuthenticated().and().
    httpBasic().and().
    csrf().disable();
}

This method cab be overridden for following
A.Form Login
B.Authorization with roles
C.Logout
D.HttpSecurity

2.   A class should extend GlobalAuthenticationConfigurerAdapter. 


GlobalAuthenticationConfigurerAdapter is a SecurityConfigurer that can be exposed as a bean to configure the global AuthenticationManagerBuilder using the init method.

@Configuration
public class NeeWebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter  {
public void init(AuthenticationManagerBuilder auth) throws Exception {
   auth.userDetailsService(userDetailsService());  
  }
}


AuthenticationManagerBuilder allows for easily building in memory authentication, LDAP authentication, JDBC based authentication, adding UserDetailsService, and adding AuthenticationProvider's.

UserDetailsService is a core interface which loads user-specific data.It is used throughout the framework as a user DAO and is the strategy used by the DaoAuthenticationProvider.
The interface requires only one read-only method, which simplifies support for new data-access strategies.
        @Bean
  UserDetailsService userDetailsService() {
    return new UserDetailsService() {

      public UserDetails loadUserByUsername(String username) throws  UsernameNotFoundException {
         Account account = accountRepository.findByUsername(username);
        if(account != null) {
        return new User(account.getUsername(), account.getPassword(), true, true, true, true, AuthorityUtils.createAuthorityList("USER"));
        } else {
          throw new UsernameNotFoundException("could not find the user '"
                  + username + "'");
        }
      }
      
    };
  }

AuthenticationProvider: Spring Security provides a variety of options for performing authentication – all following a simple contract – an Authentication request is processed by an AuthenticationProvider and a fully authenticated object with full credentials is returned.



Github project implementing Spring Security



Resource

Streaming with Kafka API

The Kafka Streams API is a Java library for building real-time applications and microservices that efficiently process and analyze large-sca...