Thursday, April 29, 2021

OAuth2 implementation in Spring Application using Google as authentication and authorization service provider

 OAuth stands for OpenID authorization. What this means. In general, we have an authenication and authorization module maintain by the application itself. But it comes with cost i.e. security to maintain user credential and its authorization. Other way is to have this authentication and authorization to be done by other application and once the user is declared valid user then allow them to access the requested url.

“OAuth protocol comes to help us in this fashion. Where in we ask the user to get authenticated and authorized from other site and once done can access the url from our site.”

Lets try to understand this in sequence manner.

You might have come across many sites now a day which when you try to access ask you to login using google or linked in or GitHub and once you are successful you are able to access the content of that site. So how this happen

Step 1:- User ask for the url from our application
Step 2:- Our application check if the user is in session/live or not if not then show him the page that ask them to login through Google or LinkedIn etc.
Step 3:- Once the user click on the option user is moved to the login screen of respective site i.e. google. Along with some information like request scope – contacts or OpenID email profile, response type – code, callback url – that contains the url the user will be directed when user click allow grant button. And client id.
Step 4:- Once the user logged in they will be shown one concent page that says following application (i.e. our application url) is asking to acces resource i.e. profile or username etc from google. Do you agree ?
Step 5:- Once the user agree or click on the allow grant button then google send one temporary id i.e. grant authorization id to our browser
Step 6:- Our browser send this temprorary id i.e. grant authorization id to our server. This is simple as only one additional parameter is added either in url or in header.
Step 7:- Then this temporary id i.e. grant authorization id is send from our server to google along with some parameters to get the access token. This access token is called JWT json web token having much information of the user along with user email id.
Step 8:- Once we have this access token and id token to our server we can make a call to resource server to get user profile

Now in above we have discussed web flow, but there are other flow also i.e. JavaScript flow, mobile app flow, TV and Device flow.

This flow which is defined above which is build on top of OAuth2 is called OpenID connect flow.

‘So OpenID connect is a thin layer build on top of Oauth2 used for login purpose.”

Now lets try to create a simple spring boot application when we try to access this application using browser we will be asked for first logged in to system i.e. google and then on successful login we will be able to see the first page.

Please follow the below step religiously.

Step 1- Create spring boot application with following

Add an Index Page in location: src/main/resources/templates/index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
    <title>Welcome</title>
</head>
<body>
<h1>Siddhu Welcome Page</h1>
<p>Welcome to Spring Security page that will be shown after the authenticaion and authorization from Google API</p>
<form th:action="@{/logout}" method="post">
    <input type="submit" value="Sign Out"/>
</form>
</body>
</html>

Now create following files
1- Controller.java

package com.siddhu;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

2-MvcConfig.java

package com.siddhu;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry){
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index").setViewName("index");
    }
}

3- SecurityConfig.java :- this will Secure the application with Spring Security

package com.siddhu;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable().antMatcher("/**").authorizeRequests()
                .antMatchers("/","/index").authenticated()
                .anyRequest().authenticated()
                .and()
                .oauth2Login().permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutSuccessUrl("/");
    }
}

Now lets Register the Application in the Google Sign-in portal
To use Google OAuth 2.0 as an authentication provider, let us create a web client in Google cloud console. To enable google auth with spring boot you need a client identifier and shared secret which needs to be passed as a configuration parameter to the application.

log in to the Google API console using your Google account.

navigate to the credentials section on the left menu, and choose the OAuth client ID option.

Now lets change in our web application configuration files

hit below url to the browser

http://localhost:8080

You can download the code from https://github.com/shdhumale/siddhu-springboot-springsecurity-oauth.git

Monday, April 26, 2021

Distributed Tracing of spring boot Microservices using OpenTracing platform for Zipkin and Jaeger

 Lets try to take advantage of opentracing concept for distributed application i.e. springboot application.

Lets create a simple spring boot web application and inject Opentrace jager dependencies in it and try to trace the request.

