Azure AD Access Token Lifetimes and PowerShell Scripts (2024)

Table of Contents

Sometimes Scripts Need Extended Azure AD Access Token Lifetimes

A recent issue where Microsoft limited the page size for the Graph List Users API when retrieving sign-in activity sparked a request from a reader who had problems with a script. They reported that roughly an hour into the script, it failed with a 401 Unauthorized error. The reason is that the access token granted to the app to allow it to run Graph requests to fetch data expired, meaning that the next time the app tried to request data, the Graph refused.

The default Azure AD access token lifetime varies between 60 and 90 minutes (75 minutes on average). The variation exists on purpose to avoid cyclical spikes in demand. Exceptions to the rule do exist. For example, applications like SharePoint Online and OWA that support continuous access evaluation (CAE) can use tokens that last up to 28 hours. These apps support a feature known as claim challenge that is unlikely to be found in apps that execute Graph requests through PowerShell.

Apps can retrieve access tokens from Azure AD using different OAuth 2.0 authentication flows, including password, device code, and authorization code. Azure AD registered apps usually use the client credentials authentication flow. The app authenticates using its own credentials instead of trying to impersonate a user. Valid app credentials include a secret known to the app, a certificate, or a certificate thumbprint.

The client credentials authentication flow does not include the issuance of a refresh token. The lack of a refresh token, which allows apps to silently renew access tokens, means that if you want to keep a script running, you must either:

  • Configure the tenant with a longer access token lifetime.
  • Include code in the script to fetch a new access token before the current one expires.

Configurable Azure AD Access Token Lifetimes

Azure AD supports configurable token lifetimes. This is a preview feature that can set a longer lifetime for an access token. However, the current implementation supports setting token lifetimes for all apps in an organization or for multi-tenant applications. For instance, this code creates a new token lifetime policy that sets a default two-hour token lifetime. Note the organization default setting is True, so this policy applies to all apps in the organization.

$PolicySettings = @{ "definition"= @("{'TokenLifetimePolicy':{'Version': 1, 'AccessTokenLifetime': '2:00:00'}}") "displayName"= "Org-wide 2 Hr AccessTokenPolicy" "IsOrganizationDefault" = $True} New-MgPolicyTokenLifetimePolicy -BodyParameter $PolicySettings

To test the policy, use an app to request an access token. Here is some PowerShell code to get an access token using the client credentials authentication flow. In this case, the credential is a client secret stored in the app.

$AppId = “de0d7a5d-982a-49e2-8c52-f4596f32b437”$TenantId = “a662313f-14fc-43a2-9a7a-d2e27f4f3478”$AppSecret = “3il8Q~Yx4_DOJZxHAxvp7akxW5TQxXdSzhsGpdme”$Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"$Body = @{ client_id = $AppId scope = "https://graph.microsoft.com/.default" client_secret = $AppSecret grant_type = "client_credentials"}# Get OAuth 2.0 Token$TokenRequest = Invoke-WebRequest -Method Post -Uri $Uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing# Unpack Access Token$Token = ($tokenRequest.Content | ConvertFrom-Json).access_tokenWrite-Host ("Retrieved new access token at {0}" -f (Get-Date)) -foregroundcolor red

Take the access token stored in the $Token variable and examine its contents. For example, Figure 1 shows how jwt.io displays the settings in an access token. To verify that the token lifetime works is expected, compare the time of issuance with the expiration time. In this instance, the timespan should be two hours.

Azure AD Access Token Lifetimes and PowerShell Scripts (1)

Although creating a token lifetime policy with a new default lifetime for the organization works, increasing token lifetime in this manner is not something to do on a whim. It would be better to be able to assign a token lifetime policy only to the apps that need to use extended token lifetimes.

An organization can support multiple token lifetime policies. It would be nice to be able to apply suitable policies to apps as needed but this doesn’t seem to be possible currently. The Microsoft PowerShell Graph SDK includes the New-MgApplicationTokenLifetimePolicyByRef cmdlet, and you can use the cmdlet assign a token lifetime policy to an application. Alas, this has no effect on the access tokens issued by Azure AD to the app. I’ve been discussing this point with Microsoft and investigations continue.

Tracking Azure AD Access Token Lifetime in Scripts

The alternative is to incorporate code into scripts to track the lifetime of an access token so that the script can retrieve a new token before the old one expires. The script for the Microsoft 365 Groups and Teams Activity Report uses this technique. A function checks if the current time is greater than the calculated token expiration time. If it is, the script requests a new token:

