Tuesday, February 7, 2017

OpenID Connect

Introduction

As OAuth2 spec says OAuth2 is delegated Authorization protocol, but NOT Authentication protocol. This lead people to come up with new protocol for Authentication..

OpenID Connect is a simple identity layer build on top of Auth2 protocol. It provides clients a "standard" way to verify the identity of the end-user based on the authentication performed by an Authorization server.

But you may argue OAuth2 can be used as Authentication because in OAuth2 actually authentication is involving as a pre-requisite for authorization and then the access_token can be used to retrieve user information to identify the user.

For example many web applications use OAuth2 based facebook login as a one of authentication mechanism for their web sites. Below diagrams shows the typical oauth2 flow with authorization grant type.




According to this at the end of OAuth flow client app have only access_token. Having an facebook access_token ONLY means particular user is from facebook. Nothing more. So looking at the access_token client app can not say who the user is, but can only say where the user came from and what access user has delegated to client app. So client app can not identify the end user uniquely with OAuth2.

But then how facebook login works?

Facebook provide API (graph API)  to get attributes of users like facebook_id, name, age, email etc... Client app can access this API by providing access token it got.

GET : https://graph.facebook.com/v2.5/me?access_token={access_token}

This will return identity informations (claims) about the user who authorized the access_token and using this info now client can identify user.

Note :
1. This last step (accessing facebook API) is not part of OAuth2 specification. And also other identity providers like google , twitter provide their own API's to access user information. Because of that it is difficult to build standard specification for this approach.
2. Authentication and retrieving  access_token for user endpoint events are not correlated. Because of that access_token token can be used to impersonate the user.
So peoples came up with new protocol for authentication called OpenId Connect - a simple identity layer build on top of OAuth2.

OpenID Connect

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol which extends authorization process of OAuth2 to implement its authentication mechanism. Following two new concepts were introduced along with the spec.

1. Id token : The Id token is a security token that resembles the concept of an identity card and contains claims about the authenticated user. The list of standard claims are used within Id token can be found here.
These claims are package into simple JSON object and represent as a JWT token along with other security parameters.

eg: JSON structure with claims
 {
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "exp": 1311281970,
   "iat": 1311280970
  }
So we can use id token as a authentication and for signing into an application while access token can be used to access resources.

2. User info endpoint : Can be used to by the clients to get more user information of the authenticated user. These additional claims should request along with the access token.

3. openid scope : Remember we used scope parameter in OAuth2 to specify what access privilleges are being requested for access tokens. For OpenID connect scope is used to request specific sets of informations be made available as claim values. Standard list of scope values can be found in here.

Note: In openId connect value of scope parameter of authorization request MUST start with openid. There could be other scopes after that.
i.e : scope = openid profile email

OpenID Connect flows

Now we know what an ID token is, but how can client (in openId connect context called as Relying Party) request id token from server(in openId connect context called as OpenId Provider) securely. OpenId connect specs provide following flows.

1. Authorization code flow (extension of OAuth2 authorization code flow)
2. Implicit flow                    (extension of OAuth2 authorization code flow)
3. Hybrid flow                      (combination of Authorization code and implicit flows)

Authorization code flow

openId auth code flow is very similar to OAuth2 auth code flow except following steps. (Please refer steps of Oauth2 auth code in my blog)

step 1 : Define scope parameter by setting required values preceding with "openid"

HTTP/1.1 302 Found
  Location: https://server.example.com/authorize?
    response_type=code
    &client_id=xxxx
    &redirect_uri=xxx
    &scope=openid profile
    &state=xxx

 step 8: Token endpoint returs id_token along with access_token.
  HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-cache, no-store
  Pragma: no-cache

  {
   "access_token":"SlAV32hkKG",
   "token_type":"Bearer",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "id_token":"eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso"
  }

Now the id token MUST be carefully validate by the client peruse the instruction of openid spec.

Summary

OpenId standardized the authentication process with OAuth2 using following concepts / components. These standard  leverage client to plug arbitrary openId providers without customizing the code.
  • Standard scopes and claims
  • use JWT tokens
  • Id token
  • user info end point