Request access token via /oauth/token/ endpoint using code

Imported Google Group message. Original thread at: Redirecting to Google Groups Import Date: 2016-01-19 21:15:55 +0000.
Sender:Pascal Combescot.
Date:Friday, 12 June 2015 15:35:31 UTC+1.

Hi,

I cannot find the documentation on the /oauth/token/ API

I am trying to get an access_token from a code generated via the /tyk/oauth/authorize-client/ endpoint

The request look like this :
curl -H “Authorization: Basic {{client secret}}” -d “grant_type=authorization_code&client_id={{client_id}}&code={{auth code generated by /tyk/oauth/authorize-client/}}” http://localhost:8080/APPID/oauth/token/

I am getting the following response :
{“error”:“invalid_request”,“error_description”:“The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.”}

In the log I find the following message :
ERRO[82160] ERROR: Invalid authorization message

It seems to be the right Header and the right syntax since if I delete the “Basic” in the Authorization Header I have this message “Invalid authorization header”

What should I put in this Authorization Header ? Not the client secret ?

Thanks in advance
Pascal Combescot

Imported Google Group message.
Sender:Martin Buhr.
Date:Friday, 12 June 2015 15:49:57 UTC+1.

I took a look at my test collection, and it looks like you may need to include a few more parameters in your form data:

grant_type
client_id
redirect_uri
client_secret
code

Hope that helps :slight_smile:

Cheers,
Martin

Imported Google Group message.
Sender:Pascal Combescot.
Date:Friday, 12 June 2015 16:48:19 UTC+1.

I have added the client_secret and the redirect_uri parameter but I have the same error

curl -H “Authorization: Basic {{client_secret}}” -d “grant_type=authorization_code&client_id={{client_id}}&code={{code}}&redirect_uri={{redirect_uri}}&client_secret={{client_secret}}” http://localhost:8080/APPID/oauth/token/

The error is generated by the Authorization Header it seems

Could you give me a sample request that answers you an access_token ?

I found about the authorization header in this test class https://github.com/lonelycode/tyk/blob/master/oauth_manager_test.go but I don’t know if it is still used and if it should indeed contains the client_secret

Imported Google Group message.
Sender:Martin Buhr.
Date:Friday, 12 June 2015 18:25:43 UTC+1.

Have you set the content type header?

Imported Google Group message.
Sender:Martin Buhr.
Date:Saturday, 13 June 2015 12:17:11 UTC+1.

Hi Pascal,

The test does the following:

It sets these request parameters:
grant_type
redirect_uri
client_id
code

It then also sets the Authorization header. This test passes, so it works with our Oath implementation.

There’s a great guide here that explains things better (OAuth 2 Simplified • Aaron Parecki), this guide was used to set up the original tests, so it’s a good place to start, a token request looks like this:

POST https://api.oauth2server.com/token
grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET

Now this isn’t setting the auth header, so it may not be required, but even if it isn’t, it is optional since our test passes :blush:

I haven’t got a sample auth request to hand I’m afraid, I’ve gone through some of my old test requests and found one I was using, here it is:

Form data:
grant_type=authorization_code&client_id=21e2baf424674f6461faca6d45285bbb&redirect_uri=http%3A%2F%2Foauth.com%2Fredirect&client_secret=MWI1Mzk4MzktMGNjNi00ZWI2LTZlMzYtMDY0MWY2ZmEwNDQ1&code=NmM1ZGZmZWQtOWE1MS00ZWI0LWJhYmQtNjAwMDcwMzU1Yjg4

Header:
Authorization:Basic MjFlMmJhZjQyNDY3NGY2NDYxZmFjYTZkNDUyODViYmI6TVdJMU16azRNemt0TUdOak5pMDBaV0kyTFRabE16WXRNRFkwTVdZMlptRXdORFEx
Content-Type:application/x-www-form-urlencoded

The Auth header will be needed because it will be checked by Tyke to grab the client so it cn verify the secret. Here it is including the client_secret in the params, which is odd, it may or may not be needed :-/ (long time since I’ve worked on this, so forgive me if my Oath knowledge is rusty).

I think the Basic header is correct, you will need to base64 encode it though.

The client secret looks like it base64 encoded too. As is the code. You may need to make sure that all the params are encoded correctly.

I hope that helps.

