Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I force OAuth2 access token expiration with DotNetOpenAuth

I'm implementing OAuth2 authorization/resource server based on DotNetOpenAuth. My server is going to issue access tokens with very long life time. These tokens are going to be used from iOS devices. The flow, the way I see it, is like this, 1) a user is asked to enter their username/password on iOS device 2) an access token is requested with grant type of Resource Owner Password credentials 3) token is granted and stored on the iOS device for future use.

Now from time to time users get disabled. I would like to revoke the token at the same time. How do I do this? I suspect that I need to use ICryptoKeyStore.RemoveKey method for that, but not sure how to find which key to remove.

Note 1: in future the server will be used by third party web applications.

Note 2: the requirement to have grant type of Resource Owner Password credentials stems from the fact that it was decided that implementing browser redirection on iOS device is not worth the time.

Update 1 Some excavations in the source code suggest that DotNetOpenAuth does not support this ability to force token expiration out of the box. Moreover in the standard implementation lifetime of the token is not even checked. As far as I can see the calss is responsible for this is StandardAccessTokenAnalyzer and it ignores the Lifetime and UtcCreationDate properties. Also it does not seem that the standard ResourceServer class has any database access coded, the token validity checked by the token content only, so it seems that if I need to add ability to expire the tokens I need to wire up the ResourseServer to database myself. Am I missing something?

Update 2 I think I found the answer here: https://groups.google.com/forum/#!topic/dotnetopenid/aLabu1ujkt4 It's not what I was hoping for and I still have a few unclarities. For example, Andrew wrote:

Your custom class then could take an access token, then use a private HTTP request to the authorization server to verify the continued validity of the token.

It is unclear how this verification can happen, given that AccessToken does not include Authorization Id. This can make finding the target Authorization record difficult. In theory we can try to look it up by combination of client, user and issue time, but as far as I can see there are no guarantee that these will be unique.

like image 263
Andrew Savinykh Avatar asked May 01 '12 08:05

Andrew Savinykh


People also ask

How do I make my access token expire?

You can change the access token lifetime using the Auth0 Dashboard . Go to Dashboard > Applications > APIs and click the name of the API to view. Locate the Token Expiration (Seconds) field, and enter the appropriate access token lifetime (in seconds) for the API. Default value is 86,400 seconds (24 hours).

How do I know if my oauth2 access token is expired?

The OAuth 2.0 standard, RFC 6749, defines the expires_in field as the number of seconds to expiration: expires_in: RECOMMENDED. The lifetime in seconds of the access token. For example, the value "3600" denotes that the access token will expire in one hour from the time the response was generated.


1 Answers

Now from time to time users get disabled. I would like to revoke the token at the same time. How do I do this? I suspect that I need to use ICryptoKeyStore.RemoveKey method for that, but not sure how to find which key to remove.

You revoke tokens by revoking the authorization behind the token. This typically means you delete an entry in the authorizations table of your database. The effect this must have is that your implementation of IAuthorizationServerHost.IsAuthorizationValid will return false for this authorization.

This doesn't immediately revoke access tokens, but it blocks the client from refreshing expired access tokens. So as long as your access tokens have a reasonably short lifetime (an hour or less) then a user's disabled account means that all client access will terminate within an hour.

Note 2: the requirement to have grant type of Resource Owner Password credentials stems from the fact that it was decided that implementing browser redirection on iOS device is not worth the time.

It's your app. But I urge everyone to use the proper browser redirect flow. The user is likely already logged into your server on the device's browser so they can possibly avoid entering their credentials altogether this way, improving your conversion rates. Users are also more likely to trust the browser asking for their credentials than a device app. At least I hope so.

By the way, the resource owner password grant type is likely to not be supported for non-authenticating clients (TBD), which installed device apps will typically be. So you may be forced into using a different grant type.

Update 1 Some excavations in the source code suggest that DotNetOpenAuth does not support this ability to force token expiration out of the box. Moreover in the standard implementation lifetime of the token is not even checked. As far as I can see the calss is responsible for this is StandardAccessTokenAnalyzer and it ignores the Lifetime and UtcCreationDate properties.

DotNetOpenAuth does check for and reject expired access tokens. It's just not in that class. It's checked in the code that deserializes access tokens.

Also it does not seem that the standard ResourceServer class has any database access coded, the token validity checked by the token content only, so it seems that if I need to add ability to expire the tokens I need to wire up the ResourseServer to database myself. Am I missing something?

You are correct that the ResourceServer class does not require any database access, because access tokens are assumed valid for their entire lifetime (they're non-revokable by default). This is why short access token lifetimes are recommended. This isn't as far-out as you might think. For example, ASP.NET forms authentication, which you very likely use already, is based on the same pattern: authenticate the user once, hit the database for a credential check, then issue an encrypted and signed HTTP cookie to the user agent. From that point on, the database isn't hit on every incoming HTTP request -- the cookie signature is validated and then assumed to be valid until the cookie expires. Same principle. Except that in the HTTP cookie case, there's a sliding timeout, so that as long as the user remains active on the site, they never have to reauthenticate. With OAuth 2 access tokens, they expire regardless of how actively they're used, forcing a token refresh which can then be rejected to lock out access.

It is unclear how this verification can happen, given that AccessToken does not include Authorization Id. This can make finding the target Authorization record difficult. In theory we can try to look it up by combination of client, user and issue time, but as far as I can see there are no guarantee that these will be unique.

It's true no ID is included, but the tuple of client-user-issuedate-scope should be unique, as your authorization table should have a unique constraint on it since having duplicates wouldn't make sense. Besides, if they weren't unique, just the presence of any record with that tuple suggests the authorization is valid.

Hope this helps.

like image 153
Andrew Arnott Avatar answered Oct 15 '22 23:10

Andrew Arnott