Maintaining Box refresh / access tokens in a disrtibuted system - box-api

We have multiple servers that access Box, so we turn off auto-refresh.
connect.setMaxRequestAttempts(1);
connect.setAutoRefresh(false);
Assumptions gathered from unit tests:
Previous access tokens < 1hr old can still be used for access
A token
pair can be refreshed multiple times, as long as a newer token pair
has not been used for access.
Given that, it appears you can have multiple readers with one writer updating the token pair, even if a reader gets the previous token pair, it should be fine (for access).
We ensure that only one thread in the system updates the tokens, but yet are having issues with 401 errors in spite of locking down the token updates. It seems there something wrong with the assumptions above.

Your assumptions are close. Here is the expected behavior:
A token is valid for one hour, unless a new token is requested and
used.
If a new token is requested but not used, the old token is
still valid (assuming it less than one hour old).
If a new token is requested and used, the old token is
invalidated.

Related

Invalidating JWTs on Permissions

Do people typically store permissions in a JWT? I've seen example that might have admin: true or scopes: ['add_foo', 'delete_foo', 'read_foo']. And this seems fine, other that the potentially large size that the JWT could become if there are a lot of permissions/scopes. It seems like it would be really useful as you wouldn't need to hit a DB or cache to get the users permissions as long as the JWT can be verified.
My main question though is how these would be invalidated in the event of a permissions change.
For example, sys admin Joe, revokes the 'add_foo' and 'delete_foo' permissions from user Bob, but keeps the 'read_foo' permission. In this scenario user Bob should not have his token entirely invalidated and need to log back in, he should basically be forced to get a new JWT with the new permissions and carry on as normal.
I've seen examples explaining issuing a new JWT in the event of a password change, but the difference here is that sys admin Joe does the update to user Bob. Thus, there is no opportunity in this workflow for user Bob to get the new token immediately.
Most examples suggest for invalidation maintaining a black list of revoked tokens, or changing a DB record ID so the token is no longer valid, or having a per-user secret and changing that.
I see that all of these would work for the revoking of the token and test that its invalid, but how does the user then get a new token? their current JWT is now invalid? Trying to do anything with it should fail.
I've seen mention of a "refresh token". Are these widely use? Are they secure on the web or mainly used for mobile apps where the refresh token is harder to obtain. It seems like it would be reasonably easy to steal a refresh token via browser dev tools or similar and then someone would have access forever to that account until the unauthorized access was noticed and the refresh token revoked.
Maybe in this scenario forcing user Bob to re-authenticate is not such a big deal? Permissions probably don't change too often.
Thanks, Mike.
You can set expiration date (for Web app we are usually using 15 min - 30 min, for mobile 1 week). When you set Issued at claims parameter ("iat"). Then every time when you validate token you should check the token's "age". If it older than 5 min you load data from DB and create new token with current "iat" value.
When permissions change you should invalidate the issued tokens for this user. There are different techniques to use. See Invalidating client side JWT session
But consider that revoking tokens is not a recommended practice because you lose one of the main advantages of JWT: It does not require server storage.
The objective of Refresh tokens, as defined in Oauth2.0, is allow applications to obtain a new access token without re-authenticate
Refresh tokens are credentials used to obtain access tokens. Refresh tokens are issued to the client by the authorization server and are used to obtain a new access token when the current access token becomes invalid or expires,
If the permissions do not change frequently it may be easier to re-authenticate user, and if they change much consider whether they really should be included in the token

What is ErrorMessagePerFolderCountReceiveQuotaExceeded?

