Be Sociable, Share!

After my previous Token Based Authentication post I’ve received many requests to add OAuth Refresh Tokens to the OAuth Resource Owner Password Credentials flow which I’m currently using in the previous tutorial. To be honest adding support for refresh tokens adds a noticeable level of complexity to your Authorization Server. As well most of the available resources on the net don’t provide the full picture of how to implement this by introducing clients nor how to persist the refresh tokens into database.

So I’ve decided to write a detailed post with live demo application which resumes what we’ve built in the previous posts, so I recommend you to read part 1 at least to follow along with this post. This detailed post will cover adding Clients, persisting refresh tokens, dynamically configuring refresh tokens expiry dates, and revoking refresh tokens.

Before start into the implementation I would like to discuss when and how refresh tokens should be used, and what is the database structure needed to implement a complete solution.

Using Refresh Tokens

The idea of using refresh token is to issue short lived access token at the first place then use the refresh token to obtain new access token and so on, so the user needs to authenticate him self by providing username and password along with client info (we’ll talk about clients later in this post), and if the information provided is valid a response contains a short lived access token is obtained along with long lived refresh token (This is not an access token, it is just identifier to the refresh token). Now once the access token expires we can use the refresh token identifier to try to obtain another short lived access token and so on.

But why we are adding this complexity, why not to issue long lived access tokens from the first place?

In my own opinion there are three main benefits to use refresh tokens which they are:

Updating access token content: as you know the access tokens are self contained tokens, they contain all the claims (Information) about the authenticated user once they are generated, now if we issue a long lived token (1 month for example) for a user named “Alex” and enrolled him in role “Users” then this information get contained on the token which the Authorization server generated. If you decided later on (2 days after he obtained the token) to add him to the “Admin” role then there is no way to update this information contained in the token generated, you need to ask him to re-authenticate him self again so the Authorization server add this information to this newly generated access token, and this not feasible on most of the cases. You might not be able to reach users who obtained long lived access tokens. So to overcome this issue we need to issue short lived access tokens (30 minutes for example) and use the refresh token to obtain new access token, once you obtain the new access token, the Authorization Server will be able to add new claim for user “Alex” which assigns him to “Admin” role once the new access token being generated.

Revoking access from authenticated users: Once the user obtains long lived access token he’ll be able to access the server resources as long as his access token is not expired, there is no standard way to revoke access tokens unless the Authorization Server implements custom logic which forces you to store generated access token in database and do database checks with each request. But with refresh tokens, a system admin can revoke access by simply deleting the refresh token identifier from the database so once the system requests new access token using the deleted refresh token, the Authorization Server will reject this request because the refresh token is no longer available (we’ll come into this with more details).

No need to store or ask for username and password: Using refresh tokens allows you to ask the user for his username and password only one time once he authenticates for the first time, then Authorization Server can issue very long lived refresh token (1 year for example) and the user will stay logged in all this period unless system admin tries to revoke the refresh token. You can think of this as a way to do offline access to server resources, this can be useful if you are building an API which will be consumed by front end application where it is not feasible to keep asking for username/password frequently.

Refresh Tokens and Clients

In order to use refresh tokens we need to bound the refresh token with a Client, a Client means the application the is attempting communicate with the back-end API, so you can think of it as the software which is used to obtain the token. Each Client should have Client Id and Secret, usually we can obtain the Client Id/Secret once we register the application with the back-end API.

The Client Id is a unique public information which identifies your application among other apps using the same back-end API. The client id can be included in the source code of your application, but the client secret must stay confidential so in case we are building JavaScript apps there is no need to include the secret in the source code because there is no straight way to keep this secret confidential on JavaScript application. In this case we’ll be using the client Id only for identifying which client is requesting the refresh token so it can be bound to this client.

In our case I’ve identified clients to two types (JavaScript – Nonconfidential) and (Native-Confidential) which means that for confidential clients we can store the client secret in confidential way (valid for desktop apps, mobile apps, server side web apps) so any request coming from this client asking for access token should include the client id and secret.

Bounding the refresh token to a client is very important, we do not want any refresh token generated from our Authorization Server to be used in another client to obtain access token. Later we’ll see how we will make sure that refresh token is bounded to the same client once it used to generate new access token.

Database structure needed to support OAuth Refresh Tokens

It is obvious that we need to store clients which will communicate with our back-end API in persistent medium, the schema for Clients table will be as the image below:

