Skip to main content

How OIDC run on top of OAuth - Demo by a maven web application

As I said in the previous blog about OIDC, OIDC is running on top of OAuth in-order to provide authentication and authorization. When it comes to real scenario, we have need to clearly understand the flows between authorization server, and resource server. For OAuth it needs token introspection endpoint in-order to validate the token. But, in OIDC it doesn't need to have this introspection endpoint because OIDC response token (JWT) it contains the idtoken which contains information about the token to validate by the resource server. OIDC is running as authorization grant type is pretty much safe way for the web applications.

Let's see how a real world application using this OIDC on top of OAuth.
Note: I have created an sample application to provide the graphical interface for this explanation.

  1. When you are trying to login a online web application account you may see another login options also available. For example, login with Google, login with Facebook,etc. Those things are running on OAuth + OIDC to log into the applications. [Google, Facebook, also providing these kind of OAuth services to share it's user's information. Here, I am using Auth0 to login without creating a account/login via username and password]
  2. As usual in OAuth, the authorization server response with the user consent page on the redirection URL to the client application (your created application), in-order to get the  permission from the user (what claims the 3rd party clients can borrow from the resource server (here resources are stored in identity server which is acting as authorization server and resource server).
  3. After the user permission client app will receive the OIDC token, which no need further validation (token introspection). Because all the information are stored in the idtoken (you wont see the flow in the URL because in my case I gave the flows in POST services). Finally client application will successfully get the required information.
        

[Here I have logged Auth0 by using my gmail, so it's get my profile picture and other details through Google, now it sharing the information what is it having to the OIDC(my created application) client application]

Let's see the things with the rest-client and with the source codes (I have wrote those flows in each function in AppRestController.java).

Protocols endpoints:
Authorization endpoint: https://benjamine.auth0.com/authorize
Token endpoint:  https://benjamine.auth0.com/oauth/token

Client registration:
[This is on my previous blog]
Client_ID: 1BgekLBANaKy6r076OCdMZ0zzonrpcWc
Client_Secret: Bra4e8ICHwkAdT5LjezJIil573E6gJY3xf7EJyJ7L6oPI1n7f7MACZjR8T7g0jYN

Authorization code grant type:
In-order to get the authorization code the request URL will be like this.

Request:
https://benjamine.auth0.com/authorize?audience=https://benjamine.auth0.com/api/v2/&scope=openid%20profile&response_type=code&client_id=1BgekLBANaKy6r076OCdMZ0zzonrpcWc&redirect_uri=http%3A%2F%2Flocalhost%3A9090%2Foidcapp%2Fcallback&state=123

This will redirects you to get the users permission and the response with the code.

Response
http://localhost:9090/oidcapp/callback?code=R3bnvlibRaQ4rZRP&state=123

Function written to get the authorization code:
@RequestMapping(value = "/login-auth0", method=RequestMethod.GET)
    public RedirectView processForm1() {
        RedirectView redirectView = new RedirectView();

        //Prepare the OAuth Authorization URL
        String url = "https://benjamine.auth0.com/authorize?"+
                    "audience=https://benjamine.auth0.com/api/v2/"+
                    "&scope=openid%20profile"+
                    "&response_type=code"+
                    "&client_id=1BgekLBANaKy6r076OCdMZ0zzonrpcWc"+
                    "&redirect_uri=http%3A%2F%2Flocalhost%3A9090%2Foidcapp%2Fcallback"+
                    "&state=123";
        redirectView.setUrl(url);
        return redirectView;
    }

[This function needs to execute when we click the login with Auth0]

Request Access token by using the authorization code:
This will be a POST request contains 2 headers.

Headers:
Authorization: Basic<client_ID:client_secret> -->[no need if you add them inside the body]
Example:
BasicMUJnZWtMQkFOYUt5NnIwNzZPQ2RNWjB6em9ucnBjV2M6QnJhNGU4SUNId2tBZFQ1TGplekpJaWw1NzNFNmdKWTN4ZjdFSnlKN0w2b1BJMW43ZjdNQUNaalI4VDdnMGpZTg==
[client_ID:client_Secret needs to be base64 encode]
content-type: application/x-www-form-urlencoded

Request URL: [Token endpoint]
https://benjamine.auth0.com/oauth/token

POST body:
grant_type=authorization_code&client_id=1BgekLBANaKy6r076OCdMZ0zzonrpcWc&client_secret=Bra4e8ICHwkAdT5LjezJIil573E6gJY3xf7EJyJ7L6oPI1n7f7MACZjR8T7g0jYN&code=bR-Xb6-GQl90s-E1&redirect_uri=http%3A%2F%2Flocalhost%3A9090%2Foidcapp%2Fcallback



Response:
Access token(JWT)

{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1VUXlPVUkxTlVFM09FUkVOalEwTVVVMk9USTVNVVpCTkRBd1JVTXlRekZFTnpRM09UZ3hSUSJ9.eyJpc3MiOiJodHRwczovL2JlbmphbWluZS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWJkNTIyN2EzZjMyNWYwZDhmODExNTYxIiwiYXVkIjpbImh0dHBzOi8vYmVuamFtaW5lLmF1dGgwLmNvbS9hcGkvdjIvIiwiaHR0cHM6Ly9iZW5qYW1pbmUuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTU0MDY5ODEwMSwiZXhwIjoxNTQwNjk4NDYxLCJhenAiOiIxQmdla0xCQU5hS3k2cjA3Nk9DZE1aMHp6b25ycGNXYyIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUifQ.jjOQHLHiWEscfCHU7XSVo1PFdFHKY98RG2B6BJrej3OKnzVqlScRjxPg9Y2Wb4F_rzHkmgWym0DCVk6Mlv2wBmBHJBoLDUqwVYugQ21I4ayJgbd-y8asrwTiwriBFGCPeae_GOu4uQaEUfRk8pxM-PVDJ_GZeM7iL-6E4OTPPallj3egAt49wIoaJE-yxggG5P01DGAIs1L3UkUImbmq8I1ojG1EnEk_XLm3mqEAZhR57sfIpLC893a4p6r5OSGftMuFWdWjSwPXo4eNUt9VRTTpZ_If8NZ9vHigxrWiKppL8Hbj1pDwgk6xpv-Wg68lplMgNfNaAG91EN6ncmWVqA","id_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1VUXlPVUkxTlVFM09FUkVOalEwTVVVMk9USTVNVVpCTkRBd1JVTXlRekZFTnpRM09UZ3hSUSJ9.eyJuaWNrbmFtZSI6InNhaGF5YW5hdGhhbmJlbmphbWluZS5zYiIsIm5hbWUiOiJzYWhheWFuYXRoYW5iZW5qYW1pbmUuc2JAZ21haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vcy5ncmF2YXRhci5jb20vYXZhdGFyL2M4NzhlNTkyNzY3Zjk4YTczNzA0ZTViNjYwMTIyZGZkP3M9NDgwJnI9cGcmZD1odHRwcyUzQSUyRiUyRmNkbi5hdXRoMC5jb20lMkZhdmF0YXJzJTJGc2EucG5nIiwidXBkYXRlZF9hdCI6IjIwMTgtMTAtMjhUMDM6MDQ6MDEuOTc1WiIsImlzcyI6Imh0dHBzOi8vYmVuamFtaW5lLmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1YmQ1MjI3YTNmMzI1ZjBkOGY4MTE1NjEiLCJhdWQiOiIxQmdla0xCQU5hS3k2cjA3Nk9DZE1aMHp6b25ycGNXYyIsImlhdCI6MTU0MDY5ODEwMSwiZXhwIjoxNTQwNjk4NDYxfQ.jZbPgxo8LeRXHW60UfOObpr-8xHRaDQWa3ubZmsvgAtNkcuvhKyI52cjajlZC98aAKeIMifhu4RNjPLGocQMyLk9c8mIrKqLGpIf_hb2Srai0uBs41mH4Ok-Xdq4C0CToAfAm7dyS6uCbe5cgKcDHaPJOMpGD98XodLFSWaBZasw3ymBF95om0x1i7F_orsV0bCKPxHjBJ7fgXmy1XrBsAPLOIK4Hz_M1DyXeWbedyhOH7akMBlu3bphUrAZlYRuGvGBzoNeifLvz80W-DO_GVH-qSWmwxwclWJ9mKtIkjQjL7vqyGVclOXy78Nb3PudTKWeZdlBO6DissCmDAahbQ","scope":"openid profile","expires_in":360,"token_type":"Bearer"}

Function written to get the access token:

public String getAuthResponse(String authCode)
    {
        ////Prepare the POST request to get the access_token and id_token 
        
        //OAuth Token URL
        String auth_url = "https://benjamine.auth0.com/oauth/token";
        
        //Prepare POST Request Body
        String POST_PARAMS = "grant_type=authorization_code"+
                            "&client_id=1BgekLBANaKy6r076OCdMZ0zzonrpcWc"+
                            "&client_secret=Bra4e8ICHwkAdT5LjezJIil573E6gJY3xf7EJyJ7L6oPI1n7f7MACZjR8T7g0jYN"+
                            "&code="+authCode+
                            "&redirect_uri=http%3A%2F%2Flocalhost%3A9090%2Foidcapp%2Fcallback";
        String authReponse = "";

        try
        {
            //Create the objects of URL and the HttpURLConnection and set the request method to POST
            URL obj = new URL(auth_url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");

            //Set Headers
            con.setRequestProperty("content-type", "application/x-www-form-urlencoded");

            //Set Body
            con.setDoOutput(true);
            OutputStream os = con.getOutputStream();
            os.write(POST_PARAMS.getBytes());
            os.flush();
            os.close();


            //Execute and get the response
            int responseCode = con.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK)//success
            {
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        con.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();

                while ((inputLine = in.readLine()) != null)
                {
                    response.append(inputLine);
                }
                in.close();

                authReponse = response.toString();

            }
            else
            {
                System.out.println("Error : " + responseCode);
            }
        }
        catch (Exception ex)
        {
            System.out.println(ex);
        }
        
        //Return the response received
        return authReponse;
    }

Extract the data from the access token: [By using JWT decorders]
Copy the id_token data and decode it by using JWT decorders [https://jwt.io/]


Extract the data from the access token: [By using functions]

@RequestMapping(value = "/oidcapp/callback", method = RequestMethod.GET)
    public RedirectView authUser(ModelMap model, @RequestParam(value = "code",required=true) String authCode) {
        
        try{
            //Get the access token and id_token from the auth0 server by providing the code received
            String response = getAuthResponse(authCode);
            //return response;

            //Extract the user data from the received response
            //return getUserData(response); --> old
            JSONObject jsonBody = getUserData(response);
            this.nickname = jsonBody.getString("nickname");
            this.picture = jsonBody.getString("picture");
            this.JASON_RESPONSE=jsonBody.toString();

            //Set the attribute to the page and redirect the user to the user's home page
            return viewHomePage();
        }
        catch(Exception ex){
            System.out.println(ex);
        }
        return null;
    }
    public RedirectView viewHomePage(){
        AppController app = new AppController();
        app.setModelAttribute("nickname",this.nickname);
        app.setModelAttribute("picture",this.picture);
        app.setModelAttribute("JASON_RESPONSE", this.JASON_RESPONSE);
        app.setModelAttribute("verify_status",this.msgVerify);
        RedirectView redirectView = new RedirectView();
        redirectView.setUrl("/home");
        return redirectView;
    }


My next blog will contain how to validate the JWT signature.

Comments

Popular posts from this blog

Bandit Wargame – Documentation

Basically wargames are providing the basic knowledge on the security concepts. It is a game that contain many tricks to break the borders to gain the access especially passwords (commands are mostly on the Linux CLI). You can find many wargames through the Internet and they are very interest and fun full too. “Bandit” is also a wargame which is for the beginners. You all can access that through the link given bellow. And this article is an document for this game. I have used Ubuntu as the operating system. Bandit – Clickhere . Level 0: Case study → Clickhere Here we have need to connect the host through the SSH (secure socket shell) server. The informations are provided as follows. Host name: bandit.labs.overthewire.org Port No: 2220 User name: bandit0 Password: bandti0 There are many ways to connect through the SSH server. Method 1: Download and run the “PuTTY SSH client”. ( https://the.earth.li/~...

Introduction to OAuth

What is OAuth? OAuth is a protocol that allows distinct parties to share information and resources in a secure and reliable manner. OAuth needs to consider the 2 concept to provide the informations in secure and reliable manner. They are authentication and authorization. Authentication -> Validating the person/system who need the information Authorization -> After authentication what action can be performed by the person/system. By maintaining this 2 concept OAuth is providing federated identity and delegated identity. Federated identity -> User can use his/her one application account to login another application. [Example: If a user having Facebook account then he can login Instagram with the same login as Facebook] Delegated identity -> One service can access another service resources. [Example: When creating a Facebook account with eMail address that will suggest the contacts in the eMail to add as friends] Without OAuth With OAuth User ...