3

Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).

Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.

Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?

But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??

I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.

Ahmad Akra
  • 505
  • 4
  • 14

1 Answers1

1

Short answer/suggestion

Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.

Explanation

ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.

But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.

Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!

Community
  • 1
  • 1
Kavindu Dodanduwa
  • 12,193
  • 3
  • 33
  • 46
  • Let's say the SPA receives both the Id token and the access token from the identity provider. And then the SPA did its dues and validated the signature of the id token. Now if the user is malicious s/he can do anything with these tokens that the SPA is keeping (since it's a SPA and inherently open). So the user can at will replace the access token with anything else. So when the API receives the access token from the SPA, and uses the claims inside it to ensure that this is Joe for example, it seems to be relying on the access token for authentication – Ahmad Akra Nov 12 '18 at 13:28
  • That's why for the life of me I don't understand why is the identity provider sending TWO tokens in the first place, it seems pointless. And why do they stress in the documentation that the access token is not for authentication – Ahmad Akra Nov 12 '18 at 13:33
  • Well same can be said for sessions right. Think about a simple web app relies on a session. End user can use those values to do anything if s/he really wants to. But from service provider's point of view, session can be secured from third party. Two tokens exist because of the way protocols were designed. OIDC is built on OAuth 2.0. Thus OIDC has ID token for client application's authentication and Access token for protected resource access. ID token is not intended to be shared – Kavindu Dodanduwa Nov 13 '18 at 01:57
  • Beside this discussion being old, recently OAuth working group decided not to recommend Implicit flow - https://medium.com/@torsten_lodderstedt/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926 . This justifies some of your doubts. – Kavindu Dodanduwa Nov 13 '18 at 01:59