OAuth, Implicit Flow, and Authorization Code Flow

By | January 5, 2020

If you ever tried registering applications in Azure, you have probably seen the term “implicit flow”. I’ve seen it a few times, and, finally, I’ve figured I need to get to the bottom of it. What I ended up with is the post below – it’s not meant to cover OAuth in details, but it is meant to provide a conceptual explanation and required references, even if only so I would know where to look for all this information when I need it again. If you find inaccuracies there, please drop me a note.

The purpose of OAuth is to provide a way for the users to authorize application access to various API-s. Once the authorization is provided, a token will be issued which the application will be able to utilize to call those API-s.

It all starts with registering a client (which is represented by a client id) on the authorization server. That client is normally set up to require access to certain API-s. However, required access is not granted automatically – it’s the user who has to authorize the client first.

So, you might ask, why can’t we keep utilizing user identity all the time? Why introducing those client id-s etc? Actually, it’s just a matter of reducing the “attack surface”. For example… As an Office 365 user, you might be able to access Common Data Service Web API, SharePoint API-s, Exchange API-s, and a whole lot of other services. However, when authorizing a client, you will only be authorizing access to certain API-s (so, an authorized client app might get access to the CDS API-s, while it won’t have access to the Exchange API-s).

Now, imagine there is a web page, and there is a JavaScript that needs to call certain API. When the page is loaded, it should not be able to just call that API – some kind of authentication and authorization has to happen first. Imagine there is an OAuth server, and there is a client registered there which can access required API-s. The idea is that, knowing the client ID, our imaginary web page needs to do a few things:

  • It needs to somehow ask the user to authenticate and authorize the usage of that client (which essentially means providing authorization to access those API-s)
  • Once this happens, it needs to somehow confirm to the API-s that it’s been authorized to use them

 

Let’s assume for a moment that the authentication and authorization has already happened. How does the second part work?
That is, actually, relatively straightforward (at least conceptually). On the client side, we just need to add authorization token to all API calls as a request header:


POST /api?param=123 HTTP/1.1
Host: apiserver.com
Authorization: Bearer AbCdEf123456

It will be up to the API to validate those tokens – for example, the API might just confirm token “validity” with the authorization server. Well, if you want to explore this topic a little more, have a look at this post:
https://dzone.com/articles/oauth2-tips-token-validation


But how does our imaginary web page gets that token to start with?

That’s what happens as part of the authorization grant, and this is where things get messy since there are different authorization grant flows. In other words, there are different ways our web page (or our application) can get a token from the authorization server.

You’ve probably spotted two of those authorization grant flows while looking at the Azure B2C configuration, or while trying to create app registrations in Azure portal:

  • Authorization code flow
  • Implicit flow

 

However, even though the authorization server might be able to support different authorization grant flows, not all of those flows might be supported on the client side.

There is a detailed explanation of how those flows work in the following post:

https://developer.okta.com/blog/2018/12/13/oauth-2-for-native-and-mobile-apps

I’ll copy one of the images from the post above just to illustrate, quickly, what’s happening in the implicit flow:

Implicit Flow

There is a bunch of redirects in this flow. You will open the browser, it will load the page, and the script in that page will realize that it needs to get a token. So, the script will redirect your browser to the authorization server, and, as part of that redirect, it will also specify that it wants to use implicit flow by passing “token” for the “response_type” in the query string:

https://alexbilbie.com/guide-to-oauth-2-grants/

From there, the user will provide the authorization, the token will be issued, and it will be sent back to the client browser as a url fragment…

What’s a url fragment? That any part of the url following the ‘#’ character. URL fragments are special since browsers won’t add fragments to the requests – instead, fragments live on the client side and they are available to the javascript running on the browser side. If you are interested in how fragments behave, have a look at the post below:

https://blog.httpwatch.com/2011/03/01/6-things-you-should-know-about-fragment-urls/

That reduces the “exposure” of OAuth tokens on the network, so this flow becomes more secure. However, it is still less secure than the other one (authorization code flow), and, actually, it’s been deprecated:

https://oauth.net/2/grant-types/implicit/

Why was it introduced in the first place, though? This is because authorization code flow usually requires cross-domain calls, and, come to think of it, cross-domain calls from javascript were not really supported when OAuth was introduced.

Things have changed, though. JavaScript-based applications should not have a problem utilizing cross-domain calls today:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Although, there is probably still a lot of apps which have not been migrated, so implicit flow may still be needed in many cases.

There is one important aspect of the authorization flows which I have not mentioned so far, and it’s the “redirect url-s”.

Imagine that our web page has redirected the browser to the authorization server, the user has provided required authorization, the token is ready… where should the authorization server “redirect” the browser now (since it’s all happening in the browser in this scenario)? This is what redirect url-s are for, and, if you are interested in a bit more details, have a look at the page below:

https://www.oauth.com/oauth2-servers/redirect-uris/

Hope this helps, though, as usual in such cases, somehow I have a feeling there is still more to it:)

PS. There is a continuation to this post here: https://www.itaintboring.com/power-platform/power-app-portals-and-azure-ad-b2c/

Leave a Reply

Your email address will not be published.