Many thanks,
Martin

Imported Google Group message.
Sender:Pascal Combescot.
Date:Tuesday, 16 June 2015 14:53:33 UTC+1.

Hi,

I finally found the way to make it work. The parameter client_secret is not necessary and I would suggest not to send it since it could be logged in access_log files.
The Authorization Header is build as follow : Basic base64_encode(client_id:secret)

Still I have some questions left :
How long is the code valid to be exchange for access_token/refresh_token ? It seems not to be very long
How long is a refresh_token valid ?

Thank you for sample request, I don’t think I would have guessed it on my own :slight_smile:

Pascal Combescot

Imported Google Group message.
Sender:Martin Buhr.
Date:Tuesday, 16 June 2015 15:14:06 UTC+1.

Hi,

Looking at the code in the osin package, the osin server has the following default expirtion times in seconds:

AuthorizationExpiration: 250,
AccessExpiration: 3600,

So you have 4 minutes to claim a token and one hour for access data.

Dug around in the code and found that a refresh token only lasts 3600 seconds by default.

Not ideal, I may want to increase that, or make it configurable.

Thoughts?

Martin

Imported Google Group message.
Sender:Martin Buhr.
Date:Tuesday, 16 June 2015 15:31:49 UTC+1.

On reflection have made this configurable and made the defaul (non-configured) to 14 days. This will be in v1.7 and is available in master.

M.

Imported Google Group message.
Sender:Pascal Combescot.
Date:Wednesday, 17 June 2015 10:06:54 UTC+1.

Indeed if the refresh token do not last longer than the access_token it is not very useful :slight_smile:
Thanks for all the infos, it is consistent with my observations

One last thing, it seems the service /tyk/keys/?api_id= (that should list all the declared keys for a given api) is not working in Tyk 1.6. It is not essential, still it is very useful for debugging and I don’t feel like putting a new version in production without this api working (it was working in v1.5)

Do you know about this ? Will it be repaired in v1.7 ?

Pascal Combescot

Imported Google Group message.
Sender:Martin Buhr.
Date:Wednesday, 17 June 2015 11:59:23 UTC+1.

The key listing API works in 1.6, however you will need to disable key hashing in your Tyk.conf and dashboard configs.
Being able to list keys goes against the benefit of having the security of a hash, so that API is not functional I t his secure mode.
M.

Imported Google Group message.
Sender:Pascal Combescot.
Date:Thursday, 18 June 2015 10:45:29 UTC+1.

Ok sorry I didn’t know about this parameter and I agree it is more secure for a production platform

Is it possible to list all the keys that have access_rights for a given api_id ? (assuming I am in the mode “hash_keys”: false)

When I call the service for a known api_id it seems to give me all the declared keys, no matter for what API the key has been given access_rights to (it was also the case in v1.5). Perhaps I am missing something in the configuration or in the service purpose

If I send an unknown api_id it tells me “API not found” so it seems the parameter is being handle

Pascal

Imported Google Group message.
Sender:Martin Buhr.
Date:Thursday, 18 June 2015 10:56:07 UTC+1.

Hi Pascal,

I’m afraid not - keys are stored in redis by the key name, there is no real way to search by value at the moment.

However, if you use the policies feature to attach a policy to a key, you can bulk control access rights across whole swathes of keys.

Regarding the api_id, this parameter does not filter by API, it filters by session handler. Tyk allows you to add custom back-ends to authorization and session handlers (e.g. for LDAP or other DB’s). In order for Tyk to know which session handler to query when it gets a key listing request, it needs to know the API ID, since the handlers can be defined per-api. The default is Redis, so no matter which APi ID you query, it will use the redis handler, which will display all keys.

There is no way to pull keys for a specific API (yet), if we do introduce it, it will probably be a breaking change as we would need to change how keys are namespaced.

If you use the developer portal (or even just abuse their POST endpoints), the portal will map Developer -> API -> hash(Key), in the next version of the dashboard we have introduced an endpoint to pull developers by API.

There’s a post somewhere on this forum where a team are doing just this - they don;t want the portal, but they want the link between named developer and key.

Obviously, this can also be done programatically - as in, if you use the APi to create the key, then you can store metadata about it elsewhere outside of Tyk (including it’s unhashed representation).

Just a few options :slight_smile:

Thanks,
Martin