Function Check-AccessToken {# Function to check if the access token needs to be refreshed. If it does, request a new token# This often needs to happen when the script processes more than a few thousands groups$TimeNow = (Get-Date)if($TimeNow -ge $TokenExpiredDate) { $Global:Token = GetAccessToken $Global:TokenExpiredDate = (Get-Date).AddMinutes($TimeToRefreshToken) # Write-Host "Requested new access token - expiration at" $TokenExpiredDate }Return $Token}

The function can then be called whenever necessary within the script.

$Global:Token = Check-AccessToken

This is a relatively unsophisticated mechanism, but it allows the script to process tens of thousands of groups. Variations on the theme can handle other situations.

Only for Special Scripts

The default lifetime for an access token is sufficient for most scripts. Even scripts that run dozens of Graph requests can usually complete processing in a few minutes. It is scripts that must retrieve tens of thousands of items (or even hundreds of thousands of items) that usually deal with inadequate Azure AD access token lifetimes. In those cases, you’ll be glad that methods exist to avoid the dreaded 401 Unauthorized error.

Support the work of the Office 365 for IT Pros team by subscribing to the Office 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365.

Related

Azure AD Access Token Lifetimes and PowerShell Scripts (2024)

FAQs

What is the lifespan of Azure AD access token? ›

Access and ID token lifetimes (minutes) - The lifetime of the OAuth 2.0 bearer token and ID tokens. The default is 60 minutes (1 hour). The minimum (inclusive) is 5 minutes. The maximum (inclusive) is 1,440 minutes (24 hours).

What is the lifetime of Azure AD conditional access token? ›

The default lifetime of the token is 1 hour. From an application's perspective, the validity period of the token is specified by the NotOnOrAfter value of the <conditions …> element in the token.

How long does SSO token last? ›

The minimum token lifetime is 5 minutes, and the maximum is 1,440 minutes (24 hours)1. If your application has been granted the offline_access scope, the refresh token lifetime is 14 days1. However, you can customize these token lifetimes based on your organization's needs.

What is the lifetime of access token? ›

Configure access token lifetime

Locate the Token Expiration field under Token Settings. Enter the desired lifetime (in seconds) for access tokens issued for this API. Default value is 86,400 seconds (24 hours). Maximum value is 2,592,000 seconds (30 days).

What is the lifetime recommendation of access token? ›

Access token lifetime

By default, an access token for a custom API is valid for 86400 seconds (24 hours). We recommend that you set the validity period of your token based on the security requirements of your API.

What happens after access token expires? ›

After expiration, the user gets a new refresh token in the same family, or refresh tokens that share a family ID, or a new access token/refresh token pair. To learn more, read Refresh Token Rotation.

What is the lifespan of refresh token vs access token? ›

Another major differentiating factor for refresh tokens is that they last much longer than access tokens. For example, refresh tokens in Microsoft's identity platform have default and rigid (non-configurable) lifespans of 90 days for most scenarios and 24 hours for single-page apps.

What is the lifetime of ADFS 2016 token? ›

The maximum lifetime of a token is 84 days, but AD FS keeps the token valid on a 14-day sliding window. If the refresh token is valid for 8 hours, which is the regular SSO time, a new refresh token isn't issued.

Should access tokens expire? ›

By default, access tokens are valid for 60 days and programmatic refresh tokens are valid for a year. The member must reauthorize your application when refresh tokens expire.

How to check if access token is expired or not? ›

So the best way to handle this is to have the next line after you obtain the token (and this is true for both JWT Grant or Authorization Code Grant) perform a simple calculation that tells you when the token expires by adding the number of seconds to the value of Now() (each language has a similar method).

Do tokens have an expiry date? ›

Your tokens can expire and can also be revoked by you, applications you have authorized, and GitHub itself.

How long does an Azure MFA token last? ›

When I access my web app that is registered in Azure AD, it first sends my app to Microsoft login page and after successful login it returns an id token which is used to retrieve the data from backend server. The expiry time of token is approx. 30 mins to 1 hr.

How long does an Office 365 access token last for? ›

The default lifetime for the access token is 1 hour.

Is access token expired? ›

ACCESS_TOKEN_EXPIRED means that the access token you have used has expired. You need a valid access token in order to access the api. Access tokens are only valid for an hour and then they are expired. The solution is to either use your refresh token to request a new access token.

Top Articles
Latest Posts
Article information

Author: Edmund Hettinger DC

Last Updated:

Views: 5496

Rating: 4.8 / 5 (58 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Edmund Hettinger DC

Birthday: 1994-08-17

Address: 2033 Gerhold Pine, Port Jocelyn, VA 12101-5654

Phone: +8524399971620

Job: Central Manufacturing Supervisor

Hobby: Jogging, Metalworking, Tai chi, Shopping, Puzzles, Rock climbing, Crocheting

Introduction: My name is Edmund Hettinger DC, I am a adventurous, colorful, gifted, determined, precious, open, colorful person who loves writing and wants to share my knowledge and understanding with you.