The Secret column is hashed so anyone has an access to the database will not be able to see the secrets, the Application Type column with value (1) means it is Native – Confidential client which should send the secret once the access token is requested.

The Active column is very useful; if the system admin decided to deactivate this client, so any new requests asking for access token from this deactivated client will be rejected. The Refresh Token Life Time column is used to set when the refresh token (not the access token) will expire in minutes so for the first client it will expire in 10 days, it is nice feature because now you can control the expiry for refresh tokens for each client.

Lastly the Allowed Origin column is used configure CORS and to set “Access-Control-Allow-Origin” on the back-end API. It is only useful for JavaScript applications using XHR requests, so in my case I’ m setting the allowed origin for client id “ngAuthApp” to origin “http://ngauthenticationweb.azurewebsites.net/” and this turned out to be very useful, so if any malicious user obtained my client id from my JavaScript app which is very trivial to do, he will not be able to use this client to build another JavaScript application using the same client id because all preflighted requests will fail and return 405 HTTP status (Method not allowed) All XHR requests coming for his JavaScript app will be from different domain. This is valid for JavaScript application types only, for other application types you can set this to “*”.

Note: For testing the API the secret for client id “consoleApp” is “123@abc”.

Now we need to store the refresh tokens, this is important to facilitate the management for refresh tokens, the schema for Refresh Tokens table will be as the image below:

The Id column contains hashed value of the refresh token id, the API consumer will receive and send the plain refresh token Id. the Subject column indicates to which user this refresh token belongs, and the same applied for Client Id column, by having this columns we can revoke the refresh token for a certain user on certain client and keep the other refresh tokens for the same user obtained by different clients available.

The Issued UTC and Expires UTC columns are for displaying purpose only, I’m not building my refresh tokens expiration logic based on these values.

Lastly the Protected Ticket column contains magical signed string which contains a serialized representation for the ticket for specific user, in other words it contains all the claims and ticket properties for this user. The Owin middle-ware will use this string to build the new access token auto-magically (We’ll see how this take place later in this post).

Now I’ll walk you through implementing the refresh tokens, as I stated before you can read the previous post to be able to follow along with me:

Step 1: Add the new Database Entities

Add new folder named “Entities”, inside the folder you need to define 2 classes named “Client” and “RefreshToken”, the definition for classes as the below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

publicclassClient

{

[Key]

publicstringId{get;set;}

[Required]

publicstringSecret{get;set;}

[Required]

[MaxLength(100)]

publicstringName{get;set;}

publicApplicationTypesApplicationType{get;set;}

publicboolActive{get;set;}

publicintRefreshTokenLifeTime{get;set;}

[MaxLength(100)]

publicstringAllowedOrigin{get;set;}

}

publicclassRefreshToken

{

[Key]

publicstringId{get;set;}

[Required]

[MaxLength(50)]

publicstringSubject{get;set;}

[Required]

[MaxLength(50)]

publicstringClientId{get;set;}

publicDateTimeIssuedUtc{get;set;}

publicDateTimeExpiresUtc{get;set;}

[Required]

publicstringProtectedTicket{get;set;}

}

Then we need to add simple Enum which defined the Application Type, so add class named “Enum” inside the “Models” folder as the code below:

1

2

3

4

5

publicenumApplicationTypes

{

JavaScript=0,

NativeConfidential=1

};

To make this entities available on the DbContext, open file “AuthContext” and paste the code below:

1

2

3

4

5

6

7

8

9

10

11

publicclassAuthContext:IdentityDbContext<IdentityUser>

{

publicAuthContext()

:base("AuthContext")

{

}

publicDbSet<Client>Clients{get;set;}

publicDbSet<RefreshToken>RefreshTokens{get;set;}

}

Step 2: Add new methods to repository class

The methods I’ll add now will add support for manipulating the tables we’ve added, they are self explanatory methods and there is nothing special about them, so open file “AuthRepository” and paste the code below:

Step 3: Validating the Client Information

Now we need to implement the logic responsible to validate the client information sent one the application requests an access token or uses a refresh token to obtain new access token, so open file “SimpleAuthorizationServerProvider” and paste the code below:

By looking at the code above you will notice that we are doing the following validation steps:

We are trying to get the Client id and secret from the authorization header using a basic scheme so one way to send the client_id/client_secret is to base64 encode the (client_id:client_secret) and send it in the Authorization header. The other way is to sent the client_id/client_secret as “x-www-form-urlencoded”. In my case I’m supporting the both approaches so client can set those values using any of the two available options.

