I am new to dot net MVC and I am working on a application which required Box integration, in which user authorizes our application using oauth2 authentication flow.
I get the access token and refresh token and save them to my database for further offline access so that user do not have to authenticate the application again.
Now, I am using Box Windows SDK v2 to get list of files and folders of a user.
Here is the code block by which I am able to get the rot folder of box.
var config = new BoxConfig(clientId, clientSecret, new Uri("http://localhost:49671/CloudBox/Callback/"));
//Pls note, here accessToken and refreshToken are fetched from database
OAuthSession session = new OAuthSession(accessToken, refreshToken, 3600, "bearer");
BoxClient client = new BoxClient(config, session);
BoxFolder boxFolder = client.FoldersManager.GetInformationAsync("0").Result;
Everything is fine upto this point.
Now when the access token expires (as it is valid only for 3600 seconds), and I try to get the root folder again, Box SDK refreshes access token and refresh token automatically without telling me. and provides me the root folder object.
At this moment I got the root folder, but I am not aware that Box SDK has updated the access token and refresh tokens. Still I have old access token and refresh token in my database. They are not updated. And I am lost. Now I am left with those old invalidated access token and refresh token.
Pls help. How do I know that Box SDK has updated access token and refresh token ? so that I can update them in my database for future use.
It would be nice, if you can provide a working sample MVC application which stores the access token and refresh token. You can provide the code blocks which needs to be placed in controller. I hope, I will be able to integrate them.
Thanks in advance.
You could use the events triggered by Box.V2 after refreshing the token:
SessionAuthenticated : Fires when a new set of auth token and refresh token pair has been fetched
SessionInvalidated: Fires when the authenticaiton session is invalidated
Related
I'm writing a program that automates some actions with my Gmail account (using Ruby). I generate a callback URL and go to it, which gives me an auth code. Then, I request a refresh token using the auth code.
Now, after the refresh token expires, I was under the impression I can just grab another refresh token using the original auth code. But it seems I keep having to get a new auth code - which is frustrating because I'm hard coding the auth code in my script right now. Is this normal? Am I misunderstanding refresh tokens?
consider code as one-time-password to get a access_token. With access_token you are also getting refresh_token, both have expiration date set - refresh_token is valid for longer time, but if it expires you have to begin whole flow from the very beginning ( getting code )
I have one quick question related to "acquiring a new access token upon expiration". I have read some tutorials where people write code to manually request a new access token.
In my case I wrote an ASP.NET MVC app to access Google APIs, such as Gmail API, and I am using API Client Library for .NET for that.
After OAuth 2.0 authorization I get back the result object of type AuthorizationCodeWebApp.AuthResult.
Where result.Credential.Token contains AccessToken and RefreshToken properties.
I save the refresh token in my web.config the very first time when it comes back (after the consent screen). All next requests dont have a refresh token, only an access token that expires after 1 hour.
So, my question is - before I make a call to instantiate a Gmail Service, I assign previously saved refresh token:
result.Credential.Token.RefreshToken = WebConfigurationManager.AppSettings["RefreshToken"];
var service = new GmailService(
new BaseClientService.Initializer { HttpClientInitializer = credential });
When result.Credential.Token.AccessToken expires, does Gmail API (or any other API Client Library for .NET) acquires a new access token automatically if result.Credential.Token.RefreshToken was assigned a valid refresh token value previously saved, like in my code sample?
Thank you!
UPDATE - More clarification to my question With the same refresh token, how many times I can aquire a new access token when making calls to Google API?
I will explain: access token expires in 1 hour, right.
If I keep making calls with, lets say, 10 minutes intervals to Gmail API (for example), after 6 calls (1 hour limit), Gmail API will use my refresh token to acquire a new access token. After 6 more calls (1 more hour) the whole thing repeats itself. Question - is there a limit to it? Remember, I am not changing my refresh token. Same refresh token is being used to acquire a new access token. And for how long this repetitive calls may continue without any error?
UPDATE AFTER THE TEST
I let my application run on my local machine in Visual Studio DEBUG mode trying to catch any exception, NO Human interaction.
The application kept receiving AJAX calls to Gmail Action with 2 minutes interval, everything was working fine, I went to the gym, came back 2 hours later - oops, Visual Studio debug is open on this Token has been revoked exception, here we go, so it's clear the token was revoked by the Google API service, as you can see from the Debug window. The only question remains - why, since there are no specific details are provided, there is no Inner Exception just that general error message and no reason, but the source is clear - Google API, we can even see it came back from
Google.Apis.Requests.ClientServiceRequest`1.Execute() в
C:\Users\mdril\Documents\GitHub\google-api-dotnet-client\Src\GoogleApis\Apis\Requests\ClientServiceRequest.cs:row
96
I am guessing the service shuts down (revokes a token) after N number of calls, maybe within certain interval. If some one knows the limitations of Google API in terms of number of calls or time intervals between calls, please let me know.
It seems that Matthew Riley, the custodian of Google API on github, coded some logic to revoke a token based on some criteria: https://github.com/google/google-api-dotnet-client
Long response to comment :
One question though: can this be done indefinitely long, unlimited number of times, or I will get an error at some point?
Refresh tokens can be come invalid for the following reasons:
user can revoke it in there google account.
if a refresh token isn't used for 6 months to get a new access token it will expire automatically.
If a user authenticates your application you get a refresh token if they do it again you get a different refresh token. Both will work. you can do this up to 26 times. on the 27 th time the user Authenticates your application the first one you got will expire. You can only have 26 live refresh tokens. (DONT ASK how I know this! "#¤%&)
So assuming you don't reauthentcate your application to many times, use the refresh token at least once every six months. You can use it as many times as you want.
Update for comment:
I think you are still confused. Access tokens expire after 1 hour. Refresh tokens only expire for the above reasons you can use them as many times as you like. To get a new access token.
However you can only have 25 working refresh tokens.
Lets say I have a windows service application that backs up files to a users Google drive account. A user installs it on a server and authenticates it and gets a refresh token. Every night the windows service runs and backs up the files to google drive, it uses the refresh token to get a new access token.
Lets say this user really likes my auto super imba backup service. He installs it on another server. He gets another refresh token and the application goes about its business uploading files at night
Lets say my super user really has a server farm he installs my application on 25 servers. Those applications will be able to get new access tokens forever.
However if this crazy user installs it the 26 th time on a different server getting a new refresh token for this server. The first server they installed it on will stop working because google only allows you to have 25 outstanding refresh tokens for an application.
This is user application based so you can have any number of users each with a max of 25 refresh tokens
I'm using this site https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx to do Authorization Code Grant Flow with the goal of reading my office 365 calendars using this type of flow. The problem is that when I request for an oauth token the response is not updating the "scope" variable. I'm requesting the oauth token using this POST call "https://login.microsoftonline.com/common/oauth2/token" and passing in the body my grant_type, redirect_uri, client_id, client_secret, code, resource. The response is 200OK but for scope it only reads -> "'scope': 'Contacts.Read'" when it should also have Calendars.Read as well. In manage.windowsazure.com for the app that has the same client_id I'm passing in has the read calendars checked as well as the read contacts checked. When I first got my authorization code by typing this into the browser "login.microsoftonline.com/common/oauth2/authorize" I only had "Contacts Read" checked. But now every time I type that into my browser it skips the page where I accept my app to look at my calendars and contacts page. When I login with someone else's computer and get the auth code and request the token it updates their scope to both contacts and calendar and works fine. For me I'm getting a new Auth code in the url but it skips the page where I could accept my app to look at my contacts AND calendars. I'm getting a new authorization each time. I tried clearing my browsing data but It still wouldn't work.
You need the user to logon again so they can consent to the new scope. Try adding prompt=consent to your logon URL.
This works much nicer in the v2 app model, which does dynamic scopes.
We have Azure ACS configured to issue JWT that is valid for 15 minutes. Once the user is logged-in to the web application (MVC), the user will use the token to access resources on another server (WebAPI). The WebAPI server would then validate that token.
So, is there any way to renew the JWT somehow without interrupting user's work on the web app? We don't want to popup a window and ask the user to sign in again.
Thanks!
If you are using Active Directory Authentication Library (ADAL) for .NET, then it includes a token cache. Per this blog post:
One last thing I’d highlight at this point is that every time you get a token from the authority ADAL adds it to a local cache. Every subsequent call to AcquireToken will examine the cache, and if a suitable token is present it will be returned right away. If a suitable token cannot be found, but there is enough information for obtaining a new one without repeating the entire authentication process (as it is the case with OAuth2 refresh tokens) ADAL will do so automatically. The cache is fully queryable and can be disabled or substituted with your own implementation, but if you don’t need either you don’t even need to know it’s there: AccessToken will use it transparently.
ADAL.NET is available on Nuget here: https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/
If you aren't using ADAL.NET, provide more info, such as:
What library you are using
What is ACS on top of, AD FS or Azure Active Directory
We use ACS + ADAL and there seems to be no clever way to refresh the token. Even if the ExpiresOn Time on the Token inside the Cache is due the AcquireToken always returns the stale cached token. We cache the token ourself, so this code is only invoked when the ExpiresOn is due.
I ended up with this dirty hack:
var authContext = new AuthenticationContext(ServiceInfo.AcsUrl);
if (authContext.TokenCacheStore.Count > 0)
{
authContext.TokenCacheStore.Remove(authContext.TokenCacheStore.First());
}
result = authContext.AcquireToken(acsRealm, allProviders.First());
I'm struggling to figure out how to use my Box authentication tokens to use the Box API. I've built the authentication flow into my app so that I can save away the relevant pieces (access token, refresh token, etc.) to the Keychain. The issue I'm having is that whenever I re-open the app, I can't seem to find an appropriate way to set up my BoxOAuth2Session or whatever to re-use the saved tokens to upload files to Box. Currently, I'm recreating the BoxOAuth2Session with my clientID and secret, and manually setting the accessToken, refreshToken, etc. values on that session. I create a BoxFilesResourceManager, attach this BoxOAuth2Session, and upload a file with uploadFileWithInputStream. This request always fails with a 401. The only way I have been able to upload files to Box is immediately following the login step using the [BoxSDK sharedSDK].filesManager. What is the expected workflow for re-creating the OAuth state to access the API?
A BoxOAuth2Session is bound to an SDK instance. When you access the [BoxSDK sharedSDK] singleton, you are using an instance of the SDK that is already wired up with its own BoxOAuth2Session and manager instances. In normal usage, we recommend using the sharedSDK singleton, so you should manipulate the BoxOAuth2Session attached to this SDK.
One way to do this is to attempt to load a refresh token from the keychain and set the refreshToken property on the OAuth2Session.
[BoxSDK sharedSDK].OAuth2Session.clientID = #"YOUR_CLIENT_ID";
[BoxSDK sharedSDK].OAuth2Session.clientSecret = #"YOUR_CLIENT_SECRET";
// set up stored OAuth2 refresh token
self.keychain = [[KeychainItemWrapper alloc] initWithIdentifier:REFRESH_TOKEN_KEY accessGroup:nil];
id storedRefreshToken = [self.keychain objectForKey:(__bridge id)kSecValueData];
if (storedRefreshToken)
{
[BoxSDK sharedSDK].OAuth2Session.refreshToken = storedRefreshToken;
}
The SDK will automatically refresh the OAuth2 session and acquire a new access token and refresh token on the next API call, so long as the refresh token has not been revoked and is not expired. You may wish to manually trigger a heartbeat call to force a refresh.
We've put together a sample app that demonstrates how to store and load refresh tokens using the keychain.
As a side note, we do not recommend storing the access token on the device since this token is a bearer token; losing this token could allow Mallory to impersonate your app's users.