We have a standalone Java application (see "Installed application") which runs periodically and uses Google API (updates some information from customer databases/ldap/...).
To access Google APIs we store username and password in configuration file, which is a security risk and customer does not like that. So we would like to use OAuth2 long-living access token instead.
What`s default expiration time for Google OAuth2 access tokens ?
As we will have only access token in application, app itself cannot refresh it when access token expires.
Personally I think that OAuth2 implementation in this case will not bring any major benefit but let`s focus on main question - default expiration times.
You shouldn't design your application based on specific lifetimes of access tokens. Just assume they are (very) short lived.
However, after a successful completion of the OAuth2 installed application flow, you will get back a refresh token. This refresh token never expires, and you can use it to exchange it for an access token as needed. Save the refresh tokens, and use them to get access tokens on-demand (which should then immediately be used to get access to user data).
EDIT: My comments above notwithstanding, there are two easy ways to get the access token expiration time:
It is a parameter in the response (expires_in)when you exchange your refresh token (using /o/oauth2/token endpoint). More details.
There is also an API that returns the remaining lifetime of the access_token:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={accessToken}
This will return a json array that will contain an expires_in parameter, which is the number of seconds left in the lifetime of the token.
The default expiry_date for google oauth2 access token is 1 hour. The expiry_date is in the Unix epoch time in milliseconds. If you want to read this in human readable format then you can simply check it here..Unix timestamp to human readable time
Related
I've been doing a lot of reading on this subject and I can see that there are many different opinions and approaches to authenticating using JWT.
My understanding is as follows:
In its simplest form, a JWT authentication mechanism should:
Verify username and password.
Create a signed JWT access token containing information (depending on the app's needs) on the user.
Send that token in the response.
The client then stores the token (which from my understanding there is some debate whether a secure cookie or localStorage is more secure), and sends it with each request's headers.
The server can then authorize the user using middleware verifying the JWT. No state, all information in contained within the JWT.
Assuming the JWT has no expiration (or perhaps a very long expiration date, maybe a couple of months), it sounds good because I can provide the user a persistent logged in state for a long time. The concern is, to my understanding, if the JWT was to be stolen, it is essentially an unlimited access card and a huge security breach.
So that's where the refresh token enters, the server issues both refresh and access tokens (refresh token with a long/unlimited expiration and the access token short).
The server database holds some kind of table of valid refresh tokens (so that if one is stolen it can be invalidated easily) and when issuing a new access token, validates the refresh token.
This also adds the need to add some sort of countdown mechanism on the front end where a refresh request is to be sent to the server prior to the access token expiration date so that the user won't be logged out.
And my question:
Why? If we go through all the trouble of creating a db table for refresh tokens, why not just make a table of valid access tokens and invalidate them if needed? How is that less secure than using refresh tokens?
Thank you
Access tokens aren't primarily used to provide extra security, but to provide efficiency and decoupling.
An access token can have a very short lifetime - maybe even less than a minute - but be used to authenticate multiple requests to different services within that time. Those services don't need to have any access to the authentication database, because they can trust the access token until its expiry date; that makes them faster and simpler.
For instance, if you're using a dynamic page with lots of AJAX requests, that might run in very quick succession. Those AJAX calls might be implemented as serverless functions (e.g. AWS Lambda), or as standalone scripts in different programming languages on different servers, or you might just want to make them as efficient as possible, and avoid any database access. The only information that needs to be shared between them is a public key to verify the signature on the JWTs they receive.
From a security a point of view, this is a trade-off: on the one hand, an access token for a user whose access has been revoked can still be used until it expires; on the other hand, the long-lived refresh token is transmitted much less than a traditional session token, so there are fewer chances for it to be intercepted.
To address your concrete concern:
This also adds the need to add some sort of countdown mechanism on the front end where a refresh request is to be sent to the server prior to the access token expiration date so that the user won't be logged out.
No "countdown" is needed. The code that has access to both tokens simply looks at its current access token before using it; if it has expired, or is about to expire, it requests a new one using the refresh token. It then gets a new access token, and probably a renewed refresh token - the expiry date on the refresh token represents how long the user can be idle before they are automatically logged out.
We don't need to make a table of access tokens and it is dangerous to secure.
We have to save only refresh token and add one field for valid/invalid in the table. And send access token and refresh token to the client side.
The clients send access token with each request's headers.
The server can authorize the user using middleware verifying the JWT.
After some time, the access token will be expired(access token's expired time is shorter than the refresh token's expired time).
The client sends refresh token to server.
Then the client will get new access token using refresh token(refresh token should be recreated, in other words, we can use only one-time refresh token, we have to update table of refresh token with new refresh token).
The client can get new access token and refresh token.
I hope it will be help you.
I have questions related to non interactive clients like backend apps based on oauth2 flow.
https://auth0.com/docs/api-auth/grant/client-credentials
In accordance with oauth2 for non interactive clients, flow is :
The application authenticates with Auth0 using its Client Id and Client Secret.
Auth0 validates this information and returns an access_token.
The application can use the access_token to call the API on behalf of itself.
Base on this, my questions are :
Backend applications should store the access_token locally or request a new access_token for the same client each time the client uses the application?
If access_token is stored locally what happend with expiration time?
Access_token for non interactive clients should have the same expiration time compared with access_token for interactive users (login web) ?
Backend applications should store the access_token locally or request
a new access_token for the same client each time the client uses the
application?
For client credentials grant flow, the decision whether to renew frequently, or "cache" a returned JWT Access token will depend upon your requirements - if scopes for example change frequently, it may make sense to fetch a new access token frequently to ensure those changes are reflected. Speaking from personal experience, this generally isn't the case, so caching the token for the duration of its expiration makes sense, and saves an extra call to Auth0 to fetch a new token with each request.
If access_token is stored locally what happened with expiration time?
You can choose to check the expiration before making a request each time, and fetch a new access token if expiration has elapsed, or else just attempt to use the access token without checking, and then try renewing only when you receive a failure when using the existing token.
Access_token for non interactive clients should have the same
expiration time compared with access_token for interactive users
(login web) ?
Similar question to the first one. Since using Client Credentials grant flow usually indicates confidential / trusted client (you are storing a client secret) - and frequently for machine to machine scenarios - it may make sense to use a greater expiration time. However, as already mentioned, if scopes may change etc, then a short expiration would result in configuration changes (scopes) being picked up faster.
On most of the JWT (JSON Web Token) tutorial (e.g: this and this) are saying, once validated you can use the incoming token to get client information without validating it from the DB.
My question is, how invalid user situation is maintained then? What I mean is, lets say a client just got a JWT token which expires in one week. But for very specific reason lets say we decided to invalidate the user, and don't want the user to access our API. But still that user has a token which is valid and user can access the API.
Of course if we take a round trip to DB for each request then we can validate if the account is valid or invalid. My question is, what is the best way to take care this kind of situation for long lived tokens.
Thanks in advance.
It's difficult to revoke JWT-based access tokens if not impossible.
How should an access token be represented? There are two major ways.
As a meaningless random string. Information associated with an access token is stored in a database table behind an authorization server.
As a self-contained string which is a result of encoding access token information by base64url or something similar.
A choice between these ways will lead to consequent differences as described in the following table.
See "7. Access Token" in "Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings" for pros and cons of the ways of access token representation.
If your access tokens are JWT-based, your system has to (1) remember revoked access tokens until they expire. Another compromise is to (2) make lifetime of access tokens short enough and give up revoking them.
Personally, after consideration, I didn't select JWT as access token representation when I implemented an authorization server (Authlete) because it is difficult/impossible to revoke and update JWT-based access tokens once they are issued.
RFC 7009 specifies OAuth 2.0 Token Revocation. Basically you have an endpoint where you can revoke the access_tokens.
It's not clear which OAuth flow you are using from your question, or whether you are referring to OpenID Connect rather than Oauth.
Consider using refresh tokens and have a much shorter expiration on your access token - e.g. 30 mins.
In this scenario, the user (resource owner) doesn't have to keep authenticating, and your API (Resource Server) doesn't have to check the user is still valid on every single request.
Once the access token expires, your client (application calling your API) should contact your DB (Authorisation Server) and exchange its refresh token for a new access token - and usually a new refresh token - providing the user is still a valid user on your DB and the user has not revoked access for the client application to his/her data on the API.
You could also use token revocation as suggested in another answer if your Authorization Server allows it but I would try refresh tokens and short-lived access tokens as it's much easier to implement and doesn't pollute your API with user authentication/authorisation concerns - this job is best done by an Auth Server.
That's the main problem when you are using JWT. So basically best approach in this case is creating blacklist on your gateway. It's not best solution for security point of view but this is only good solution if you are using JWT.
I'm currently using my own Instagram account (not that of my users) to get an access_token, and thus I don't need to create an explicit server-side authentication flow for myself to get the code. I can then use the code programmatically to get an access_token without any human interaction.
My question is, for the purposes of an app that only requires the owner's code to get an access_token, does Instagram let you reuse the same code so that you don't have to keep manually entering a new one?
Thanks :)
If you are only using a single account, there is currently no need to request new access tokens repeatedly. You should be authenticating one time, and storing that access token to use with calls to the API endpoints.
Instagram access tokens currently have no set expiration, however may expire at any time in the future. So you may reuse the token indefinitely (for now), but build the system to be prepared to request a new token in the event that the stored token expires.
Per http://instagram.com/developer/authentication/:
Note that we do not include an expiry time. Our access_tokens have no
explicit expiry, though your app should handle the case that either
the user revokes access or we expire the token after some period of
time. In this case, your response’s meta will contain an
“error_type=OAuthAccessTokenError”. In other words: do do not assume
your access_token is valid forever.
I'm playing around with the api of a service that supports oauth. I managed to retrieve the access_token from the service and I'm now able to call the various endpoints of the api. So far so good.
Now my question is: How long do I hold on to this access_token I received. Is this a token I keep forever, or does this expire after some time? I'm working on a desktop app, so I a have two options:
I request a new token every time the application is opened
I store the token somewhere and re-use it
What are the best practices around the storage of this token?
Usually the Access Token is stored across sessions. There is an expiration (with OAuth 2.0), but the Refresh Token is then used to retrieve a new Access Token. If you don't store the tokens, then you would need to have the end user re-authorize everytime they want to use your application (which is probably not the experience you are looking for).