I'm reading through the OAuth2 RFC 6749 specs before implementing an Authorization/Resource server for the Resource Owner Password Credentials Grant.
I understand that the Client application uses the refresh_token (along with its credentials) to obtain a new access token for an End User (Resource Owner) rather than storing the End User's username/password and sending them every time an access_token expires.
However, to me this sounds like the refresh_token is as good as an access_token, it's pretty much just an extra server call, so why not use it directly i.e. if the refresh token is valid grant access?
Am I also correct to assume there is one refresh token per End User's session?
However, to me this sounds like the refresh_token is as good as an
access_token, it's pretty much just an extra server call, so why not
use it directly i.e. if the refresh token is valid grant access?
Because that extra server call to the Authorisation Server is important in ensuring access is still allowed to the client app. The resource server would not be able to verify that the refresh token is still good without talking to the Authorisation Server. But this is not the concern of the resource server.
A valid access token is a bearer token. It is used directly on the resource server to get data - no questions asked. If it's not expired, and it has the right scopes - here's the data, whoever you are!
A refresh token on the other hand has to be presented to the Authorisation Server along with client credentials. The Authorisation Server may choose to verify that the resource owner hasn't revoked access to that client, or that the client app itself is still valid. If OK the authorisation server can mint a new, short-lived bearer access token, which is as good as data to anyone who has it!
Related
We have just started out with ASP.NET Web API 2 and implemented OAuth2 client credential token grant, resource owner token grant (for internal apps) as well as code flow token Grant for third party Vendors.
For code flow, when the refresh token is exchanged for a new access token and refresh token the original token is removed from the token store and as such invalidated. The resource owner can also at any time revoke an access token and its associated refresh token.
One of our vendors will follow the code flow grant as there is a requirement that the resource owner or representative authorizes the access to the resource server.
The vendor subsequently requested that instead of the normal flow to redeem the refresh token for a new access token and refresh token, that the host server automatically provide a new access token and refresh token for each request.
The idea that over and above servicing the request, the host API calls back to a pre-determined endpoint on the client domain that will provide a new access token and refresh token.
It goes without saying that such an arrangement introduces complexity within the host API and it would defeat the whole point of short lived tokens and longer lived refresh tokens and we would probably implement other measures to prevent token hi-jacking and other types of attacks.
Currently our authorization server and resource server is one and the same. We would however want to keep the option open to separate the authorization server from the resource in future.
The questions from this then:
Should we consider this arrangement at all?
Would it make sense to adjust to a never expiring access token and not issue a refresh token with the token request?
I'm working on a SPA app based on Node, with token-based authentication using JWT. Right now, the jwt token never expires, which is not good.
I want it to expire for more security, but I don't want my users to be forced to re-log. That's why I need a refresh token.
So i'm reading about OAuth2.
I have a hard-time to understand why refresh-tokens must be stored in a database, whereas access-token are generated on the fly using a secret key.
Why refresh tokens can't be generated the same way as access tokens ?
Thank you guys !
Refresh tokens usually are generated the same way as access tokens.
An authorization server will often return a refresh and access token if requested (and you're not using the implicit grant type).
The difference is how they are used.
An access-token is usually a bearer token: whoever has it can use it against the resource server, but it is only valid for a short period of time. In which case, storing them in a database is often pointless as they are worthless once expired.
A refresh token however is like having access to a "forge" which allows you to mint a new token.
If you present the refresh token to the authorisation server (not the resource server) you will get back a new access token and possibly a new refresh token.
Providing of course that the user has not revoked/changed access permissions to your application and that the user is still a valid user.
So you would keep them in a database perhaps because your user logs in infrequently. So you may need the refresh token weeks after you got it.
Alternative to the refresh token.
If you are using the implicit grant (which is common with SPAs but not recommended). You can try and keep your end user logged in to the identity provider used by the authorisation server. This way you can keep requesting new access tokens from the auth server without the user being prompted by the auth server for credentials as a session will be persisted between the identity provider and the user's browser.
Why can't the client simply send both the access and refresh tokens together for every authorized request? If the access token is expired, it wouldn't require two additional trips to retrieve a new access token and finally making the relevant request.
I realize this operation is amortized, but it would lessen the number of requests for very short access tokens. And under SSL, I don't see how adding the refresh token makes this any more vulnerable. Or does it?
I think the main reason is that the refresh token and the access token are sent to different places. The access token is sent to the resource server and the refresh token is sent to the authorization server. In the general case, there's nothing that the resource server can do with the refresh token.
Some reasons:
The access token provides an abstraction layer, replacing different
authorization constructs (e.g., username and password) with a single
token understood by the resource server. This abstraction enables
issuing access tokens more restrictive than the authorization grant
used to obtain them, as well as removing the resource server's need
to understand a wide range of authentication methods.
https://www.rfc-editor.org/rfc/rfc6749#section-1.4
Having the resource servers understand refresh tokens means more work for them when it can / should be abstracted away (by the authorization server).
...
Because refresh tokens are typically long-lasting credentials used to
request additional access tokens, the refresh token is bound to the
client to which it was issued. If the client type is confidential or
the client was issued client credentials (or assigned other
authentication requirements), the client MUST authenticate with the
authorization server as described in Section 3.2.1.
https://www.rfc-editor.org/rfc/rfc6749#section-6
A refresh request requires client credentials. The resource server shouldn't have to ever see the client's credentials.
Refresh tokens are meant to be long-lasting, while access tokens aren't (or shouldn't be).
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 am following this tutorial about OAuth2.0 https://developers.google.com/youtube/v3/guides/authentication
It looks quite clear how OAuth2.0 works. But I have a bit confusion at the access token part.
After obtaining an access token for a user, your application can use
that token to submit authorized API requests on that user's behalf.
The API supports two ways to specify an access token: Specify the
access token as the value of the access_token query parameter:
www.googleapis.com/youtube/v3/videos?access_token=ACCESS_TOKEN
if someone acquired this access token during the url transferring they can access this protected resource right?
How the server know if the request is coming from the client initially requested the access token?
UPDATE:
after reading this post Are HTTPS headers encrypted? my confusion is cleared. I thought query string is not encrypted during transmission in the network.
Generally I think the consensus is that OAuth 2.0 is a server side technology and all access tokens and communication should be transmitted using SSL as the bearer tokens need to be kept as secure as possible.
Also, you need to know that there are 2 types of flows in OAuth 2.0
i) Implicit grant flow - This is the flow where the user logs in to the service provider and his browser gets the access token. Say you have X.com and Log in via Facebook. Once the user keys in his FB credentials, the access token is sent to his browser.
ii) Authorization Code flow - In this flow (consider the above situation again), facebook will pass an authorization code to the user's browser. If anyone, somehow, intercepts the authorization code there is nothing he can do. An authorization code can be exchanged for an access when passed with valid client credentials. So, when the user logs in, his browser gets an authorization code which is passed to your server at X.com. from there you would hit the code-token exchange endpoint provided by FB and get the access token returned to your server!
Authorization code flow adds another layer of security, where the access token is visible only to the client + server and not to the user agent. And as you figured out yourself, the token is passed via HTTPS.