4
votes

Can't find any guidelines about the best way to implement persistence of OAuth 2 refresh tokens and any common opinion about what actually should be stored and how.

Though there is a very good totorial by Taiseer Joudeh about OAuth authorization in ASP.NET Web API. This is RefreshTokens table from the article:

enter image description here

where: Id - hash of unique token identifier, Subject - user name, ClientId - applicatation identifier, ProtectedTicket - serialized access token.

I would like to prove or subvert some decisions made there with the help of SO community. So here are my concerns:

  1. Why should we persist short-lived access_token? So far I can think of a two reasons agains this approach. First, potentially it could be a security threat when you are keeping user's access tickes anywhere, just waiting for someone to grab them, and reuse for unsuspicious resource server (remember, they should use the same algorithm to serilize/deserialize keys). Second, you would have to care about updating those persisted tickets once you decide to change any part of serialization algorithm. So, why don't we simply create new tickets in runtime once we've verified client_id and refresh_token instead of reading and deserializing it from database?

  2. How access_token should be encrypted, if we should persist it? Will salt + SHA2 on serialized ticket do the job or there is a better way?

  3. Why hash refresh_token id? From what kinds of attacks it actually protects? And won't it be more secure if we'd send hashed keys as refresh_token while keeping real key in the database? This way brute-force attack on the refresh_token (guessing refresh token of a random user) would have to guess hashing algorithm as well.

1

1 Answers

2
votes

I will try to clarify those points more:

1 & 2 - If you look on the source code for context.SerializeTicket here you will notice that this protected ticket is encrypted using the default DPAPI which depends on server machineKey for encryption. So if you grab it from DB you can't do anything with it unless you have the machineKey.

3 - If your DBA has access to this table and he can see the the plain refresh token identifiers then he can simple obtain new access token using those refresh token identifier using the grant_type (refresh_token)