Wednesday, October 11, 2017

Getting Started with OAuth 2.0 using WSO2 Identity Server

WSO2 Identity Server can act as an authorization server in OAuth 2.0 [1] protocol. In this blog post, I am providing the steps for you to try out each OAuth grant type using WSO2 Identity Server. As the Identity Server supports the standard requests and responses in OAuth grant types, the same steps would be applicable for other OAuth authorization servers as well. Here I use the Identity Server 5.3.0 version, which is the latest released GA version at the time of this writing.

Protocol Endpoints

Once you start WSO2 Identity Server, by default it runs on localhost and on port 9443. So, the OAuth 2.0 protocol endpoints in the authorization server are as following.

Authorization Endpoint : https://localhost:9443/oauth2/authorize


Client Registration

Before making OAuth requests, we should register a client application in Identity Server to obtain the credentials of the client.

Login to the Management Console and Add a Service Provider.


In the Service Provider configuration, expand Inbound Authentication Configuration and under that you will find OAuth/OpenID Connect Configuration. Click on the Configure option there.


The Callback URL is the Redirection Endpoint (redirect_uri) of the client application where the authorization server should send the responses. Here I define the redirect_uri with the dummy value http://myoauthclient.com/callback although I do not have a client application running in that URL. That is fine because we can manually run through all the OAuth grant types using any dummy redirect_uri. If you are trying this out, you can put any URL as you wish.

In the configuration, it has checkboxes for each grant type. I am keeping all the checkboxes selected here, although in this article I will only demonstrate the authorization code, implicit, resource owner password credentials and client credentials grant types.

After successfully registering the OAuth client application, we can obtain the Client Key and Client Secret for the application. Update the service provider to persist the configuration of the OAuth client.

These are the values I have got. When you try out the same steps, you can use the values which you have received.

Client Key : 3T6XUzSJBZVHWlyzfV0Q3d7r7DEa
Client Secret : 39jR0RugVmUIfnVLgWVnfkEHIUoa


Authorization Code Grant Type

For trying out the authorization code grant type, we can prepare a URL like below (to the authorization endpoint of Identity Server with required query parameters) and visit that in the browser. Note that the redirect_uri is URL encoded.


Then, Identity Server would authenticate the user (resource owner). Here I need to provide user account credentials and login to Identity Server.


Then it will show the User Consent Page and ask the user to grant authorization for the client for the requested scopes.