We are checking if the consumer didn’t set client information at all, so if you want to enforce setting the client id always then you need to invalidate the context. In my case I’m allowing to send requests without client id for the sake of keeping old post and demo working correctly.

After we receive the client id we need to check our database if the client is already registered with our back-end API, if it is not registered we’ll invalidate the context and reject the request.

If the client is registered we need to check his application type, so if it was “JavaScript – Non Confidential” client we’ll not check or ask for the secret. If it is Native – Confidential app then the client secret is mandatory and it will be validated against the secret stored in the database.

Then we’ll check if the client is active, if it is not the case then we’ll invalidate the request.

Lastly we need to store the client allowed origin and refresh token life time value on the Owin context so it will be available once we generate the refresh token and set its expiry life time.

If all is valid we mark the context as valid context which means that client check has passed and the code flow can proceed to the next step.

Step 4: Validating the Resource Owner Credentials

Now we need to modify the method “GrantResourceOwnerCredentials” to validate that resource owner username/password is correct and bound the client id to the access token generated, so open file “SimpleAuthorizationServerProvider” and paste the code below:

By looking at the code above you will notice that we are doing the following:

Reading the allowed origin value for this client from the Owin context, then we use this value to add the header “Access-Control-Allow-Origin” to Owin context response, by doing this and for any JavaScript application we’ll prevent using the same client id to build another JavaScript application hosted on another domain; because the origin for all requests coming from this app will be from a different domain and the back-end API will return 405 status.

We’ll check the username/password for the resource owner if it is valid, and if this is the case we’ll generate set of claims for this user along with authentication properties which contains the client id and userName, those properties are needed for the next steps.

Now the access token will be generated behind the scenes when we call “context.Validated(ticket)”

Step 5: Generating the Refresh Token and Persisting it

Now we need to generate the Refresh Token and Store it in our database inside the table “RefreshTokens”, to do the following we need to add new class named “SimpleRefreshTokenProvider” under folder “Providers” which implements the interface “IAuthenticationTokenProvider”, so add the class and paste the code below:

As you notice this class implements the interface “IAuthenticationTokenProvider” so we need to add our refresh token generation logic inside method “CreateAsync”, and by looking at the code above we can notice the below:

We are generating a unique identifier for the refresh token, I’m using Guid here which is enough for this or you can use your own unique string generation algorithm.

Then we are reading the refresh token life time value from the Owin context where we set this value once we validate the client, this value will be used to determine how long the refresh token will be valid for, this should be in minutes.

Then we are setting the IssuedUtc, and ExpiresUtc values for the ticket, setting those properties will determine how long the refresh token will be valid for.

After setting all context properties we are calling method “context.SerializeTicket();” which will be responsible to serialize the ticket content and we’ll be able to store this magical serialized string on the database.

After this we are building a token record which will be saved in RefreshTokens table, note that I’m checking that the token which will be saved on the database is unique for this Subject (User) and the Client, if it not unique I’ll delete the existing one and store new refresh token. It is better to hash the refresh token identifier before storing it, so if anyone has access to the database he’ll not see the real refresh tokens.

Lastly we will send back the refresh token id (without hashing it) in the response body.

The “SimpleRefreshTokenProvider” class should be set along with the “OAuthAuthorizationServerOptions”, so open class “Startup” and replace the code used to set “OAuthAuthorizationServerOptions” in method “ConfigureOAuth” with the code below, notice that we are setting the access token life time to a short period now (30 minutes) instead of 24 hours.

Once this is done we we can now test obtaining refresh token and storing it in the database, to do so open your favorite REST client and I’ll use PostMan to compose the POST request against the endpoint http://ngauthenticationapi.azurewebsites.net/token the request will be as the image below:

What worth mentioning here that we are setting the client_id parameter in the request body, and once the “/token” end point receives this request it will go through all the validation we’ve implemented in method “ValidateClientAuthentication”, you can check how the validation will take place if we set the client_id to “consoleApp” and how the client_secret is mandatory and should be provided with this request because the application type for this client is “Native-Confidential”.

As well by looking at the response body you will notice that we’ve obtained a “refresh_token” which should be used to obtain new access token (we’ll see this later in this post) this token is bounded to user “Razan” and for Client “ngAuthApp”. Note that the “expires_in” value is related to the access token not the refresh token, this access token will expires in 30 mins.