I'm synchronizing Office 365 mail folders via the Office 365 REST API by doing a GET on me/MailFolders/{folder_id}/messages. For two different accounts, I've recently been getting 500 responses to these GETs with the error code ErrorMessagePerFolderCountReceiveQuotaExceeded and error message "The number of received messages has exeeded the quota for the folder." (Typo theirs, not mine.)
I can't find any documentation on this error. What does it mean? What should I do to fix this situation?
I couldn't seem to find any documentation for it either.
From the error message, it seems it might be related to the "Maximum number of messages per mailbox folder" limit on Exchange Online. Do you know if the folder contains 1M+ messages?
https://technet.microsoft.com/en-us/library/exchange-online-limits.aspx#MailboxFolderLimits
I guess my other idea would be that you're getting too many messages in too short of a time period. Suggestion would be to use the endpoint GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages with $deltaToken and $skipToken to skip previously synced messages.
https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations#synchronize-messages
When you do a sync to an Exchange folder via the Outlook REST API, you pass it a sync token. In response, the API returns a new sync token and a set of changes. And the client is expected to send the new token back with their next sync request.
With most systems that support sync, using a stale sync token (i.e. one that has been sent to the server once) in a subsequent request will generally just succeed with no problems. And Exchange appears to work like that... for the first 999,999 times you do it. On the 1,000,000th time (and each time thereafter), you get ErrorMessagePerFolderCountReceiveQuotaExceeded. This is (I think) because Exchange keeps track of each token that it's given out and updates the token in its store each time it's used for sync. If a client uses a stale token, Exchange views it as a new client and adds that stale token as a new entry in its list of active tokens. That active token list can have at most 1,000,000 entries. ErrorMessagePerFolderCountReceiveQuotaExceeded is the cryptic error indicating that Exchange's active token list has overflowed.

Outdated information in jwt token payload

As written in jwt.io "The payload contains any arbitrary information in the form of claims that we as developers find useful for our applications.". So i think it would be convenient to put there username, email, and so on. In this case i have no need to get this information from database or file system during authentication process. It is being touted as an advantage if app is distributed across many servers.
But I see here is one annoying obstacle. What if a payload was changed as a result of changing user account information? All old issued tokens stays valid since a signature is still valid. So i'll get wrong user account information from old token payload.
I missed something in idea behind jwt tokens?
There's an optional claim exp for JWTs that specifies the expiry time after which tokens render invalid and should be rejected by the receiver. The idea behind JWT tokens is that you issue them with an exp timestamp that says until when the information in the JWT is valid.
If your user account information changes on a daily basis, the exp should be no longer than 24 hours ahead of the JWTs issuance time. After that timestamp the sender should go out and get a new JWT before sending it to the recipient so the information in the new JWT is fresh.

Refreshing Box API token from multiple servers

We are planning on migrating our Box v1 integration to v2.
Our integration implementation includes API calls accessing user box account and files from different servers at the same time.
With v2, and the introduction of refresh token, we would like to know whether multiple refresh token requests can be made concurrently from multiple servers over the same user account.
Moreover, and as a consequence of multiple refresh calls, we would also like to know whether it is possible to have more than one access key per user at any given time.
Thanks for the help
Assaf
We recommend that you use some sort of coordination between your servers to manage auth tokens and refresh tokens. While a user can have multiple access tokens for the same service, they will have to authenticate multiple times in order to get them. You can't mint extra auth tokens off a single auth-token/refresh-token pair.
Here's what we recommend.
Create a pair of encrypted columns in your database to store the auth token, the refresh token, a datetime for "token_expires", and a flag for "token_refresh_in_progress". Identify it by userID.
Write your code so that when you are about to make a call, if you are close (say, within a minute) of the token-expires datetime, instead of making your call, you check to see if the refresh-flag has been set, or if there's already a new token pair. If the flag hasn't been by some other server in the cluster, set the flag that you are doing the refresh. Make the refresh-grant call, and update the database with the new pair, and of course reset the flag.

Get non expiring Access Token from Box or Get access token from box by passing UserName and Password.?

I got the Access Token using Box Api but it is expiring in 1 hour.
What I want here is,
Either I need non expiring access token or get the access token by passing my Box User Id and Password to API.
If above things are possible let me know the way.
Thanks in advance..
You've got what is called a Bearer Token and a Refresh Token. The Bearer token is good for an hour, and the Refresh token is good for 60 days. The Refresh token can be traded in for another pair of tokens, which resets both clocks at the time you do the refresh.
Box doesn't have tokens that you can get via a username-password grant in OAuth2, because that inherently doesn't work for enterprise customers that need to do SSO through their ActiveDirectory / Okta / Ping / 2-factor / SecureID signin flows.
What you probably want is an SDK that handles the refreshing of the token for you. Most users won't ever have to logon a second time, unless they go on vacation for a few weeks. Box has already released several SDKs, all on github with open-source licenses. Most of them take care of refreshing the token for you automatically.
We've also added some enhancements recently (early 2014) to help multi-server implementations work more smoothly with the refresh-token flow, including allowing you to use the old refresh token to get the new token multiple times in a narrow time-window. That helps with both multi-threaded environments trying to get new tokens across a number of threads (or servers). It also helps with the case where you have a network interruption and you don't actually get the new token-pair back from your initial refresh call.