Then, Identity Server will redirect the user agent (browser) to the redirect_uri with the query parameter ‘code’ that has the authorization code value. (Here since I don’t have a web application running in the redirect_uri, it shows the error. However I can manually extract the authorization code from the URL and continue the flow.

Now that we have the authorization code, next step is to request the OAuth access token from the Token Endpoint of the Identity Server. Here, we need to authenticate the client application. For that, in the HTTP Headers, I need to use the “Authorization: Basic XXX” header where the value is the Base 64 encoded string of ClientID:ClientSecret value.

I am using curl for making the HTTP POST request to the Token Endpoint. Similarly we can use any HTTP client (even RESTClient addon in browser).


curl -k -X POST --header "Authorization: Basic M1Q2WFV6U0pCWlZIV2x5emZWMFEzZDdyN0RFYTozOWpSMFJ1Z1ZtVUlmblZMZ1dWbmZrRUhJVW9h" --data "grant_type=authorization_code&redirect_uri=http%3A%2F%2Fmyoauthclient.com%2Fcallback&code=3d7f3e3c-8989-3301-8fdc-4f912fd2d5f8" https://localhost:9443/oauth2/token



As the response, I receive the following JSON payload which contains the OAuth access token and also the refresh token.


{
  "access_token":"44b279b3-2c3b-3a6f-b51b-845c15f3dd26",
  "refresh_token":"9380f382-dfd7-39d2-bee6-a89162d19d37",
  "scope":"openid",
  "id_token":"eyJ4NXQiOiJObUptT0dVeE16WmxZak0yWkRSaE5UWmxZVEExWXpkaFpUUmlPV0UwTldJMk0ySm1PVGMxWkEiLCJraWQiOiJkMGVjNTE0YTMyYjZmODhjMGFiZDEyYTI4NDA2OTliZGQzZGViYTlkIiwiYWxnIjoiUlMyNTYifQ.eyJhdF9oYXNoIjoidWlob20wZXNhelZJMHI3WUtJLUJuUSIsInN1YiI6ImFkbWluIiwiYXVkIjpbIjNUNlhVelNKQlpWSFdseXpmVjBRM2Q3cjdERWEiXSwiYXpwIjoiM1Q2WFV6U0pCWlZIV2x5emZWMFEzZDdyN0RFYSIsImF1dGhfdGltZSI6MTUwNzc1MjQwMCwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2VuIiwiZXhwIjoxNTA3NzU2MTc3LCJpYXQiOjE1MDc3NTI1Nzd9.hM43uJBQyI72OJXzHKzB0C1AxBgaOSPi6PySJr7HJyeR1k-AXxCDuWGfTsSVSf4WZNfaPaxMgw-xyjmLVztyqXOpXQXolDgnOMwkJYc4vrDrkg7gqxJhpoedS_bdg1905Gj-xYBawNfxYSdEXoaYxNIoGpTYOBSlK2wtxm0ExbE",
  "token_type":"Bearer",
  "expires_in":3600
}


Implicit Grant Type

In this grant, we can prepare the URL as following with the required parameters and invoke the authorization endpoint of Identity Server.


Once we access this URL in the browser, it will prompt for user authentication (if the user is not already logged into Identity Server) and then it will get the user’s approval from the User Consent page. Finally it will redirect the user-agent to the redirect_uri where the OAuth access token would be sent in the URL fragment.



Resource Owner Password Credentials Grant Type

Here we directly invoke the Token Endpoint of Identity Server with the required parameters. In the HTTP body, we need to provide the resource owner’s credentials as username and password parameters. In the HTTP Authorization header, we need to send the client’s credentials (clientID and clientSecret).

curl -k -X POST -H "Authorization: Basic M1Q2WFV6U0pCWlZIV2x5emZWMFEzZDdyN0RFYTozOWpSMFJ1Z1ZtVUlmblZMZ1dWbmZrRUhJVW9h" --data "grant_type=password&scope=openid&username=admin&password=admin" https://localhost:9443/oauth2/token

The response we get here is similar to Authorization Code grant’s response.



Client Credentials Grant Type

Here, we directly invoke the Token Endpoint of Identity Server, sending the required parameters. For authenticating the client, we use the Authorization HTTP header.

curl -k -X POST -H "Authorization: Basic M1Q2WFV6U0pCWlZIV2x5emZWMFEzZDdyN0RFYTozOWpSMFJ1Z1ZtVUlmblZMZ1dWbmZrRUhJVW9h" --data "grant_type=client_credentials&scope=openid" https://localhost:9443/oauth2/token


Retrieving User Profile Information using OAuth Access Token

Once we have obtained the OAuth access token for a user, then we can invoke the User Info Endpoint of Identity Server providing the access token in the Authorization header as a bearer token.

curl -k -X POST -H "Authorization: Bearer 44b279b3-2c3b-3a6f-b51b-845c15f3dd26" https://localhost:9443/oauth2/userinfo?schema=openid

Then in the response, we receive the user’s profile attributes as a JSON message.


We can configure the attributes to be received in the JSON response from the Service Provider configuration. In the Claim Configuration section of the Service Provider, we can add the claims we require in the response.


Additionally, we need to make sure the request claim URIs are already there in the OIDC claim dialect (http://wso2.org/oidc/claim). If a claim is not already there in the OIDC claim dialect, then we need to add it in order to be included in the JSON response sent by the Identity Server.

Also, we need to make sure the user’s profile has the values set for the claims that we need to include in the response.



References


Tharindu Edirisinghe
Platform Security Team
WSO2

1 comment:

  1. Very nice tutorial. Helped a lot. Thanks!!!!

    ReplyDelete