Skip to content

Code Grant Type With Github#

In this section we will try to make an example for using OAUTH2 in Spring Security application. To be simple we will use Github as an Authorization Server, our Spring Security application will be the Resource Server.

Register Client Details With Github#

  • So, the first thing you have to do is creating a Github account following this link.
  • Now, if you already have a Github account, so you can register a client details and use it's OAUTH2 authorization server following steps below.
  • Step 1: You can click on your account at the top right corner and choose Setting.

 #zoom

  • Step 2: You continue to scroll down and choose Developer Setting

 #zoom

  • Step 3: You continue to choose OAuth App and choose New OAuth App

 #zoom

  • Step 4: Now you have to input some required information as in the image below

 #zoom

  • In which the Homepage Url is the homepage of your application url. The Authorization Callback URL is the url that you want the Github authorization server to call back after the authorization is successful.
  • After input required information, then click button Register Application to finish registering.
  • Step 6: After successfully register, you will see there is a Client Id. Then you have to click on the button Generate a new client secret to get the Client Secret as the image below,

 #zoom

  • Now, you have the Client Id and Client Secret so you can copy them and you can use them for the Spring Security configuration later.

Configure Spring Security With Github OAUTH2 Server#

  • Let create a new project and import these dependencies into pom.xml as below for Spring Boot, Spring Security and Oauth2 Client.
pom.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
    <version>2.6.3</version>  
</dependency>  

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

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-oauth2-client</artifactId>  
    <version>2.6.3</version>  
</dependency>
  • Then create the main class as below to enable Spring Boot application.
SpringSecurityOauthGithubApplication.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.springboot.security.oauth.github;  


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

@SpringBootApplication  
public class SpringSecurityOauthGithubApplication {  

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

}
  • Next, Let's create a simple controller as below for mocking the resource that the client want to access. So this api just simply response a text, but we will print out the Authentication details from Github Auth Server for checking.
ResourceController.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.springboot.security.oauth.github.controller;  

import org.springframework.http.ResponseEntity;  
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  

@Controller  
public class ResourceController {  

    @GetMapping("/")  
    public ResponseEntity<String> getResource(OAuth2AuthenticationToken oAuth2AuthenticationToken) {  
        System.out.printf(String.valueOf(oAuth2AuthenticationToken.getPrincipal()));  
        return ResponseEntity.ok("Hello! this is the secret resources!");  
    }  

}
  • Then, in the application.yml, we will add the clientId and clientSecret that we got from the register client details with Github as below.
application.yml
1
2
3
4
5
github:  
  oauth2:  
    client:  
      id: c224cc2eb828c3ba811c  
      secret: 7515f35ceb176a13911efa24f85238ff2d8e1d4c
  • Now, we will move to configuration steps. Basically, there are three ways for you to config OAUTH2 in Spring Security and base on the business use cases, you will chose the most appropriate one.

Configure OAUTH2 Using CommonOAuth2Provider#

  • CommonOAuth2Provider is a provider class from spring-boot-starter-oauth2-client. This class provides some default configuration parameters for common Authorization Server such as Facebook, Google, Github and OKTA.
  • Because we using Github in this example, so using CommonOAuth2Provider will boot up our configuration very fast and we also can add our custom configuration easily.
  • Firstly, we need to create a configuration class with the content as below.
SpringSecurityOauthGithubConfig.java
 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
package com.springboot.security.oauth.github.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SpringSecurityOauthGithubConfig {

    @Value("${github.oauth2.client.id}")
    private String clientId;

    @Value("${github.oauth2.client.secret}")
    private String clientSecret;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http.authorizeRequests().anyRequest().authenticated().and().oauth2Login().and().build();
    }

    @Bean
    public ClientRegistrationRepository clientRepository() {
        ClientRegistration clientRegistration = this.clientRegistration();
        return new InMemoryClientRegistrationRepository(clientRegistration);
    }

    private ClientRegistration clientRegistration() {
        return CommonOAuth2Provider.GITHUB
                .getBuilder("github")
                .clientId(this.clientId)
                .clientSecret(this.clientSecret)
                .build();
    }

}
  • As you can see, firstly, we will configure the filterChain bean for protecting all apis and every request come into our Spring Security application has been validated and authenticated. The authentication will be supported by OAUTH2 authorization framework by adding .oauth2Login().
  • To using OAUTH, we must register a client with a provider. The client registration information may than be used for configuring a ClientRegistration using CommonOAuth2Provider. Because we are using Github so we will use builder with github value and add some more information such as clientId and clientSecret which are got from the application.yml.
  • After building a ClientRegistration object, we will use it to create ClientRegistrationRepository bean which will be used by the ApplicationContext or configured via oauth2Login().clientRegistrationRepository(..).
  • In this example, we are defining a bean ClientRegistrationRepository for ApplicationContext using new InMemoryClientRegistrationRepository(clientRegistration).