Step 6: Generating an Access Token using the Refresh Token

Now we need to implement the logic needed once we receive the refresh token so we can generate a new access token, to do so open class “SimpleRefreshTokenProvider” and implement the code below in method “ReceiveAsync”:

We need to set the “Access-Control-Allow-Origin” header by getting the value from Owin Context, I’ve spent more than 1 hour figuring out why my requests to issue access token using a refresh token returns 405 status code and it turned out that we need to set this header in this method because the method “GrantResourceOwnerCredentials” where we set this header is never get executed once we request access token using refresh tokens (grant_type=refresh_token).

We get the refresh token id from the request, then hash this id and look for this token using the hashed refresh token id in table “RefreshTokens”, if the refresh token is found, we will use the magical signed string which contains a serialized representation for the ticket to build the ticket and identities for the user mapped to this refresh token.

We’ll remove the existing refresh token from tables “RefreshTokens” because in our logic we are allowing only one refresh token per user and client.

Now the request context contains all the claims stored previously for this user, we need to add logic which allows us to issue new claims or updating existing claims and contain them into the new access token generated before sending it to the user, to do so open class “SimpleAuthorizationServerProvider” and implement method “GrantRefreshToken” using the code below:

What we’ve implement above is simple and can be explained in the points below:

We are reading the client id value from the original ticket, this is the client id which get stored in the magical signed string, then we compare this client id against the client id sent with the request, if they are different we’ll reject this request because we need to make sure that the refresh token used here is bound to the same client when it was generated.

We have the chance now to add new claims or remove existing claims, this was not achievable without refresh tokens, then we call “context.Validated(newTicket)” which will generate new access token and return it in the response body.

Lastly after this method executes successfully, the flow for the code will hit method “CreateAsync” in class “SimpleRefreshTokenProvider” and a new refresh token is generated and returned in the response along with the new access token.

Notice how we set the “grant_type” to “refresh_token” and passed the “refresh_token” value and client id with the request, if all went successfully we’ll receive a new access token and refresh token.

Step 7: Revoking Refresh Tokens

The idea here is simple, all you need to do is to delete the refresh token record from table “RefreshTokens” and once the user tries to request new access token using the deleted refresh token it will fail and he needs to authenticate again using his username/password in order to obtain new access token and refresh token. By having this feature your system admin can have control on how to revoke access from logged in users.

To do this we need to add new controller named “RefreshTokensController” under folder “Controllers” and paste the code below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

[RoutePrefix("api/RefreshTokens")]

publicclassRefreshTokensController:ApiController

{

privateAuthRepository _repo=null;

publicRefreshTokensController()

{

_repo=newAuthRepository();

}

[Authorize(Users="Admin")]

[Route("")]

publicIHttpActionResult Get()

{

returnOk(_repo.GetAllRefreshTokens());

}

//[Authorize(Users = "Admin")]

[AllowAnonymous]

[Route("")]

publicasyncTask<IHttpActionResult>Delete(stringtokenId)

{

varresult=await_repo.RemoveRefreshToken(tokenId);

if(result)

{

returnOk();

}

returnBadRequest("Token Id does not exist");

}

protectedoverridevoidDispose(booldisposing)

{

if(disposing)

{

_repo.Dispose();

}

base.Dispose(disposing);

}

}

Nothing special implemented here, we only have 2 actions which lists all the stored refresh tokens on the database, and another method which accepts a query string named “tokeId”, this should contains the hashed value of the refresh token, this method will be used to delete/revoke refresh tokens.

For the sake of the demo, I’ve authorized only user named “Admin” to execute the “Get” method and obtain all refresh tokens, as well I’ve allowed anonymous access for the “Delete” method so you can try to revoke your own refresh tokens, on production you need to secure this end point.

To hash your refresh tokens you have to use the helper class below, so add new class named “Helper” and paste the code below:

Once the refresh token has been removed, if the user tries to use it he will fail obtaining new access token until he authenticate again using username/password.

Step 8: Updating the front-end AngularJS Application

I’ve updated the live front-end application to support using refresh tokens along with Resource Owner Password Credentials flow, so once you log in, and if you want to user refresh tokens you need to check the check box “Use Refresh Tokens” as the image below:

One you log in successfully, you will find new tab named “Refresh Tokens” on the top right corner, this tab will provide you with a view which allows you to obtain a new access token using the refresh token you obtained on log in, the view will look as the image below:

