I'm having some trouble understanding how to get a Microsoft graph API token that lives more than 3599 seconds.
This is my first call to the API to get the first token:
And now that I got a refresh token I going to pass it through another call to get a new token:
This all works fine, except the new token also has a 3599 duration, so, my question is, is it possible to get a longer lived token, e.g. 14 days?
This actually isn't determined by Microsoft Graph but rather by Azure Active Directory.
For a given tenant, the life-time can be configured using Configurable token lifetimes in Azure Active Directory (Public Preview). There are a couple of important notes about this functionality:
This functionality is still in Preview, so functionality may change between now and general release.
This configuration is per tenant, service principal, or application. If you configure it on the application, then the policy will apply on multi-tenant applications unless superseded by a policy on the service principal or tenant level.
The maximum lifetime for an Access token is 24 hours (minimum is 10 minutes, default is 1 hour).
In general, rather than adjusting the lifetime of the Access Token you should rely on the Refresh Token instead. These have a much longer lifetime of 14 days.
Related
When creating GitLab "Applications" for the purpose of 3rd party integrations, you also create access-tokens to enable said communication between GitLab and 3rd party software.
As of GitLab 15, access-tokens (and refresh-tokens) expire after 2hrs. GitLab seems to explain in their docs that it is now expected that access-tokens (or refresh-tokens) be refreshed every 2hrs in order to keep them alive.
This means that a lot of old 3rd party integrations are now breaking in my dev environments. Is it expected that the 3rd party software now implement some cron-job or other type of scheduled job to be able to keep tokens alive?
Or should 3rd party integrations request "Personal Access Tokens" that can have an extended lifetime, and avoid having to implement "refresh logic" for all potential customers that they support?
[should apps] implement some cron-job or other type of scheduled job to be able to keep tokens alive?
No. While this can work, you should only create live tokens when you actually need to use them. That's why you have a refresh token -- to get new tokens after the access token expires. There's no reason to constantly keep access tokens "fresh" and available if you can generate new tokens on-demand.
Your best bet is to build this "refresh logic" into your integrated applications. The fact that tokens do not expire by default in GitLab <15 is really more of a security bug/oversight than a feature.
Note also that refresh tokens remain valid, even after the access token expires. Per the docs (emphasis added):
To retrieve a new access_token, use the refresh_token parameter. Refresh tokens may be used even after the access_token itself expires. This request:
Invalidates the existing access_token and refresh_token.
Sends new tokens in the response.
Or should 3rd party integrations request "Personal Access Tokens"
This is an option, but it's a completely different approach compared to using an OAuth application and, depending on what your integration needs, might require each individual user of your app to create a token and provide it 'manually'. The available scopes for PATs are also different than the scopes available for OAuth apps. So, it's possible, but for a number of reasons, less desirable than an OAuth application.
This might be acceptable for integrations that don't necessarily need to access resources on behalf of users, but can get away with a ~single token (say, a Group Token or a PAT belonging to a member of the customer's top-level GitLab group) or solutions where you want to enroll project-by-project using a project token or similar.
However, if your integration needs to access resources on behalf of users or only needs access appropriate for a limited scope that is not available for access tokens (like email or profile scope), this probably wouldn't be a good approach. You also can't make "trusted" integrations this way.
I'm using an API with OAuth2.0 protocol in my backend environment with password flow (grant_type = "password").I chose this flow because I don't have user interaction, it is just machine to machine (M2M).I know there is another flow, "client_credentials" I think that is more appropriate but the API provider doesn't offer this option.
So, sometimes my system makes 5 request in an hour, sometimes none an hour, this makes me ask as the title says, is it bad to call the password flow for every request?Should I use the refresh token, another possibility or does it just not matter?
The standard behaviour is for your API to work like this:
Authenticate with the Authorization Server to provide a credential and get an access token (which may live for 60 minutes)
Cache the token in the client process (your API) - perhaps in a thread safe memory cache
Call the downstream API with the access token as frequently as you like (eg every 30 seconds)
This ensures that:
The credential is not sent often and on most calls only an access token is sent
When the credential is sent, only the Authorization Server can see it - not the downstream API
The risk of stolen credentials is lower - and if an access token is somehow stolen it will expire soon anyway
Sometimes you may have to work with non standards based APIs. In this case I would still aim to follow the above pattern as best you can.
We have a secure app which needs a very short access token validity period (for example, 15 mins). We would like the access token to remain active while the user is active and making API calls. However, once there is 15 mins of inactivity it should expire. Essentially, the expiration time shouldn't be fixed, but rather 15 mins from last call.
What is a good pattern to use for this model? Is this possible with OAuth2.
OAuth 2.0 doesn't specify how an access token can be validated. That is up to an agreement between the Resource Server (i.e. your API) and the Authorization Server so you're free in your implementation to gear it towards the scenario that you describe.
Either your Resource Server needs to track the inactivity timeout or the Authorization Server can do it and the Resource Server needs to call out on each usage to the Authorization Server to track usage and activity there.
I am implementing an App Store for my application where third-party developers can build there own apps based on my API. I have everything working and understand the concepts of OAuth 2.0, but I don't see how an external app can have timeless access with an access code that expires after one hour. Now you can use a refresh token to request a new one, but that one expires after some time too.
So how can an external app continuously connect to my API when the user of that app allows it only once?
My authorization codes expire after 10 minutes, the access tokens after 1 hour and the refresh tokens after 2 weeks.
I don't see how the app can retrieve data after those periods of time without the user re-allowing/re-installing the application through oauth.
How are bigger companies like Facebook etc. approaching this? Do they have an access token that never expires?
Expanding on my comment, the general recommendation when using bearer tokens is that their lifetime should be reduced in order to mitigate the impact of an access token being compromised.
On the other hand, asking the user credentials every hour or so would be an UX nightmare so OAuth 2.0 has the notion of refresh tokens which will normally have a longer lifetime allowing the application to request a new access token without requiring user intervention.
I'm unfamiliar with the implementation details around Facebook persistent tokens so I won't comment on that, but they are most likely safe. However, you're not Facebook, so my recommendation would be for you to follow public standards like OAuth 2.0/OpenID Connect instead of trying to provide a customized approach.
Regarding your comment about refresh tokens that never expire, it's an acceptable solution, but their lifetime is just one part of the equation. You should consider if they are multi-use or single-use, they can only be used by the client application that they were issued to, they should not be used by browser-based applications due to the difficulties of ensuring secure storage, etc.
I have two clients, one Public Client used by regular end-users logging in via our web page or native apps and one Confidential Client for our admin system. Both issues two JWT's, one Access Token and one Refresh Token.
The Public Client is not allowed to issue admin rights. The Access Token is short lived, and the Refresh Token has infinite life span.
The Confidential Client is allowed to issue admin scopes. The Access Token is short lived, and the Refresh Token lives 24 hrs.
Is it possible, using Spring Security and their oAuth2 implementation, to downgrade the admin user once the refresh token is expired? That is, once the user have been logged in for 24hrs, the user is not totally logged out, but on the next login he gets two new JWT's, one Access Token for regular user access and one matching Refresh Token for that access level. I guess I'm looking for some kind of hook in the Spring Security framework that allows me to handle token expiration in a customised way.
There's a sentence on your question that confuses me a bit, but I wanted to elaborate on other aspects so this did not fit in a comment.
... the user is not totally logged out, but on the next login he gets two new JWT's, one Access Token for regular user access and one matching Refresh Token for that access level.
What do you exactly mean with on the next login? My confusion here is that if the objective is not to logout the user, then there won't be a next login. I guess this could mean that almost to the end of the refresh token expiration you would want to do your downgrade request and use the still valid refresh token to get a new pair of tokens with less permissions.
According to the OAuth specification you can perform a refresh token request and ask the server for an access token that has less scopes than the one you currently have. However, it also dictates that if a new refresh token is returned, then that token needs to have the exact same scope as the refresh token included in the request.
Personally, for this scenario I would consider instead of downgrading tokens just ensure that in order to perform any administrator related operation the user must be an administrator and actually provided his credentials in the last 24 hours. You could accomplish this by tracking the date and time a given user actually performed a login (by providing their credentials) and then authorize administrator actions based on that value. This way you can increase the lifetime of refresh tokens for the confidential client and only force the administrators to login again if they want to perform a privileged tasks and their current tokens aren't fresh enough.
Finally, still on the subject of refresh tokens (with focus on the security considerations section)... when you say web app for the public client I'm assuming it's a browser-based Javascript application. If this is correct it's generally not recommended to use refresh tokens for these applications because refresh tokens are usually long-lived (in your case they seem to never expire) and the browser cannot ensure secure storage for them. This increases the likelihood of them leaking which would give an attacker access to the application for the lifetime of the token. You may have other constraints that make this security consideration not applicable, but I wanted to call your attention to it nonetheless.