I am developing an android mobile client and signing with oauth2 to our server that is written in c#. Everything is working well, until the server is rebooting.
I'm crashing every call to the server.. at first I've thought that my access token is not valid anymore. but after I've decided to have my own local server I saw that my calls do reach the server and they crash inside because of some static lists of tokens and user data that the server team developed and obviously getting cleared after restarting the server.
I've told them to recreate their lists of data and access tokens, but no luck for me there..
My question,
I'm not so good in server-side and oauth2 developing but i'm pretty sure there is a solution for what i want. I've tried searching for few hours without success. My thought is - To make the server decline all old access tokens from previous run of the server - and i will get unauthorised code in my client (Now i'm getting just crush in server that i don't know why and how to react in my app) Something like - Each time the server restart it will have a random seed and will create its access tokens with this seed.
Is there something like this ? or some other "Not so much work" solution for the lazy server-side team :)?
The service that is issuing you the OAuth token is also the service that needs to revoke tokens. There is nothing inside a token that you can change to invalidate it that would also not corrupt it.
If your server is crashing because you are sending it unknown / invalid tokens, this is a serious problem. The first step than anyone will do (should do) is to validate the token. Evidentally they are not. Security requires attention to detail and having a server crash due to tokens is a security problem (Denial of Service).
Related
Im wondering if anyone has any answers to this. If one follows the quickstart here:
https://developers.google.com/calendar/api/quickstart/go
we can get authorization from a user that allows us to do things with their calendar.
It seems the HTTP Client given back from the config handles calling the refresh token and keeping the client up to date.
First, as a side-question, does anyone know how long this is allowed to persist? I read in a doc somewhere that for unpublished apps/projects its 7 days, but it didn't specify a timeline otherwise. Is it indefinite or will this expire at some point (ie the refresh token runs out after 30 days). And is this avoidable at all?
now, the real question - if you take the service down entirely, ie for an update, and restart it, is there any way to opick up the authorization again? In the tutorial its writing a code to disk and reading as needed. In my case I just hold reference to the things I need in the application, so obviously when the service went down id have to reauthorize. I then tried writing the code to disk on a persistent volume and re-reading from that, but it doesnt get authorized - I guess because the new instance of the service has a new instance of the oauth config, and it wont accept the old code perhaps?
In any case, im wondering if anyone knows of a way to make this persist through ssytem restarts, or if the only real option here is to move the calendar service client to a small microservice on the side that we do not restart, and contact it from elsewhere as needed.
Thanks in advance!
The refresh token expiration is documented here. As you've noted, tokens expire in 7 days for projects in "Testing" status. Refresh tokens for projects in production last indefinitely, but there are some scenarios where they may get invalidated (user revokes access, token has not been used in 6 months, the account has over 50 live tokens, etc.). It's not mentioned but if you change your OAuth scopes you'll probably need to reauthorize as well.
This means that as long as you keep your refresh tokens and none of the invalidation conditions are met, you should be able to keep using them to get new access tokens even if your service goes down temporarily. But as mentioned in the documentation, you should anticipate the possibility that the token stops working and redirect the user to authorize again.
My guess is that in your case the refresh token stopped working for some reason (maybe the 7 days limit) and the application just tried to use the same expired token. The Quickstarts in Google's documentation usually handle the creation of the token file and how to reuse it, but they don't include the part where you have an invalid token and need to reauthorize.
References:
Google's OAuth2 Overview
OAuth2 for Web Apps
So, last week my application that connects to Office365 using IMAP suddenly stopped working with Basic Authentication (gee, thanks for the early cut-off with no warning Microsoft). I tried troubleshooting that issue for hours, and could find literally nothing wrong since everything was already configured to work with Basic Auth (and was working). I do know they've been threatening to shut-off Basic Auth for a while now, and with a new looming deadline of October, 2022.
After getting nowhere with why it suddenly stopped working, I finally decided to just bite the bullet and switch to using the XOAUTH2 authentication mechanism. After a day and a half of trial-and-error to put together the right series of incantations to make that work correctly, I got that working. Microsoft's documentation is borderline garbage with conflicting information and confusing examples. That and a complete lack of any reasonable error response from the IMAP server about why authentication failed (just the lovely "NO AUTHENTICATE failed" message).
Note: I am using the Client Credentials flow and the AccessToken is being issued to expire after 1 hour.
So, here's the question:
My app basically loops on IDLE and/or processing new mail. When the AccessToken expires, the server will respond with a "Session invalidated - AccessTokenExpired" and then just close or reset the connection. This does make sense, but I would prefer to keep the connection open and just re-authenticate.
My first idea was just re-issue the "AUTHENTICATE" command 1 minute before the AccessToken expired. Server did not like that and gave me a "Command received in Invalid state." response. Hrmph.
Second idea was 1 minute before the AccessToken expired, issue a "LOGOUT" and then "AUTHENTICATE" again. However, Microsoft's IMAP server responds to the "LOGOUT" with "OK" and then closes the connection... Hrmph.
C: R0001 AUTHENTICATE XOAUTH2
S: +
C: <username:token base64>
S: R0001 OK AUTHENTICATE completed.
C: R0002 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4REV1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CLIENTACCESSRULES CLIENTNETWORKPRESENCELOCATION BACKENDAUTHENTICATE CHILDREN IDLE NAMESPACE LITERAL+
S: R0002 OK CAPABILITY completed.
C: R0003 SELECT INBOX
... <59 mins later> ...
C: R0021 LOGOUT
S: * BYE Microsoft Exchange Server IMAP4 server signing off.
S: R0021 OK LOGOUT completed.
Connection closed.
I did notice there's a server capability called "BACKENDAUTHENTICATE", but there literally is no documentation that I could find on what the heck that capability is about or used for...
What I would really like to do is just issue something like "AUTHENTICATE" again, but with the new AccessToken and then go back to the IDLE/new mail loop. Or maybe a "REAUTHENTICATE" command (that doesn't currently exist).
And yes, I have read RFC4959, RFC3501, and even RFC2222 (as well as a lot of SO posts).
For now, I have just accepted the fact that the connection is going to close and then I'll turn around and re-open a new one...
I would love to hear if anyone has any other bright ideas.
I am considering re-implementing the application using their Graph API, which might be the slightly better long-term option assuming we stay on Microsoft Office365.
I did like that IMAP was a more generic and broadly accepted mailbox protocol and why I chose it in the first place.
Let me try to answer some of your questions.
I do know they've been threatening to shut-off Basic Auth for a while now, and with a new looming deadline of October, 2022. After getting nowhere with why it suddenly stopped working
Microsoft says that in early 2022, they will pick tenants (using some unpublished criteria) and disable basic authentication for all the chosen protocols except SMTP AUTH for a period of between 12 and 48 hours. SMTP AUTH is excluded because it might affect important operational aspects like multi-functional devices or PowerShell scripts sending updates about a job’s progress. When the period expires, Microsoft will enable basic authentication automatically.
Please refer to this link : https://office365itpros.com/2021/09/24/basic-authentication-exchange/
The Basic Auth has been already disabled for many of my clients, so the above statement is valid.
I am using the Client Credentials flow and the AccessToken is being issued to expire after 1 hour.
Using the Client Credentials flow, you do not get a refresh Token which can be used to get a valid Token without losing/dropping/closing the connection.
Based on the RFC6749 (https://www.rfc-editor.org/rfc/rfc6749#section-4.4.3), a refresh Token should not be included.
As #Max mentioned in his comment, "RFC3501 does not include any ability to reauthenticate an existing connection".
Since you don't want to lose/close the connection, I would recommend to use the
Oauth2 authorization code flow (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow), which will give you a refresh Token as well.
Also, I would recommend to use the Microsoft Authentication Library (MSAL) (https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-overview)
The Microsoft Authentication Library (MSAL) enables developers to acquire tokens from the Microsoft identity platform in order to authenticate users and access secured web APIs. It can be used to provide secure access to Microsoft Graph, other Microsoft APIs, third-party web APIs, or your own web API. MSAL supports many different application architectures and platforms including .NET, JavaScript, Java, Python, Android, and iOS.
My Box app (using v2 API) keeps track of when an access token expires, and when the app realizes the access token is about to expire, it request a new access token using the refresh token (the reason is that it simpler to avoid errors than to handle them).
I noticed that lately (this definitely was working properly a few months ago), when my app starts up (after more than 1 hour of non-use), the request for a new access token fails! The interesting thing is that at this time, my app has not attempted to use the now expired access token.
Should my app first do a dummy action with the expired access token maybe as a workaround? Again, all this was working as expected when I converted the app over to V2 API. At that time, the refresh token was valid for 14 days.
Thanks
Peter
I've tried to reproduce it, and I'm not able to. My refresh tokens are all working. It could be that you are getting an error condition on your refresh that you are not catching. There are some cases where your admin can decide that the app you are using is no longer approved for your enterprise, and on refresh, you'll be booted out. Or you may have mis-typed your password enough times that your password is going into "captcha" mode, looking to verify that there's a human, and not a machine on the other end of the wire.
Let me suggest that you log out of the app, and log back in. You're more likely to get presented with the error, since Box will be giving you the auth screen, and Box handles all the weird cases in their OAuth2 screens.
Yet another reason, that for all the pain of implementing Oauth2, it's worth it to get a better experience for your users.
I'm getting the following
{
"error" : "invalid_grant"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:103)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
at com.google.api.client.googleapis.auth.oauth2.GoogleRefreshTokenRequest.execute(GoogleRefreshTokenRequest.java:130)
This only happens in my production Appengine instance, (ie. not on dev server), and it only happens for the email address that I use for testing on both dev and production.
My working hypothesis is that it is something to do with the user being granted a refresh-token on the dev server which is somehow interfering with the stored refresh-token on the prod server.
Can anybody confirm this explanation, and is there a best practice on how to deal with this exception?
Currently only the last 25 refresh tokens granted by Google work.
We basically keep a queue of size 25 of generated refresh tokens.
That mean that on your testing account if you happened to generate more than 25 refresh tokens the older ones will start to be revoked.
Maybe that is what is happening here so I wanted to point this out, it could be that you generated more than 25 refresh tokens on your dev server with your test account and the token that was in prod got dropped (because there are 25 newer ones).
That is something that is not documented about our authentication servers and as such be aware that it could change anytime.
In general when this exception happens you need to make the user go through a new OAuth 2.0 flow in order to get a new refresh token.
For an ios 5.0 application connecting to a rest webservice, the customer wants to implement a token based security to ensure that the data being sent over the network is not intercepted and altered in any way... Doesn't https over ssl ensure that the data is not intercepted? and I thought that this would be enough. Pls advise
However, The way the client wants it to work is that starting with the first client authentication request the server would return a token id that would be used to send the next request. In the response for this next request another token id would be sent back that needs to be used for the next request and so on. The problem is of concurrency. Eg when the apns token comes back and the app has to send that to the server and if at that time the iOS application is already making a data request to the server, then the tokens to be used will not match. also since the app has to regularly poll the server for new items, then there are more chances of such concurrency issues to occur.. Any ideas what efficient solutions I can put in the app to counter this?
Or if anyone can suggest better ways of implementing security over the network data, as a possible alternative to the above approach.. solutions that would work for an iOS app and is not battery consuming?
Help in this would be greeeeaaatly appreciated! :-)
Ps. Jfyi Am already doing md5 security on the token being sent
Doesn't https over ssl ensure that the data is not intercepted?
It depends on whom you're trying to protect agains. Plain SSL will protect perfectly fine against anyone between the device and the server.
But it will be trivial for the device owner to create a man-in-the-middle against a client that trusts all CA's on the device. All he needs to do is install his own private CA-certificate on the device, issue a fake certificate for your server signed by this CA, and install this certificate on his proxy/MitM device. To avoid this attack you'd need to do certificate pinning in the App.