Update (11-08-2014) Thanks to Nikolaj for forking the repo and add support for seamless refresh token requests, you can check it here.

Lastly I’ve added new view named “/tokens” which is accessible only by username “Admin”. This view will list all available refresh tokens along with refresh token issue and expiry date. This view will allow the admin only to revoke a refresh tokens, the view will look as the below image:

I will write another post which shows how I’ve implemented this in the AngularJS application, for now you can check the code on my GitHub repo.

Conclusion

Security is really hard! You need to think about all the ins and outs, this post turned out to be too long and took way longer to compile and write than I expected, but hopefully it will be useful for anyone looking to implement refresh tokens. I would like to hear your feedback and comments if there is something missing or there is something we can enhance on this post.

Comments

I would recommend taking a look at Taiseer’s source for his Angular front end. Essentially though what you want to do is detect that your normal post to your server has returned a 401 and if you have a refresh token stored then call the API to re-authenticate using the refresh token. As a user, you shouldn’t really notice any difference apart from now having to re-enter your username / password each time your token expires.

To help with this I have just used the following interceptor module which detects this, allows you to re-authenticate and then continues with the requests.

This is a great resource, it has helped me out immensely. I do have an issue now though, I have tried to implement the GrantRefreshToken but it never get’s invoked. My ValidateClientAuthentication method is slightly different to yours because it is async and instead of return Task.FromResult(null); I use return; (like in GrantResourceOwnerCredentials). But when I try to use the refresh_token to authenticate I get an invalid_grant error message.
I have posted my problem on stackoverflow: http://stackoverflow.com/questions/38992799/grant-type-refresh-token-invalid-grant

I believe the problem is caused by the expiration time of the refresh token. In the original code by Taiseer, the expiration is set to 0 by default (or simply never changed). You have to update this in your own configuration file. Once you update it with a correct time value (aka >0), it should work. That solved the problem for me. Hope it works for you as well.

Expired refresh tokens are not handled here. You are able to generate new tokens from an expired one. Thats an security issue.
Code helps to understand behavior and flow. BUT the most important, you are in the middle of an infinite loop( refresh-token based)

In a SPA you can think or remember me option as creating a refresh token and store it securely in a HTTP cookie so you can use it to obtain new access token when it expires and the user stays logged in.

I am trying to implement refresh tokens in WebApi but am facing problem in Step 2. – I implemented the simple token based authentication without much change in code that is available in asp.net’s basic template.

Now, in step 2 it mentions “AuthRepository” file. I haven’t implemented such a file. Stuck here, really appreciate if you help. Thanks

Hello Shyamal,
The AuthRepository is a class used to encapsulate all the methods needed to access the database, you need just to add the file and paste the code as instructed. Here is the complete implementation of this class.
Hope this helps!

First of all thank you much for providing OAuth in such details. It is working as expected only thing that I would like to ask is, When I try to get access_token using refresh_token, refresh_token also changes. Is there any way to restrict It. I mean I would get access_token without changing refresh_token and once refresh token expires user need to login again with actual credentials.

Hi Joytish,
Yes you can do this, but once the refresh token change, you will benefit from the sliding expiration feature so yo can keep the user signed in as long as he keeps using the app. If you do not want this feature you need to change the code which delete then insert new token with each refresh_token grant.

In the beginning of your article you talked about the “self contained tokens” and that it would be “nice” that one could update the “contained data” if (for example) the user role changed from “user” to “admin”. Therefore you pass an access_token with a short expiration date and a refresh_token with a long expiration date.

I implemented your approach in my server, but the “GrantResourceOwnerCredentials”-Method only got called when I first create the access_token (empty grant_type in the request). When I access the token endpoint with grant_type == refresh_token and pass the refresh_token the “GrantResourceOwnerCredentials”-Method doesn’t get called. Therefore the AccessToken has the same information like in the first request (because of the line “context.DeserializeTicket(refreshToken.ProtectedTicket)”).

Thanks for your comment. Well, the “GrantResourceOwnerCrdentials” will be called only once when you set the “grant_type” to “Password”. The method “GrantRefreshToken” will be called when you set the grant type to “refresh_token” and you will have the chance to update the access token and set new claim inside it.
Hope this answers your question.

Just a little more detail on Taiseer’s response:
Taiseer’s example uses a copy-constructor to create a new identity. This copy still has all of the original roles.

