Identity cloud service : Mobile clients and PKCE support

Introduction

OAuth 2.0 has become very popular within the mobile development community mainly because it is simple to implement and the tokens are fairly compact. There are various implementation patterns to choose from and it is very important to choose the right one to make sure that the solution is secure. In this blog post I want to describe how mobile clients can get access tokens from Oracle Identity Cloud Service securely so that the identity service protected APIs can be consumed.

Before moving ahead…

If you are not aware of OAuth 2.0 standard and various grant types like implicit or authorization code, I highly recommend to go through the core specification –

https://tools.ietf.org/html/rfc6749

Oracle Identity Cloud Service and PKCE

One of the roles Oracle Identity Cloud Service plays is that of an OAuth 2.0 authorization server with support for 2 different application types –

  1. 1. Mobile application – These applications (mobile or SPA) can not maintain the confidentiality of their client secret and are also called public clients.
  2. 2. Trusted application – Server side applications which can maintain the confidentiality of the client secret hence also called confidential clients.

I want to focus on the first client type in this post. So in Oracle Identity Cloud Service, the allowed grant types for a public client are “implicit” and “authorization code”.

In short, “implicit” grant type instructs an authorization server (AS) to return an access token to a client via user’s agent (over HTTPS) in a successful response to the authorize request. It is not secure and not recommended unless there is no way to use authorization code grant.

A public client will not have a secret as it can not be kept confidential and without a client secret, the authorization code flow would also be insecure as it becomes susceptible to the authorization code interception attack.

Authorization code interception attack happens when a “malicious” app uses the same uri scheme (handler) as an “authentic” app and receives authorization code from the authorization server ( which was only meant for the authentic app), it then calls the token endpoint to get a token back and gains access to user’s resources.

PKCE (proof of key code exchange) aims to resolve this and when implemented by both a client app and the authorization server ensures that the client which requested an authorization code is the same one which is exchanging it for a token.

In depth details about PKCE are available here – https://tools.ietf.org/html/rfc7636#section-7.3

PKCE in a nutshell

PKCE is an OAuth 2.0 specification extension which adds a layer of security to the public client authorization code flow.

A public client generates a cryptographic highly random string called code_verifier and applies a code_challenge_method to compute code_challenge from code_verifier.

There are two supported challenge methods – “S256” and “plain”

code verifier correlates to code_challenge like this,

when challenge_method is “S256″ –

code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

when challenge_method is “plain”-

code_challenge=code_verifier

Then code_challenge and code_challenge_method are sent in the authorization request where as the code_verifier is sent in the token request. The authorization server(AS) follows the same formula to compute code_challenge value from code_verifier and compares it with the one sent in the authorization request. This provides enough assurance to the AS that a token request is coming from the same client which initiated the corresponding authorization request.

An important point to note is that salting is not required as code_verifier has high entropy (randomness).

IDCS PKCE Flow

IDCS - PKCE flow

IDCS – PKCE flow

Setting up a public client and testing PKCE with IDCS

We don’t need to do anything additional to enable PKCE in IDCS, it’s supported OOTB and as long as a public client sends PKCE parameters in the requests, IDCS will validate the PKCE parameters.

Configure IDCS

Login to IDCS admin console and create a new mobile application

Mobile Client

Mobile Client

 

New mobile client

 

Mobile client config

Note the auto generated Client ID.

 

Mobile client configuration

Make sure to check authorization code grant type in the allowed grant types section

Add additional scopes as required and save your configuration.

Configure and run your native app

Any OAuth 2.0 library which supports PKCE can be used to develop your native app. I tested IDCS-PKCE support using an open source project available here – https://github.com/openid/AppAuth-iOS

Assuming you have a library and a sample app ready to connect to IDCS you will need 3 parameters at a minimum –

  1. 1. IDCS URL – IDCS url for your tenant.
  2. 2. Mobile client id – configured in step 1
  3. 3. App redirect uri – configured in step 1

 

Typical flow for a client app

a) Obtain authorization serve configuration.

b) Send authorization request via browser and process the response sent to the app’s handler(redirect uri).

c) Make a direct call to token endpoint and process the response.

Request and response examples from my sample app

  1. Authorize request is initiated by the native app via a system browser , notice the additional parameters ( code_challenge and code_challenge_method)

 

https://IDCS_Host:IDCS_Port/oauth2/v1/authorize?client_id=a67adbbf841a4e94b1547a9447d7d95b&response_type=code&code_challenge=e5I_XqXj7eY34Msxr4S1wSuTWgyZh_BUBOyTggrzfjM&code_challenge_method=S256&state=797335&scope=openid&redirect_uri=com.oracle.sample:/oauth2callback

IDCS login page will be shown and user will be asked to authenticate –

IDCS login

Once authenticated, the native app will receive a response on a callback url-

com.oracle.sample:/oauth2callback?code=AQIDBAWK-lPwl8Kfg97qJUh3xr3CPeZrydyiv5_1cXgGmxNDRBrz_XkBVZ1TmjhFILSdPrHn-NCCaDlpp0QEdQPN4K58MTEgRU5DUllQVElPTl9LRVkxNCB7djF9NCA=&state=797335

3.2) Token Request – backend call , an additional parameter (code_verifier) is sent

https://IDCS_Host:IDCS_Port/oauth2/v1/token?code=AQIDBAUpMp5Xdn3ngvd-9EN18ZgsyV3eWJZ0W1gyoVyhD8Rfv3TleItzMDt0aXWBvYzRtym7zdkNsZRxCFlmlOqHVqHgMTEgRU5DUllQVElPTl9LRVkxNCB7djF9NCA=&grant_type=authorization_code&redirect_uri=com.oracle.sample:/oauth2callback&code_verifier=yKGnWqs~vAdQnOZ3b63Lqg5NSdcPYV8YThe6lar1v.hegJz3XVBB5ShZguxjg3&client_id=a67adbbf841a4e94b1547a9447d7d95b

Receives an access token if code_challenge was validated successfully otherwise returns an error.

Troubleshooting tip – IDCS server side diagnostics can be enabled to see incoming requests and troubleshoot further.

Summary

In this post I explained some basics like OAuth 2.0 mobile/public client and PKCE, how to configure a mobile client with Oracle Identity Cloud Service and how to test Oracle Identity Cloud Service support for PKCE.

Add Your Comment