26

We're using the username-password grant to obtain an access token from our auth server. We want to refresh the access token before it expires using the provided refresh token until the user logs out or closes the client app.

However I just cannot find any examples of how to issue this refresh token request..

To obtain the token we call something like:

curl -v --data "grant_type=password&username=user&password=pass&client_id=my_client" http://localhost:8080/oauth/token

So to refresh I'd expect the call to look like this:

curl -v --data "grant_type=refresh_token&access_token=THE_ACCESS_TOKEN&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token

or maybe

curl -v -H "Authorization: Bearer THE_ACCESS_TOKEN" --data "grant_type=refresh_token&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token

But it will just give me a 401..

Oh yeah, maybe I need to add the clientId? I cannot use the client secret, because there is none (see above request to obtain the token). Authentication is done using username and password after all..

I think we have the server configuration right, so I'll not post it here. If one of my example requests should work and you need to see the important config parts I'll add them.

Thanks!

Pete
  • 10,720
  • 25
  • 94
  • 139

2 Answers2

41

So as I said, we don't use a client secret, because we cannot have that hanging around in the Javascript client app. And it's not needed anyway, when using the username-password grant. (See the way we request the access token). Indeed I was close to the solution and finally figured it out:

curl -v --data "grant_type=refresh_token&client_id=THE_CLIENT_ID&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token

so no need for the access token or the client secret.

Over all it feels safe enough.

  • We don't store any secret on the client app side.
  • The users always need a password to log in and can only see their resources.
  • We limit the validity of the refresh token to a realistic time like a workday or something so that even if it is compromised the window for an attacker is limited while still allowing the user to conveniently stay connected to the resource server throughout a long session.
Pete
  • 10,720
  • 25
  • 94
  • 139
  • Not sure why do you need refresh token here at all. Access token with limited validity will behave exactly the same with a simpler workflow. Am I missing something? – long Apr 25 '17 at 10:40
  • 3
    @long what if your access token is expired and your user was still logged in. You will have to get a new access token in that case, and for that we use refresh token – Muhammad Ahsan Aug 17 '17 at 11:46
11

For the password grant_type, a clientId and clientSecret are required. You were close with your third attempt, but you pass the Base64-encoded clientId and clientSecret instead of the Access Token in the Authorization header. This is the proper refresh token request:

curl -H "Authorization: Bearer [base64encode(clientId:clientSecret)]" "https://yourdomain.com/oauth/token?grant_type=refresh_token&refresh_token=[yourRefreshToken]"

For a good reference, check this out: http://techblog.hybris.com/2012/06/11/oauth2-resource-owner-password-flow/

MattSenter
  • 3,060
  • 18
  • 18
  • Hello @Kubgfuters, i have little problem with my configuration. Firstly when i send the request to acces the token, the response will generate successfuly with the token. But when i try to access the resource, if i send base 64 encoded username/password instead of token, the resource will successfully accessed instead of sedning token. this is the url of my confuiguration https://github.com/harmeetsingh0013/dummy_project/blob/master/dummy-project-configuration/src/main/java/com/harmeetsingh13/config/Oauth2SpringSecurityConfig.java – Harmeet Singh Taara Nov 17 '14 at 09:39
  • I assume you're talking about a limitation of Spring security and not OAuth2 in general. Anyways for clarification, it's not required for OAuth2: https://tools.ietf.org/html/rfc6749#section-4.3.2 – Josh Sutterfield Sep 28 '16 at 20:13
  • Hi @MattSenter when I send the refresh token it gives this error.{ "error": "invalid_grant", "error_description": "Invalid refresh token: 291765ad-2651-42d9-b948-19c4a835dbee" } And grant types contains following list. [password,authorization_code,refresh_token,client_credentials,refresh_code] – Sajith Vijesekara Oct 03 '19 at 13:31