var newIdentity = new ClaimsIdentity(context.Ticket.Identity);

On the next line after the copy-ctor he shows how you can add a new role to that list. Instead of adding a new role you need to remove all the old roles and repopulate with the current roles. Or you can rebuild the ClaimsIdentity like you did in the GrantResourceOwnerCredentials” method.

Good evening. Could you tell me, please, when do we have to add Clients to DB and how to do that correctly? It seems, like it is not done in the code, shown at this post and it does not work without that. Thank you.

Your assumption is correct, please read the paragraph titled “Refresh Tokens and Clients” to get a better understanding of the relation between OAuth clients and refresh tokens. The clients are added in the code, check how they added here.

Thank you very much for your answer and for such a great tutorial. Could you, please, answer one more question?

Is it ok, when an unauthorized user tries to view orders page (by entering /#/orders path), he getts the static context of orders.html for a second and only after that getts redirected to the logIn page? I have the same problem both with orders page and with logout button when pressing f5.

Could you please share the database scripts or tables used in this complete article? I’m trying to create some table but that doesn’t help me to develop Web API part.
As this is database first approach so I don’t want to create and imaginary database.

I’m had a problem when a put the application in a host with load balance, when i’m trying to refresh the token and my request go into a server that is not the same who gave to me the access-key, it returns to me “invalid grant”, only works if the load-balance gives to me the same server. Did you know how solve this?

I am getting this error
{
“error”: “invalid_clientId”,
“error_description”: “Client secret should be sent.”
}
when I tried running the app for the first time after all this code and supplied these values
grant_type password
username Taiseer
password SuperPass
client_id ngAuthApp

and what values should be there in the Clients and RefreshToken table in the database.

Great Article! However I had a question. You are using Local Storage to store the credentials which will remain there until the user logs out. I need to implement Remember Me feature which means will user will be logged out if he has not selected “Remember me” and will remain logged in as long “Remember me” is enabled. Since your implementation does not use cookies, how can this be done ?

I think you have already answered my question here “In a SPA you can think or remember me option as creating a refresh token and store it securely in a HTTP cookie so I you can use it to obtain new access token when it expires and the user stays logged in.”
If we store refresh token in cookie along with local storage, how will we sync between the two when the cookie expires ? Can you elaborate on this ?

First of all great article !! I need to make make a small change in the implementation like I need to extent expiration of the token if the request is within the expiration window. Which mean If I have generated my token for 15 minutes and my request is going on the 10th minute, I want to extent it to another 15 minutes (without changing the token if possible) from the last request has been made.

Now if I keep application idle for some time and then try to access the Orders Controller, the authorize check passes but the claims object is null which causes an exception. I also found out that none of Refresh token provider or Authorization Server provider methods are being called. Please help me.

What’s the purpose of the “Client Secret” on anything other than the Auth Server? Wouldn’t the Client ID be enough for the server to know who is asking for Access/Refresh Tokens, as well as knowing what that client’s secret is to properly sign tokens? I always though a shared secret was only needed by a client if it were signing it’s own requests/tokens/etc, which to me does not seem to be the case with JWTs where clients only reuse valid tokens that have already been signed by the Auth Server when making requests.

Ok, another question. Assume we use this whole mechanism for a mobile app. What happens if a user owns two different devices? When he logs in at the second device, the refresh_token of the first gets invalidated. So, when the first client tries to refresh the access token using this invalid refresh_token, he gets “invalid grant”. Any ideas how to overcome this?

One thing that always confuses me is the client secret value. Is that basically how a password functions for users, but only for authorized clients/applications? How can it be valuable if it can be both required (Confidential Apps) and not required (Javascript Apps) when authorizing?

Hello Geo,
You should not use the client secret on non-confidential client, you just use the client Id, to identify the client for the server and obtain redirect URIs, scopes etc, from the redirect URI the agent (web browser) will redirect the resource owner (user) to a page hosted at the AuthZ server where he will provide username and password to authenticate him.
I hope this answers your concern.

Great article, best resource I found. Question, is it a better approach to keep clientAuth table for login and clientProfile table separated or as the same table? This is something I found missing in the article.

For me, keeping separated sounds better as I can separate auth from the rest of the application. However, that also means paying for two tables (instead of one) and having duplicated fields that will need sync.

In my case, client can log through phone number or facebook/google, so I would need that on client auth to confirm during login (e.g. phone, fbId, googId). After login, you can call “/me” to get full profile at any point. If we separate that would mean that phone number update would need to update auth and profile, for example.

I am still wondering why to use access tokens.
Can we achieve the same functionality if we set the access token for short time, let’s say 30 min?
If we do this, does it mean user needs to enter his credentials again and login, therefore gets a new access token, so there is no need for access token.

I am still on the fance what the way of calculating this 30 mins is? Does it count in the background user inactivity or it starts from user’s login. If the answer is the second option, does it mean user will be redirected to the login page during his activity on the page?

mehmedju
Refresh token is useful for sibling time, meaning the period of time when the user is inactive. If you dont use refresh token, the original access_token is valid and it is considered an security issue handle long-live access-token.
On the other hand, you are right. If access_token is expired, you ought to redirect to login page to re-enter credentials and so on.
By using refresh-tokens, this happens behind the scenes.

By the way: When updating my local angular client by copy-pasting some code from Github, I noticed a small bug in the auth service. You only send the clientId if refresh tokens are used. But in my undertanding the clientId is always needed for authentication.

Hello Taiseer,
I need to void access to the resource service if the client does not take action for a reasonable amount of time. I think I should void the refresh token when the resource service rejects the access token because it has expired, would this be so ?

Hello Dante,
You are correct, You have to send the expired access token to the resource server to get validated, you will get 401, then you will try to obtain a new access token using the stored refresh token, if it expired too then you will get another 401 and you are ready to prompt the user to provide his/her username/password again. Now If you do not want to send the expired access token you need to set some sort of timer at the client and base your checking on it, I do not recommend this approach unless there is a real need for this.

Great post, helped me a lot.
When I request a new access token via the grant_type refresh_token, where sits the code to check if the refresh token is validated and checked if the refresh token has not been expired?

I followed your tutos and it works like a charm! And most important thing is that I’ve understood everything!

Altough, I have a question:
I have such case :
User is logged in and is working on the app.
Access token has expired, so the next query will failed and the refresh token will re-authenticate the user.
Great, but is there a way which allows to automatically re-execute the last query which has failed?

I see one way but which is really bad : send a “ping” query before every query and the real query only in the callback.

Otherwise I would inform the user that his session has been extended, but I find that having such message every hour for example is not so nice too.

Hello Pat, thanks for your message, well what you are trying to achieve is to silently refresh your access token using the refresh token, and I think you can do this using different approaches:
1- When receiving 401, you need manually fire the refresh token flow and obtain a new access token, you can re-execute your original request using the new access token, if you are not using Angular this link will give you a hint
2- Using the library “oidc-client” which uses a hidden iframe to do this.

I followed these three posts and seems great approach. The only concern I have right now is, If the user log in using browser1 and then the same user log in again using browser2, The first refresh token generated and stored in database and browser1 will be deleted from database once the same user log in using browser2. As a result, in the browser1 user will not be able to get new access token using its refresh token. Since it has been deleted from database.

You need to use one of the libraries which allow you to decode JWT contents in client side, this is an example (https://github.com/auth0/jwt-decode) Refresh tokens will never store any claim in, it is only a reference for an actual token/claims in your DB.

I have a working Auth Server with JWT tokens. I used another walkthrough. “ASP.NET Identity 2.1 with ASP.NET Web API 2.2.”

In this walkthrough, “Token Based Authentication using ASP.NET Web API 2, Owin, and Identity.” I do not know how to decode the access token.

I have been tasked with adding Refresh Token to my existing Auth Server. In this walk through, the access_token is not a JWT. Or at least doesn’t appear to be. There are no periods in it. How to I decode it? As seen here.

to
var allowedOrigin = context.OwinContext.Get(“as:clientAllowedOrigin”);
if (allowedOrigin == null)
{
allowedOrigin = “*”;
context.OwinContext.Response.Headers.Add(“Access-Control-Allow-Origin”, new[] { allowedOrigin });
}
Reason to avoid double origin entry in header. In case of double entry the cors preflight request will fail.
Why this code worked for you before – in your example you call app.UseCors after ConfigureOAuth(app)
The order affect this, if the entry is present in a header UserCors will not add it again, but in other order your code will fail always.

Based on the tutorial I built I didn’t use refresh tokens with external identities, it doesn’t make sense to do this when you are logged in to your FB account. Assume that you have changed your FB credentials, then if you are using refresh tokens you will remain logged in while your FB account is not valid. That was my concern when writing this tutorial and thinking of refresh tokens with external accounts.

I have two questions:
1) What values are stored within the AccessTokens?
Are these the value of the context.Ticket?
Which are serialized via context.SerializeTicket and deserialized via context.DeserializeTicket?

2) The diffierent lifetimes of the
a) RefreshToken and
b) AccessToken.

