According to RFC6750-The OAuth 2.0 Authorization Framework: Bearer Token Usage, the bearer token is:
A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can.
To me this definition is vague and I can't find any specification.
Suppose I am implementing an authorization provider, can I supply any kind of string for the bearer token?
Can it be a random string?
Does it have to be a base64 encoding of some attributes?
Should it be hashed?
And does the service provider need to query the authorization provider in order to validate this token?
Bearer Token
A security token with the property that any party in possession of
the token (a "bearer") can use the token in any way that any other
party in possession of it can. Using a bearer token does not
require a bearer to prove possession of cryptographic key material
(proof-of-possession).
The Bearer Token is created for you by the Authentication server. When a user authenticates your application (client) the authentication server then goes and generates for you a Token. Bearer Tokens are the predominant type of access token used with OAuth 2.0. A Bearer token basically says "Give the bearer of this token access".
The Bearer Token is normally some kind of opaque value created by the authentication server. It isn't random; it is created based upon the user giving you access and the client your application getting access.
In order to access an API for example you need to use an Access Token. Access tokens are short lived (around an hour). You use the bearer token to get a new Access token. To get an access token you send the Authentication server this bearer token along with your client id. This way the server knows that the application using the bearer token is the same application that the bearer token was created for. Example: I can't just take a bearer token created for your application and use it with my application it wont work because it wasn't generated for me.
Google Refresh token looks something like this: 1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM
copied from comment: I don't think there are any restrictions on the bearer tokens you supply. Only thing I can think of is that its nice to allow more than one. For example a user can authenticate the application up to 30 times and the old bearer tokens will still work. oh and if one hasn't been used for say 6 months I would remove it from your system. It's your authentication server that will have to generate them and validate them so how it's formatted is up to you.
Update:
A Bearer Token is set in the Authorization header of every Inline Action HTTP Request. For example:
POST /rsvp?eventId=123 HTTP/1.1
Host: events-organizer.com
Authorization: Bearer AbCdEf123456
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/1.0 (KHTML, like Gecko; Gmail Actions)
rsvpStatus=YES
The string "AbCdEf123456" in the example above is the bearer authorization token. This is a cryptographic token produced by the authentication server. All bearer tokens sent with actions have the issue field, with the audience field specifying the sender domain as a URL of the form https://. For example, if the email is from noreply#example.com, the audience is https://example.com.
If using bearer tokens, verify that the request is coming from the authentication server and is intended for the the sender domain. If the token doesn't verify, the service should respond to the request with an HTTP response code 401 (Unauthorized).
Bearer Tokens are part of the OAuth V2 standard and widely adopted by many APIs.
As I read your question, I have tried without success to search on the Internet how Bearer tokens are encrypted or signed. I guess bearer tokens are not hashed (maybe partially, but not completely) because in that case, it will not be possible to decrypt it and retrieve users properties from it.
But your question seems to be trying to find answers on Bearer token functionality:
Suppose I am implementing an authorization provider, can I supply any
kind of string for the bearer token? Can it be a random string? Does
it has to be a base64 encoding of some attributes? Should it be
hashed?
So, I'll try to explain how Bearer tokens and Refresh tokens work:
When user requests to the server for a token sending user and password through SSL, the server returns two things: an Access token and a Refresh token.
An Access token is a Bearer token that you will have to add in all request headers to be authenticated as a concrete user.
Authorization: Bearer <access_token>
An Access token is an encrypted string with all User properties, Claims and Roles that you wish. (You can check that the size of a token increases if you add more roles or claims).
Once the Resource Server receives an access token, it will be able to decrypt it and read these user properties. This way, the user will be validated and granted along with all the application.
Access tokens have a short expiration (ie. 30 minutes).
If access tokens had a long expiration it would be a problem, because theoretically there is no possibility to revoke it. So imagine a user with a role="Admin" that changes to "User". If a user keeps the old token with role="Admin" he will be able to access till the token expiration with Admin rights.
That's why access tokens have a short expiration.
But, one issue comes in mind. If an access token has short expiration, we have to send every short period the user and password. Is this secure? No, it isn't. We should avoid it. That's when Refresh tokens appear to solve this problem.
Refresh tokens are stored in DB and will have long expiration (example: 1 month).
A user can get a new Access token (when it expires, every 30 minutes for example) using a refresh token, that the user had received in the first request for a token.
When an access token expires, the client must send a refresh token. If this refresh token exists in DB, the server will return to the client a new access token and another refresh token (and will replace the old refresh token by the new one).
In case a user Access token has been compromised, the refresh token of that user must be deleted from DB. This way the token will be valid only till the access token expires because when the hacker tries to get a new access token sending the refresh token, this action will be denied.
Bearer token is one or more repetition of alphabet, digit, "-" , "." , "_" , "~" , "+" , "/" followed by 0 or more "=".
RFC 6750 2.1. Authorization Request Header Field (Format is ABNF (Augmented BNF))
The syntax for Bearer credentials is as follows:
b64token = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
credentials = "Bearer" 1*SP b64token
It looks like Base64 but according to Should the token in the header be base64 encoded?, it is not.
Digging a bit deeper in to "HTTP/1.1, part 7: Authentication"**,
however, I see that b64token is just an ABNF syntax definition
allowing for characters typically used in base64, base64url, etc.. So
the b64token doesn't define any encoding or decoding but rather just
defines what characters can be used in the part of the Authorization
header that will contain the access token.
This fully addresses the first 3 items in the OP question's list. So I'm extending this answer to address the 4th question, about whether the token must be validated, so #mon feel free to remove or edit:
The authorizer is responsible for accepting or rejecting the http request. If the authorizer says the token is valid, it's up to you to decide what this means:
Does the authorizer have a way of inspecting the URL, identifying the operation, and looking up some role-based access control database to see if it is allowed? If yes and the request comes through, the service can assume it is allowed, and does not need to verify.
Is the token an all-or-nothing, so if the token is correct, all operations are allowed? Then the service doesn't need to verify.
Does the token mean "this request is allowed, but here is the UUID for the role, you check whether the operation is allowed". Then it's up to the service to look up that role, and see if the operation is allowed.
References
RFC 5234 3.6. Variable Repetition: *Rule
RFC 2616 2.1 Augmented BNF
Please read the example in rfc6749 sec 7.1 first.
The bearer token is a type of access token, which does NOT require PoP(proof-of-possession) mechanism.
PoP means kind of multi-factor authentication to make access token more secure. ref
Proof-of-Possession refers to Cryptographic methods that mitigate the risk of Security Tokens being stolen and used by an attacker. In contrast to 'Bearer Tokens', where mere possession of the Security Token allows the attacker to use it, a PoP Security Token cannot be so easily used - the attacker MUST have both the token itself and access to some key associated with the token (which is why they are sometimes referred to 'Holder-of-Key' (HoK) tokens).
Maybe it's not the case, but I would say,
access token = payment methods
bearer token = cash
access token with PoP mechanism = credit card (signature or password will be verified, sometimes need to show your ID to match the name on the card)
BTW, there's a draft of "OAuth 2.0 Proof-of-Possession (PoP) Security Architecture" now.
A bearer token is like a currency note e.g 100$ bill . One can use the currency note without being asked any/many questions.
Bearer Token A security token with the property that any party in
possession of the token (a "bearer") can use the token in any way that
any other party in possession of it can. Using a bearer token does not
require a bearer to prove possession of cryptographic key material
(proof-of-possession).
The bearer token is a b64token string, with the requirement that if you have it, you can use it. There are no guarantees as to what the meaning of that string actually is in the specification beyond that. It is up to the implementation.
5.2. Threat Mitigation
This document does not specify the encoding or the contents of the
token; hence, detailed recommendations about the means of
guaranteeing token integrity protection are outside the scope of this
document. The token integrity protection MUST be sufficient to
prevent the token from being modified.
https://datatracker.ietf.org/doc/html/rfc6750#section-5.2
While the token could be random each time it is issued, the downside is the server side would need to keep track of the tokens data (e.g. expiration). A JSON Web Token (JWT) is often used as a bearer token, because the server can make decisions based on whats inside the token.
JWT:
https://jwt.io/
Related
I need to understand why refresh token issued by AAD is not in JWT format( i used Auth Code grant type for generation of refresh token). It looks something like as follows 0.ATYAoWHs1YRqUk-OAYpDkwKjaYAEJhrbDpBNmWw7q0NZVas2APk....(rest of the token).
Also if we can get this refresh token in JWT format then how can we do that.
Thanks
Abhishek
It isn't in JWT format because it does not need to be.
A refresh token is data that you send to the identity provider to get new access tokens.
It should not have any other meaning for your application.
Store it securely and send it to AAD when you need new tokens.
Then take the new refresh token you get in the response and overwrite your previous refresh token with that.
The OAuth 2 RFC also talks about it https://www.rfc-editor.org/rfc/rfc6749#page-10:
A refresh token is a string representing the authorization granted to the client by the resource owner. The string is usually opaque to the client. The token denotes an identifier used to retrieve the authorization information. Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.
I am using a variant of the in-memory clients defined in the reference IdentityServer4 demo project and after I log into the Identity Server and get redirected, the URI is such that the id_token and access_token are the same exact JWT.
Is this a sensible behavior? Why would you want the id_token and access_token to be the same, ever? Maybe if you don't care about the access_token?
Not sure what you mean same exact JWT. But both access token and ID token can come as JWT tokens.
One good example is OAuth flow of Azure AD. According to the document successful token response return an access token and an id token (yes, Azure does send one for OAuth auth. code flow) both in JWT format (reference). But their contents could be different. For example, one could be a signed JWT and other could not be.
Reason for the usage of JWT is due to self-contained nature of them. For example, token validations can be done easily from client application end as well as protected API end.
Usually if both access token and ID token are JWTs they could be differ by claims. For example audience claim ("aud") could be different depending on intended audience of token.
I'm building a system with OIDC and OAuth 2.0 (using Auth0), and I'm unsure how to properly use the id_token and access_token. Or rather, I'm confused about which roles to assign to the various services in my setup.
I have a fully static frontend-application (single-page app, HTML + JS, no backend) that ensures that the user is authenticated using the implicit flow against Auth0. The frontend-application then fetches data from an API that I am also building.
Now, which is right?
The frontend SPA is the OAuth client application
My API service is an OAuth resource server
...or:
The frontend and my API service are both the client application
If both my frontend and backend API can be considered to be the client, I see no real harm in using the id_token as the bearer token on requests from my frontend to my backend - this is appealing because then I can simply verify the signed token on the backend, and I have all the information about the user that I need. However, if my API is considered a resource server, I should probably use the access_token, but then I have to connect to Auth0's servers on every API request to both verify the token, and get basic user info, won't I?
I've read this which seems to suggest that the access_token is the only valid token for use with my API. But like I said, I'm not sure about the roles of the individual services. And using the id_token is tempting, because it requires no network connections on the backend, and contains information I need to extract the right data.
What is the right way to go about this?
I like this Medium post about the difference, all cred to this author.
https://medium.com/#nilasini/id-token-vs-access-token-17e7dd622084
If you are using Azure AD B2C like I am you can read more here:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect
ID Token
You will get id token if you are using scope as openid. Id token is specific to openid scope. With openid scope you can get both id token and access token.
The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims(claims are name/value pairs that contain information about a user) about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT)
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
The above is default JWT claims, in addition to that, if you requested claims from service provider then you will get those as well.
An id_token is a JWT, per the OIDC Specification. This means that:
identity information about the user is encoded right into the token
and
the token can be definitively verified to prove that it hasn't been
tampered with.
There's a set of rules in the specification for validating an id_token. Among the claims encoded in the id_token is an expiration (exp), which must be honored as part of the validation process. Additionally, the signature section of JWT is used in concert with a key to validate that the entire JWT has not been tampered with in any way.
Access Tokens
Access tokens are used as bearer tokens. A bearer token means that the bearer (who hold the access token) can access authorized resources without further identification. Because of this, it's important that bearer tokens are protected. If I can somehow get ahold of and "bear" your access token, I can pretend as you.
These tokens usually have a short lifespan (dictated by its expiration) for improved security. That is, when the access token expires, the user must authenticate again to get a new access token limiting the exposure of the fact that it's a bearer token.
Although not mandated by the OIDC spec, Okta uses JWTs for access tokens as (among other things) the expiration is built right into the token.
OIDC specifies a /userinfo endpoint that returns identity information and must be protected. Presenting the access token makes the endpoint accessible.
http://openid.net/specs/openid-connect-core-1_0.html
https://connect2id.com/learn/openid-connect#cool-id-token-uses
https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1
Your frontent is your OAuth client application, once it stores the token it can take actions on the OAuth flow. And your API service is resource server, because it accepts the access_token issued by your identity server.
Also I would say that your id_token stands for the identification of the logged user and may contain sensitive data for your app. The access_token is standing as your credential to access a resource.
At the end you will use an access_token to request a resource, and then if you need specific data from the logged in user (resource owner), you may request the ID token from the token endpoint.
In my opinion, the first approach is correct. Your SPA is the client application and your APIs are resource servers.
I would suggest you limit the use of id_token till your SPA only. You can use the basic information present in the id token (like username and email) to display user information within your UI. If you can generate access tokens as JWTs too then your API can validate the access tokens without going to the Identity provider. You can include roles (or similar) in your access token to get authorization information in your access token.
I was also wondering if I need to talk to the IdP on every request if I'm using the tokens received from the IdP. I ended up with the following setup:
Only the backend talks to the IdP, the frontend does not.
Upon the IdP callback the backend issues a JWT for the frontend.
User session and frontend-backend communication is managed entirely by my app using the JWT token.
Check this article: OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc)
and this repo: https://github.com/thisismydesign/nestjs-starter
and this question: OAuth2 flow in full-stack NestJS application
The id_token is an cryptographically encoded token for authentication. The OP (the auth provider) is the one that generates it and the RP (relying party or the resource) will eventually re-present the token to the OP to counter validate when handed over by the client. In short the id_token is tied to authn workflow.
The access_token enables resource access. It does subsume the userinfo i.e., the id_token or any other principal on whose behalf the access is being requested. So this token includes both user claims plus claims to groups that are authorized. In short the access_token is tied to your authz workflow.
I am facing a custom implementation of OpenId Connect. But (there is always a but) I have some doubts:
I understand the process of obtainning an acces_token an a id_token, except the step when the OP provides an authorization_code to the client. If it is done by a redirect (using the redirect uri)
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
The end-user is able to see that authorization code? It does not expire? Imagine we catch it and we use later (some days later) Is it a security hole? Should the state be expired in the Token Endpoint?
The flow continues and we got at the client the Access_token and the id_token in the client.
How the Access_token should be used on the OP side ? It should be stored in a database? Or be self containing of the information required to validate it ?What would you recommend?
And in the client-side , both tokens should be sent in every request?
And the last doubt, if we have an Access_token the existence of an id_token is for representing authorization and authentication in separated tokens?
Extra doubts:
I know the process to obtain an access token but I have doubts of how the OP ,once generated and sent, it validates the access_token that comes with every request
How the OP knows an access token is valid? As far as I know, the OP should say that an access_token is valid/invalid. There should be some way to check it right? How it gets to know that a token represents a valid authenticated user if it is not stored in DB?
Is it a bad idea to store access_token in a cookie? Because sometimes we call to some webservices and we want to send access_token as parameter. Or there is another workaroundsolution?
How the access token should be stored in the Client , for example, in ASP.NET, in the session?
Thanks very much to all of you, I will give upvote and mark as answer as soon as you give me the explanations.
Thanks!
The end-user is able to see that authorization code?
Yes. Although, even if the authorization code can be seen, the token request requires that the client's secret be sent as well (which the browser does not see)
it does not expires? Imagine we catch it and we use later (some days later) It is a security hole? Should the state be expired in the Token Endpoint?
The spec says that the authorization code should expire. See https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2.
How the Access_token should be used on the OP side ? It should be stored in a database? Or be self containing of the information required to validate it ?What would you recommend?
The access token should be stored on the OP if you want to be able to revoke the tokens. If you don't, the token will be in JWT format (self-contained)...but you should store it if you want to be able to revoke it whether it's a JWT or not.
And in the client-side , both tokens should be sent in every request?
No, just the access token.
And the last doubt, if we have an Access_token the existance of an id_token is for representing authorization and authentication in separeted tokens?
Yes, they are separate tokens for different purposes. Access token is for authorization and Id token is self contained and used to communicate to the client that the user is authenticated.
How the OP knows an access token is valid? As far as i know, the OP should say that an access_token is valid/invalid. There should be some way to check it right? How it gets to know that a token represents a valid authenticated user if it is not stored in DB?
see How to validate an OAuth 2.0 access token for a resource server? about thoughts on how the resource server should validate the access token before letting the request from the client go through.
It´s a bad idea to store access_token in a cookie? because sometimes we call to some webservices and we want to send access_token as parameter. Or there is another workaroundsolution?
I'm assuming you're using the authorization code grant flow (...from your questions). If that's the case, the reason why an authorization code is, first of all, passed back from the OP rather than the access token is so that the access token can stay hidden on the server side--away from the browser itself. With the authorization code grant flow, the access token should stay out of the browser. If you're wanting to send api requests to the resource server directly from the browser, then look into the oauth2 implicit flow (https://www.rfc-editor.org/rfc/rfc6749#section-4.2).
How the access token should be stored in the Client , for example, in ASP.NET, in the session?
In the OpenID Connect flavour of OAuth2, the access token is for offline_access (i.e. outside of an authenticated "session"). The access token could be used during the session of the user but it might be better to store the refresh token in the database so that your client app can request new access tokens whenever it needs to and as long as the refresh token is valid...even when the user's authentication is expired. The access token should be short-lived so storing it in the database is an option but not necessary.
I'm trying to implement the Resource Owner & Password Credentials flow from the OAuth 2 spec. I'm having trouble understanding the token_type value that gets sent back with a valid response. In the spec all the examples show "token_type":"example" but says it should be
token_type
REQUIRED. The type of the token issued as described in
Section 7.1. Value is case insensitive.
Can someone please explain this to me?
token_type is a parameter in Access Token generate call to Authorization server, which essentially represents how an access_token will be generated and presented for resource access calls.
You provide token_type in the access token generation call to an authorization server.
If you choose Bearer (default on most implementation), an access_token is generated and sent back to you. Bearer can be simply understood as "give access to the bearer of this token." One valid token and no question asked. On the other hand, if you choose Mac and sign_type (default hmac-sha-1 on most implementation), the access token is generated and kept as secret in Key Manager as an attribute, and an encrypted secret is sent back as access_token.
Yes, you can use your own implementation of token_type, but that might not make much sense as developers will need to follow your process rather than standard implementations of OAuth.
Anyone can define "token_type" as an OAuth 2.0 extension, but currently "bearer" token type is the most common one.
https://www.rfc-editor.org/rfc/rfc6750
Basically that's what Facebook is using. Their implementation is a bit behind from the latest spec though.
If you want to be more secure than Facebook (or as secure as OAuth 1.0 which has "signature"), you can use "mac" token type.
However, it will be hard way since the mac spec is still changing rapidly.
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-http-mac-05
From RFC 6750, Section 1.2:
Bearer Token
A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession).
The Bearer Token or Refresh token is created for you by the Authentication server. When a user authenticates your application (client) the authentication server then goes and generates for your a Bearer Token (refresh token) which you can then use to get an access token.
The Bearer Token is normally some kind of cryptic value created by the authentication server, it isn't random it is created based upon the user giving you access and the client your application getting access.
See also: Mozilla MDN Header Information.