Configure OAUTH2 Manually#

  • In special cases, The authorization server is belong to an organization or a company and it's not supported in the CommonOAuth2Provider, so you have to configure OAUTH2 manually.
  • Let's create a configuration class as below.
SpringSecurityOauthGithubConfig2.java
 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
package com.springboot.security.oauth.github.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SpringSecurityOauthGithubConfig2 {

    @Value("${github.oauth2.client.id}")
    private String clientId;

    @Value("${github.oauth2.client.secret}")
    private String clientSecret;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http.authorizeRequests().anyRequest().authenticated().and().oauth2Login().and().build();
    }

    @Bean
    public ClientRegistrationRepository clientRepository() {
        ClientRegistration clientRegistration = this.clientRegistration();
        return new InMemoryClientRegistrationRepository(clientRegistration);
    }

    private ClientRegistration clientRegistration() {
        return ClientRegistration.withRegistrationId("github")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .clientId(this.clientId)
                .clientSecret(this.clientSecret)
                .scope("read:user")
                .authorizationUri("https://github.com/login/oauth/authorize")
                .tokenUri("https://github.com/login/oauth/access_token")
                .userInfoUri("https://api.github.com/user")
                .userNameAttributeName("id")
                .clientName("GitHub")
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .registrationId("{baseUrl}/{action}/oauth2/code/{registrationId}")
                .build();
    }

}
  • Like the configuration in CommonOAuth2Provider, firstly, we will configure the filterChain bean for protecting all apis and every request come into our Spring Security application has been validated and authenticated. The authentication will be supported by OAUTH2 authorization framework by adding .oauth2Login().
  • Then we have to build the ClientRegistration object manually by full fill information like.
  • registrationId
  • clientId
  • clientSecret
  • scope
  • authorizationUri
  • tokenUri
  • userInfoUri
  • userNameAttributeName
  • clientName
  • authorizationGrantType
  • redirectUri
  • After building a ClientRegistration object, we will use it to create ClientRegistrationRepository bean which will be used by the ApplicationContext or configured via oauth2Login().clientRegistrationRepository(..).
  • In this example, we are defining a bean ClientRegistrationRepository for ApplicationContext using new InMemoryClientRegistrationRepository(clientRegistration).

Configure OAUTH2 Using Auto Configuration#

  • In case you are using CommonOAuth2Provider with common Authorization Server such as Facebook, Google, Github and OKTA. However, you don't have many custom information that you want to input, you just need to add ClientId and ClientSecret. So you can use auto configuration to configure OAUTH2 quickly.
  • Let's create a configuration class as below.
SpringSecurityOauthGithubConfig3.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package com.springboot.security.oauth.github.config;  

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
import org.springframework.security.web.SecurityFilterChain;  

@Configuration  
public class SpringSecurityOauthGithubConfig3 {  

    @Bean  
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {  
        return http.authorizeRequests().anyRequest().authenticated().and().oauth2Login().and().build();  
    }  

}
  • As you can see, firstly, we only need to configure the filterChain bean for protecting all apis and every request come into our Spring Security application has been validated and authenticated. The authentication will be supported by OAUTH2 authorization framework by adding .oauth2Login().
  • Then in the application.yml, you will put the configuration as below
application.yml
1
2
3
4
5
6
7
8
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: c224cc2eb828c3ba811c
            client-secret: 7515f35ceb176a13911efa24f85238ff2d8e1d4c
  • The configuration will have the format
  • spring.security.oauth2.client.registration.[registrationId]
  • In which the registrationId can have values like github, facebook, google and okta which are supported by spring-boot-starter-oauth2-client.

Testing#

  • Now, let's start your Spring Security application. Then open the web browser and go to http://localhost:8080. Then you will be redirect to the Github login page to prove your identity by input the username and password of your Github account.

 #zoom

  • Then after you input your Github account credentials and your Github account is valid, you will be redirected to your Spring Security application and you will see the response content of the api that you created before.

 #zoom

  • If you look into the log of your Spring Security application, you will see there are many information about the OAuth2AuthenticationToken which is received from the Github Authorization Server.

See Also#

References#