I have very little experience with Oauth 2.0 and am trying to better understand how the system works. Are access tokens tied to a user/device/session? For example, can I migrate an access token granted for one app and use it in another app? How will the server/API know? I believe most APIs have apps request using an app_ID, is there any other data that goes into a request for a token?
Thanks!
The OAuth 2.0 protocol framework is designed to allow for different types of access tokens but the only access token that has been standardized so far is the so-called "Bearer" token, so I'm assuming your question is about that.
A Bearer token is opaque to the Client which means that it is just an "identifier" or "string" that the Client passes on to the Resource Server to get access to protected resources. This also means that it is not specifically tied to a device/session or Client. In fact anyone who gets a hold of the Bearer token can actually use it to get access to the protected resources. This is one of the known drawbacks of Bearer tokens but it makes it very easy to implement them. It relies on a secure HTTPs channel for confidentiality.
The previous paragraph describes how to use a Bearer token. The process that the Client has to go through to obtain such a token, may include presenting a Client identifier and a Client secret to the Authorization Server indeed. But the Resource Server (aka. Server or API) does not know or care how the Client obtained the Bearer token.
There are token extensions of OAuth 2.0 under development that would require the Client to proof that it is the rightful owner of the token. Such tokens are called "Proof of Possession" Tokens and may be useful in environments that have higher security requirements. See: http://www.thread-safe.com/2015/01/proof-of-possession-putting-pieces.html
Related
I know that the access token obtained from OAuth2.0 can be used to access protected resources.
OpenID Connect issues ID token and access token after authentication. And the spec says that the access token can be used to access userinfo endpoint to get additional user information.
One thing I'm not able to understand is, is there any difference between the access token obtained in #1 vs #2. If there is no difference then do we need OAuth2.0, if we implement OIDC.
You tend to just implement both OIDC and OAuth 2.0 together as a combined flow, by plugging in an Open Id Connect security library.
Eg For a mobile app it is common to plug in AppAuth Libraries, which would give you this behaviour:
An OAuth 2.0 authorization redirect using response_type=code
The Open Id Connect part is initiated by including scope=openid
You then get an authorization code (OAuth 2.0)
You then swap the authorization code for tokens
You get an access token (the OAuth 2.0 part)
You also get an id token (the OIDC part)
In practical terms OIDC introduces some standardisation that makes developing UI flows and dealing with access tokens in APIs easier, eg:
Metadata endpoint, to tell us where all the other endpoints live
JWKS endpoint, from which we can get the access token's public key
Typically in my own code I do not use the id token much at all. However, it is best practice to receive one, so that libraries such as AppAuth can make extra verification checks against received tokens.
If it helps, my Message Workflow Blog Post summarises some messages and use of endpoints.
This access tokens have different audiences ("aud" claim): the OAuth 2.0 access token is intended for resource server (i.e. API), and OIDC access token is intended for identity server itself.
As for me, they cannot be used interchangebly, but some examples (e.g. IdentityServer4) do that without checking the "aud" claim.
PS. The single access token can be used for both purposes if both audiences are included:
Each principal intended to process the JWT MUST identify itself with a
value in the audience claim.<...> In the general case, the "aud" value
is an array of case-sensitive strings, each containing a StringOrURI
value.
JWT doc
I very clearly understand the OAuth2 token exchange flows and roles. What I'm not clear about is how it maps on real world scenarios. If I have a website which acts like a GUI portion (Client) that communicates to the backend rest API (Resource Provider), it requests token from Auth server to authenticate to RP. The token usually carries scopes the describe user's permissions or roles as they would be enforced by the RP. However, the GUI usually needs to make decisions based on which scopes/roles have been granted to the token. On the one side it looks like it should be introspecting the token to figure out this information to "adapt" UI to match user's permissions. On the other, tokens are not required to be readable, they might be opaque. It seems like authorization decisions are being done on both Client & RP, which would seem to indicate client is also a secondary RP? What is the intended pattern for GUI to receive roles/scopes that the user granted it access to?
Are you talking about OAuth2.0 or OIDC or both? You've tagged openid so I'll assume both.
It seems like authorization decisions are being done on both Client &
RP
An OAuth2.0 client is an OIDC relying party. They are the same thing.
If you are using the hybrid grant - i.e. you are using OAuth2.0 with OIDC to get an access_token and an id_token then your id_token will contain information your client (relying party) can use. It is a JWT token and has an information format which you can rely on. It's also transparent.
The access_token on the other hand may be opaque, it may not - either way it is for your client to pass on to your resource server and not to try and use itself.
The access_token should contain scopes related to what your client can access on the resource server (your backend rest API), whereas your id_token should contain claims related to who the user is, when and how he authenticated and any other identity claims about him supplied by the Identity provider / Authorisation server. These claims may allow your client to tailor the GUI as required.
In OAuth2.0 Authorization Code Grant as stated in RFC 6749, the token request requires client secret according to sec4.1.3; however, the authorization request is not according to sec4.1.1.
Does anyone know why? It seems using client secret for both authorization and token request makes the process more secure.
They are different because they are two different types of requests. 4.1.1
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
Is used to display the actual consent screen to the user.
Once the user has accepted then the code is exchanged for an access token
>HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
No secret is needed because you are currently in the Authorization Code section of the document.
4.1. Authorization Code Grant
The authorization code grant type is used to obtain both access
tokens and refresh tokens and is optimized for confidential clients.
Since this is a redirection-based flow, the client must be capable of
interacting with the resource owner's user-agent (typically a web
browser) and capable of receiving incoming requests (via redirection)
from the authorization server.
Authorization Code is sometimes refereed to as the Implicit flow, as the required access token is sent back to the client application without the need for an authorization request token. This makes the whole flow pretty easy, but also less secure. As the client application, which is typically JavaScript running within a Browser is less trusted, no refresh tokens for long-lived access are returned. Returning an access token to JavaScript clients also means that your browser-based application needs to take special care – think of XSS (Cross-Site Scripting) Attacks that could leak the access token to other systems.
Basically a user implicitly trusts their pc so there is really no need for the client secret validation step. Client secret is only needed for server sided applications where the user does not have access to the server so the server must validate itself.
Can someone tells me the difference in OAuth2, Auth0, JWT in a concise way and when to use either one and which one is much better?
OAuth2.0 is the name of the protocol you can use to get tokens that can be used to perform an action on behalf of the user. Now these tokens can be used to access some 3rd party API or your own Service.
For example, if you wanted to access someones emails on Outlook for an app you're building, OAuth2.0 allows you to get an Access token (issued by Microsoft) on the end user's behalf (they have to sign in to the identity provider) that can be used in a bearer request (just an HTTP request w/ the Access token).
Highly recommend skimming the RFC to read about the different scenarios OAuth2.0 can be used, the example here is just one case.
JWT (JSON Web token) is the standard format of a token used by many identity providers. Those Access tokens above may come in this format. Here's a small site you can use to decode JWT tokens (try hitting the example token).
Auth0 is a private company that works in the Identity space.
I'm developing a REST API which uses an Access Token for verifying & validating.
There is one scenario where user can obtain the Access Token by providing proper credentials and use the same Access Token from a different machine to access any REST API.
I just wanted to check if there's any downside to allowing such a case?
Assuming we're talking OAuth 2.0: it actually depends on the access token type: a so-called Bearer access tokens can be used by any Client that gets hold of it. Bearer access tokens are used in the majority of OAuth 2.0 deployments today.
Other types of access tokens are emerging (so-called Proof of Possession tokens) that require the Client to prove that they are really the intended presenter. In that case just having the access token on a different machine is not enough. In even more advanced emerging scenario's ("token binding") the token may be bound to the TLS connection so it can never be used by another Client or on another connection.
But as said, for the majority of OAuth 2.0 deployments today, it would be possible to use the Bearer access token from another machine.
The access token should be signed by the server, and shouldn't include any information about the specific client/machine used to access it.
For example, in the OAuth 2.0 password grant flow, the username/password is exchanged for an access token. The token is signed by the issuing token server, and represents that user's authentication and authorization claims. What machine the user is making requests from makes no difference.
So, tl;dr - yes, access tokens are portable between machines. It's not a typical use case (how would the access token get from one machine to another?), but it's perfectly valid.