Following your code, I see only one place where a time value is getting updated: That is within SimpleRefreshTokenProvider.CreateAsync, and if I get it right, that ist the lifetime of the AccessToken, not the RefeshToken. I miss somehow where the different lifetimes gets created.

The „as:clientRefreshTokenLifeTime“ value is set during the ValidateClientAuthentication. That value is used within SimpleRefreshTokenProvider.CreateAsync to update „a Token“.

My understandig of your code is:

a) Within SimpleRefreshTokenProvider.CreateAsync you create the AccessToken via the context.Ticket properties and set the refresh token (a simple value without any contained lifetime values) via context.SetToken.
So the client get the AccessToken and RefreshToken. The AccessToken gets stored as ProtectedTicket.

b) Within Step 6: The old AccessToken gets loaded via the RefreshToken and that gets updated via the next call to CreateAsync.
So basically the AccessToken gets stored, read and updated. The RefreshToken is a simple identify to the old AccessToken value and gets created everytime within the SimpleRefreshTokenProvider.CreateAsync.

I get it. The AuthoToken lifetime is defined within the OAuthAuthorizationServerOptions.

During “SimpleRefreshTokenProvider.CreateAsync” the lifetime gets update and you store a snapshot of the current Ticket. The AuthToken is liftime get generated later (not handled within the code) by OWIN based on the OAuthAuthorizationServerOptions.AccessTokenExpireTimeSpan.

