OAuth 2.0 is something I
believe most of us can get confused with (I still do at times).
Sometimes people get confused with OAuth 2.0 and
OIDC (OpenID Connect) as well.
OAuth 2.0 is a
standard protocol for Authorization. But in the past, different major
companies have started using OAuth 2.0 for Authentication by extending it in their own ways. Then some
genius set of people thought to make it a standard, thus they came up
with OIDC (OpenID Connect) specification which is to be used for Authentication.
So the key concept is that OIDC is an additional identity layer built on top of the OAuth 2.0 protocol.
Anyway, in this post, thought of writing a post about the most widely used
OAuth flow: Authorization Code, and have it compared with the
Implicit flow. (Implicit flow is considered legacy now and
its use is recommended to replace with
Authorization Code with PKCE which is a slight variation
of Authorization Code)
For this post, I am considering Microsoft Identity Platform as the Identity
Provider, this can be Auth0, Okta, Google, or even your own Identity Server
implementation. The URLs and scopes are simplified for brevity.
Authorization Code Flow
The Authorization Code grant type is used by confidential and public clients
that use server-side technologies.
|
Authorization Code Flow
|
#1: The authorization code flow begins with the client directing the
user (Resource Owner) to the /authorize endpoint. It's an HTTP GET
request, something like follows.
GET: https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize?
&client_id=myapplication-client
&response_type=code
&redirect_uri=https://myapplication.com/callback
&scope=Calendars.Read
&state=some-state
One of the most important thing here is the response_type=code, we are basically asking for an Authorization code. Now the user will be
redirected to the Identity provider login page, in this case it's Microsoft.
#2: After the user has entered their Email and Password, upon
successful login, the user will be presented with a consent screen. There the
scopes requested will be visible.
#3: Upon accepting the consent, the user will be redirected to
the redirect_uri with an authorization code.
https://myapplication.com/callback?state=some-state&code=eyJraWQiOiIzcG...
#4: Client now makes a Back channel request to
/token endpoint to exchange the authorization code received to an
access_token.
POST: https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token
content type application/x-www-form-urlencoded
grant_type=authorization_code
client_id=myapplication-client
client_secret=<client_secret>
code=<code_received_from_authorize_endpoint>
#5: For above request, the client will receive a response, something
like below.
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI...",
"token_type": "Bearer",
"not_before": 1664733775,
"expires_in": 3600,
"expires_on": 1664737375,
"scope": "Calendars.Read"
}
#6: Now the client has the access_token in the form of a JWT token, the client can call the Resource Server using
that.
A couple of important things to note here. In the picture above, note that the
steps from #1 to #3 is happening on the Front channel, while the
steps from #4 to #6 happen on the Back channel. The reason is,
in step #3, a client_secret is involved and we shouldn't be exposing that to the outside.
Note: It is now recommended to use the Authorization Code with PKCE flow to provide better security even though a client is using
a client_secret.
Implicit Flow (Legacy)
|
Implicit Flow |
This flow was a simplified OAuth flow previously recommended for native apps
and JavaScript apps (SPA). Here we are directly asking for the access_token in the first place by setting response_type=code, so the authorization code exchange step is skipped. That introduces a
security risk when returning access tokens in an HTTP redirect without any
confirmation that it has been received by the client. Because of that reason,
Implicit flow is now deprecated and public clients such as native apps and
JavaScript apps should now use the Authorization Code with PKCE flow instead.
Hope this helps.
Happy Coding.
Regards,
Jaliya