providers/azure-devops
AzureDevOpsProfile
See
Azure DevOps Services REST API 7.0 · Profiles · Get
Extends
Record
<string
,any
>
Indexable
[key
: string
]: any
Properties
coreAttributes
coreAttributes: { Avatar: { value: { value: string; }; }; };
Avatar
Avatar: { value: { value: string; }; };
Avatar.value
Avatar.value: { value: string; };
Avatar.value.value
Avatar.value.value: string;
displayName
displayName: string;
emailAddress
emailAddress: string;
id
id: string;
default()
function default<P>(options): OAuthConfig<P>
Type Parameters
Type Parameter |
---|
P extends AzureDevOpsProfile |
Parameters
Parameter | Type |
---|---|
options | OAuthUserConfig <P > & { scope : string ; } |
Returns
OAuthConfig
<P
>
Deprecated
While still available, Microsoft is no longer supporting Azure DevOps OAuth and recommends using Microsoft Entra ID instead.
Documentation
Microsoft Docs · Azure DevOps · Authorize access to REST APIs with OAuth 2.0
Configuration
Register application
Provide the required details:
- Company name
- Application name
- Application website
- Authorization callback URL
https://example.com/api/auth/callback/azure-devops
for productionhttps://localhost/api/auth/callback/azure-devops
for development
- Authorized scopes
- Required minimum is
User profile (read)
- Required minimum is
Click ‘Create Application’
⚠️
You are required to use HTTPS even for the localhost
⚠️
You will have to delete and create a new application to change the scopes later
The following data is relevant for the next step:
- App ID
- Client Secret (after clicking the ‘Show’ button, ignore App Secret entry above it)
- Authorized Scopes
Set up the environment variables
In .env.local
create the following entries:
AZURE_DEVOPS_APP_ID=<copy App ID value here> AZURE_DEVOPS_CLIENT_SECRET=<copy generated client secret value here> AZURE_DEVOPS_SCOPE=<copy space separated Authorized Scopes list here>
Example
import AzureDevOps from "@auth/core/providers/azure-devops" ... providers: [ AzureDevOps({ clientId: process.env.AZURE_DEVOPS_APP_ID, clientSecret: process.env.AZURE_DEVOPS_CLIENT_SECRET, scope: process.env.AZURE_DEVOPS_SCOPE, }), ] ...
Refresh token rotation
Use the main guide as your starting point with the following considerations:
async jwt({ token, user, account }) { ... // The token has an absolute expiration time const accessTokenExpires = account.expires_at * 1000 ... } async function refreshAccessToken(token) { ... const response = await fetch( "https://app.vssps.visualstudio.com/oauth2/token", { headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: "POST", body: new URLSearchParams({ client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", client_assertion: process.env.AZURE_DEVOPS_CLIENT_SECRET, grant_type: "refresh_token", assertion: token.refreshToken, redirect_uri: process.env.NEXTAUTH_URL + "/api/auth/callback/azure-devops", }), } ) ... // The refreshed token comes with a relative expiration time const accessTokenExpires = Date.now() + newToken.expires_in * 1000 ... }