I have a subset of users who want to login with credentials from another system in our organization. I can verify their username/password with this system but it is not OAuth-compatible so I need to generate tokens manually. I have access token generation working fine from previous comments, but I cannot figure out how to generate a refresh token in the controller.

This is nice article for newer ones like me who wants to implement token based authentication. I implement the same in my application. I have a question on validating access_token in my other requests after login. How can i validate this access token in my other request to check its validation or its tempure or not. I am not using any jwt or custom token. I am using default access_token.

After implemented refresh token functionality I am trying to make my webAPI SSL enabled and that is causing some issues. Thought to run it by you and see if you have any suggestions.

I enabled SSL for webAPI project using properties window and got a HTTPS url (I am running the application from VS 2017 in debug mode). Also set the value AllowInsecureHttp = false.

But when I call the webAPI using HTTPS url from angularJS client, within “SimpleAuthorizationServerProvider.ValidateClientAuthentication” function, the values for both “clientId” and “clientSecret” are always null. If I disable the SSL, everything works fine.

Any suggestions why following line of code is not working when SSL is enabled:
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}

I really like this post. Helped me a lot with my app. I have tried to signout the user using the Request.GetOwinContext().Authentication.SignOut() method, bu this does not seem to work.
Could you shed some light??

Hi Taiseer,
Great article regarding refresh token implementation. Worked without any issues in local environment but whenever moved to load balanced servers, we are getting few issues. Please check them below.

1. We are frequently getting this issue “System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions. —> System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions” after which refresh token part is not at all working

2. System.Data.Entity.Core.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. —> System.InvalidOperationException: SqlConnection does not support parallel transactions.

Also, we are getting few more errors related to storage of refresh tokens in db part. Please suggest how to overcome these type of issues. If in worst case, is it really needed to store refresh tokens in a db table? Instead of sending refresh token as guid, I tried sending protected ticket in encrypted format in the token response and decrypted the protected ticket during grant_type=refresh_token. Is it feasible so that we can avoid above type of errors. Please suggest.

Hi! Great arcticle! I have a question regarding the method ReceiveAsync. You coded the search simply by looking at the token id. Would it have any added value to search the token by id “AND” by clientId just in case someone is trying values at the refresh token endpoint?

Just a small error in the AddRefreshToken method: on the line where you remove the potential existing token, should be : RemoveRefreshToken(existingToken.Id) instead of RemoveRefreshToken(existingToken)

Thanks for your great tutorial, i followed from the part, and then i just using my database and tables have been created automatically, When i run the application, always i getting client_id is null. please help me. i don’t what i need to do. Do i have to database tables. when i signup user created after login in i facing client_id null.