Thursday, September 27, 2018

Introduce Spring Boot Security into the Calculator Application

This Post is in continuation to the previous demonstration of Spring Boot Simple Calculator application http://rbc-spring-boot-samples.blogspot.com/

Here we look at adding spring-security component to our application

It includes
1) Service configuration
2) Client authentication

Service Configuration
1) Maven
Add the security starter dependency

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

Restart the Application. The Spring scanner looks for Spring Security being loaded into the classpath and adds the below Filters in the chain:

Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@338a4c61, org.springframework.security.web.context.SecurityContextPersistenceFilter@36665c11, org.springframework.security.web.header.HeaderWriterFilter@4152bd0f, org.springframework.security.web.csrf.CsrfFilter@24018c8b, org.springframework.security.web.authentication.logout.LogoutFilter@4c41a177, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@10d4b573, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@62ab5e63, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@2b6fcca1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3a709cc7, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3e01796a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@839755f, org.springframework.security.web.session.SessionManagementFilter@e4b54d3, org.springframework.security.web.access.ExceptionTranslationFilter@2976ef56, org.springframework.security.web.access.intercept.FilterSecurityInterceptor

Importantly, it generates a default security password:
Default user id: user
Using generated security password: 0xxxxxx1-7xx5-4xx9-8xxf-2xxxxxxxxxxx9

2) Client authentication

Hit the URL : http://localhost:7070/add?number1=34&number2=44

It takes you to the Basic authentication Page as below:

Give the User: User password : 0xxxxxx1-7xx5-4xx9-8xxf-2xxxxxxxxxxx9


It shows the Result as 78 after successful login

Otherwise it shows:


RestController - Simple Calculator - Service and Client

This simple Calculator demonstrates the usage of Spring Boot Rest service and Rest Client

Service Steps involved:
1) Maven Dependencies
2) Implement model class
3) Implement service class
4) Injecting resources into service class
5) Service class Configuration
6) Running Service and port settings

Client Steps involved:
1) Maven dependencies
2) RestTemplate instantiation
3) Creating Headers
4) Creating Request Parameters
5) Dealing with requests and responses


Service Steps involved:
1) Maven Dependencies and package structure

Spring Boot dependency:

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

Spring Rest dependency:

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

Package Structure:



2) Implement model class

package com.calculator.app.calculatorapp.model;

import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Componentpublic class CalculatorModel {
    public BigDecimal add(BigDecimal number1 , BigDecimal number2){
        return new BigDecimal(number1.intValue() + 
                              number2.intValue());
    }
}

3) Implement service class
4) Injecting resources into service class
5) Service class Configuration

import com.calculator.app.calculatorapp.model.CalculatorModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CalculatorService {
    @Autowired    private CalculatorModel calculatorModel;
    @GetMapping(value = "/add")
    public BigDecimal addNumbers(@RequestParam(name = "number1") 
BigDecimal number1, @RequestParam(name = "number2") 
BigDecimal number2){
        return calculatorModel.add(number1,number2);
    }
}

6) Running Service and Port settings

application.properties
server.port=7070


package com.calculator.app.calculatorapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplicationpublic class CalculatorAppApplication {

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

The service starts on Port number 7070 and can be accessed via Http url

http://localhost:7070/add?number1=34&number2=44



Client Steps involved:
1) Maven dependencies
     <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
2) RestTemplate instantiation
3) Creating Headers
4) Creating Request Parameters
5) Dealing with requests and responses
public static void main(String[] args) {
      RestTemplate restTemplate = new RestTemplate();
      HttpHeaders headers = new HttpHeaders();
      headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
      UriComponentsBuilder uriComponentsBuilder = 
UriComponentsBuilder.fromHttpUrl("http://localhost:7070/add").
queryParam("number1",344334).
            queryParam("number2",434343433);
      HttpEntity<?> entity = new HttpEntity<>(headers);
      HttpEntity<BigDecimal> sum = restTemplate.exchange
(uriComponentsBuilder.toUriString(), 
HttpMethod.GET,entity,BigDecimal.class);
      System.out.println(sum.getBody());
   }