Before starting lets understand what is distributed tracing. Generelly in loggin we trace the request from one point to another point in same context. i.e. in microservice concept lets say our whole process need to get flow from Microservice A->Microservice B->Microservice C to complete the task .. in this case we should be able to trace the complete flow from A to C and not from A to b and B to C only. Distributed tracing help us in that concept as we get the complete ui of tracing the log from start to end.

We are using jager to provide the ui for tracing https://www.jaegertracing.io/

you can directly download the jager from the below location
https://www.jaegertracing.io/download/#binaries

Add Jager to you path in the system so that you can use it from the console.

C:\jaeger-1.22.0-windows-amd64

You can run the Jagger using below command
jaeger-all-in-one –collector.zipkin.host-port=:9411

Note:- you can also use the docker container to run them in the isolate environment.this is the most preferable way as it is executed in docker env.
Use this command to start Jager in docker env

docker run -d -p 5775:5775/udp -p 16686:16686 jaegertracing/all-in-one:latest

Open the ui on the browser

http://localhost:16686/search

Now lets create our Spring boot application whose request we want to trace.

Please follow the belwo step religiously. We are using Spring STS IDE for the same.

Now lets add required dependecies in our pom.xml as show belwo


<!-- https://mvnrepository.com/artifact/io.opentracing.contrib/opentracing-spring-web-starter -->
		<dependency>
			<groupId>io.opentracing.contrib</groupId>
			<artifactId>opentracing-spring-web-starter</artifactId>
			<version>4.1.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.opentracing.contrib/opentracing-spring-jaeger-starter -->
		<dependency>
			<groupId>io.opentracing.contrib</groupId>
			<artifactId>opentracing-spring-jaeger-starter</artifactId>
			<version>3.3.1</version>
		</dependency>
		

Now add a simple @Restcontroller to our springboot application

@SpringBootApplication
@RestController
public class SpringBootJaegerApplication {

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
    SpringApplication.run(SpringBootJaegerApplication.class, args);
}
 
 
 @GetMapping("/hello")
  public String hello() {
    return "hello";
  }

}

Lets run our spring boot application

Hit the url

http://localhost:8080/hello

Run our Jaeger server

Open Jaeger ui

Note:- You can download the source code from
https://github.com/shdhumale/spring-boot-jaeger

Now lets do the same thing using the Zipkin tracing

For this we will use the docker engine

Use below command to execute zipkin server

docker run -d -p 9411:9411 openzipkin/zipkin

Now Open the url below url and check we are able to access zipkin screen

http://localhost:9411/zipkin/

Now lets start our Spring boot application and check if it is working on port http://localhost:8080/hello

Now change the pom.xml for integrating Zipkin

<dependency>
			<groupId>io.zipkin.reporter</groupId>
			<artifactId>zipkin-sender-okhttp3</artifactId>
			<version>0.10.0</version>
		</dependency>
		
		<dependency>
			<groupId>io.opentracing.brave</groupId>
			<artifactId>brave-opentracing</artifactId>
			<version>0.20.0</version>
		</dependency>
		
		<dependency>
			<groupId>io.opentracing.contrib</groupId>
			<artifactId>opentracing-spring-web-autoconfigure</artifactId>
			<version>0.0.4</version>
		</dependency>

Now let following code in out main class

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Bean
public io.opentracing.Tracer zipkinTracer() {
    OkHttpSender okHttpSender = OkHttpSender.builder()
            .encoding(Encoding.JSON)
            .endpoint("http://localhost:9411/api/v1/spans")
            .build();
    AsyncReporter<Span> reporter = AsyncReporter.builder(okHttpSender).build();
    Tracing braveTracer = Tracing.newBuilder()
            .localServiceName("spring-boot-zipkin")
            .reporter(reporter)
            .traceId128Bit(true)
            .sampler(Sampler.ALWAYS_SAMPLE)
            .build();
    return BraveTracer.create(braveTracer);
}

Now lets run our springboot application and click on RunQuery button on the zipkin and you will be able to trace your request.

Note:- Code can be downloaded from url
https://github.com/shdhumale/spring-boot-zipkin