Im using a 3rd party api server side, which generates an access_token and a refresh_token as per normal via a grant_type=password request. I'm confused because this api does not appear to support grant_type=refresh_token - I keep getting the unsupported grant type error. Does it even matter, when you can just handle unauthorized errors by re-firing the password grant request? is this typical for 3rd party api use?
The reason that the resource owner password credentials grant issues a refresh token, is so that the client does not have to keep the password around in clear text for later use.
The client is supposed to collect username and password, use it to get an access and refresh token and discard the password.
Make sure to send a POST request with Content-Type set to application/x-www-form-urlencoded and include client credentials in a basic authorization header if your authorization server requires it. See RFC-6749 for an example.
Related
Something I can't wrap my head around.
As I understand the authorization code flow is supposed to be more secured than the implicit flow, because the tokens are not directly sent to the client from the authorization server, but rather retrieved by your backend.
So the flow is basically:
Browser gets the authorization code (as a URL parameter of sort).
Sends it to a public backend endpoint.
The backend sends the code + client secret to the authorization server, retrieves the tokens and stores them in the client's cookie/local storage for further use.
In this flow all the tutorials describe the authorization code as useless to the hacker, why is that? Can't a hacker use Postman or some other client and access your (public) API directly, make it go through step 3 and thus retrieve the tokens just the same?
What am I missing here?
The code is used exactly once. In many scenarios that an attacker might get access to the code, it's already been exchanged for an access token and therefore useless.
The authorization_code is a one-time token.
Authorization Code aka auth code is used publicly so that the client can establish a secure back channel between him and the authorization server so that he can exchange it with the access token without the use of a browser.
The auth code is public and can be intercepted via a proxy since it appears in the query of the redirect_uri and is used via the browser (which is considered insecure). The access token depends on the auth_code (public) and the client_secret (private) for the exchange. Without the client_secret an attacker can get the access token with brute-forcing this way through.
Summary: even if the attacker knows the authcode he can do anything without the client_secret given to the client at registration (or dynamically) and assumed to be secured.
I have a back-end processor, (imagine a chron job once a day generating reports), that needs to integrate with a third-party system. Their APIs only support the "Authorization code" grant type. The problem is I can't even fill out a request for a token as I don't have a redirect_uri (no website), and I definitely don't have a user of any kind. I'll just have the OAuth clientId and secret I provisioned via their developer portal, (Mashery), for my back-end report processor app.
I want to use the "Client credentials" grant type/flow since I'm just a back-end service.
Is there any way to fake this or hack it so my little back-end service can somehow work with authorization code flow?
Thanks in advance
No, there is no way to hack it. Client credentials only authenticate the client. A token issued for client credentials have no information about the user. If their API needs information about the user (you probably get information only about your user), then you need to have a token issued with Code Flow.
What you can do is to generate the OAuth token yourself. E.g. you can use oauth.tools to perform a Code Flow with their Authorization Server, or you can perform the flow from browser with a dummy redirect URI (e.g. http://localhost), the get the code returned from authorization request and perform a token request from curl.
Once you have an access and refresh token you can hard code them in your script (or read them from an env variable or file, etc). You can then call the API as long as the access token is valid, and use refresh token to get a new access token when it expires. You will not have to perform a new Code Flow for as long as the refresh token is valid.
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!
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.
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.