microsoft

tarafından vercel

Yerel geliştirme ve test için Microsoft Entra ID (Azure AD) OAuth 2.0 / OpenID Connect öykünmesi. Kullanıcının Microsoft oturum açma işlemini yerel olarak test etmesi gerektiğinde kullanılır,…

npx skills add https://github.com/vercel-labs/emulate --skill microsoft

Microsoft Entra ID Emulator

Microsoft Entra ID (Azure AD) v2.0 OAuth 2.0 and OpenID Connect emulation with authorization code flow, PKCE, client credentials, RS256 ID tokens, OIDC discovery, and a Microsoft Graph /v1.0/me endpoint.

Start

# Microsoft only
npx emulate --service microsoft

# Default port (when run alone)
# http://localhost:4000

Or programmatically:

import { createEmulator } from 'emulate'

const microsoft = await createEmulator({ service: 'microsoft', port: 4005 })
// microsoft.url === 'http://localhost:4005'

Pointing Your App at the Emulator

Environment Variable

MICROSOFT_EMULATOR_URL=http://localhost:4005

OAuth URL Mapping

Real Microsoft URLEmulator URL
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration$MICROSOFT_EMULATOR_URL/{tenant}/v2.0/.well-known/openid-configuration
https://login.microsoftonline.com/.well-known/openid-configuration$MICROSOFT_EMULATOR_URL/.well-known/openid-configuration
https://login.microsoftonline.com/common/oauth2/v2.0/authorize$MICROSOFT_EMULATOR_URL/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token$MICROSOFT_EMULATOR_URL/oauth2/v2.0/token
https://login.microsoftonline.com/common/discovery/v2.0/keys$MICROSOFT_EMULATOR_URL/discovery/v2.0/keys
https://graph.microsoft.com/oidc/userinfo$MICROSOFT_EMULATOR_URL/oidc/userinfo
https://graph.microsoft.com/v1.0/me$MICROSOFT_EMULATOR_URL/v1.0/me

Auth.js / NextAuth.js

import MicrosoftEntraId from '@auth/core/providers/microsoft-entra-id'

MicrosoftEntraId({
  clientId: process.env.MICROSOFT_CLIENT_ID,
  clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
  authorization: {
    url: `${process.env.MICROSOFT_EMULATOR_URL}/oauth2/v2.0/authorize`,
    params: { scope: 'openid email profile User.Read' },
  },
  token: {
    url: `${process.env.MICROSOFT_EMULATOR_URL}/oauth2/v2.0/token`,
  },
  userinfo: {
    url: `${process.env.MICROSOFT_EMULATOR_URL}/oidc/userinfo`,
  },
  issuer: process.env.MICROSOFT_EMULATOR_URL,
})

Passport.js

import { OIDCStrategy } from 'passport-azure-ad'

const MICROSOFT_URL = process.env.MICROSOFT_EMULATOR_URL ?? 'https://login.microsoftonline.com'

new OIDCStrategy({
  identityMetadata: `${MICROSOFT_URL}/.well-known/openid-configuration`,
  clientID: process.env.MICROSOFT_CLIENT_ID,
  clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
  redirectUrl: 'http://localhost:3000/api/auth/callback/microsoft-entra-id',
  responseType: 'code',
  responseMode: 'query',
  scope: ['openid', 'email', 'profile'],
}, verifyCallback)

MSAL.js

import { ConfidentialClientApplication } from '@azure/msal-node'

const msalConfig = {
  auth: {
    clientId: process.env.MICROSOFT_CLIENT_ID,
    clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
    authority: process.env.MICROSOFT_EMULATOR_URL,
    knownAuthorities: [process.env.MICROSOFT_EMULATOR_URL],
  },
}

const cca = new ConfidentialClientApplication(msalConfig)

Seed Config

microsoft:
  users:
    - email: testuser@outlook.com
      name: Test User
      given_name: Test
      family_name: User
      tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad
  oauth_clients:
    - client_id: example-client-id
      client_secret: example-client-secret
      name: My Microsoft App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/microsoft-entra-id
      tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad

When no OAuth clients are configured, the emulator accepts any client_id. With clients configured, strict validation is enforced for client_id, client_secret, and redirect_uri.

API Endpoints

OIDC Discovery

# Default tenant
curl http://localhost:4005/.well-known/openid-configuration

# Tenant-scoped (common, organizations, consumers, or specific tenant ID)
curl http://localhost:4005/common/v2.0/.well-known/openid-configuration

Returns the standard OIDC discovery document:

{
  "issuer": "http://localhost:4005/{tenant}/v2.0",
  "authorization_endpoint": "http://localhost:4005/oauth2/v2.0/authorize",
  "token_endpoint": "http://localhost:4005/oauth2/v2.0/token",
  "userinfo_endpoint": "http://localhost:4005/oidc/userinfo",
  "end_session_endpoint": "http://localhost:4005/oauth2/v2.0/logout",
  "jwks_uri": "http://localhost:4005/discovery/v2.0/keys",
  "response_types_supported": ["code"],
  "subject_types_supported": ["pairwise"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "scopes_supported": ["openid", "email", "profile", "User.Read", "offline_access"],
  "token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"]
}

JWKS

curl http://localhost:4005/discovery/v2.0/keys

Returns an RSA public key (kid: emulate-microsoft-1) for verifying id_token signatures.

Authorization

# Browser flow: redirects to a user picker page
curl -v "http://localhost:4005/oauth2/v2.0/authorize?\
client_id=example-client-id&\
redirect_uri=http://localhost:3000/api/auth/callback/microsoft-entra-id&\
scope=openid+email+profile&\
response_type=code&\
state=random-state&\
nonce=random-nonce"

Query parameters:

ParamDescription
client_idOAuth client ID
redirect_uriCallback URL
scopeSpace-separated scopes (openid email profile User.Read)
stateOpaque state for CSRF protection
nonceNonce for ID token (optional)
response_modequery (default) or form_post
code_challengePKCE challenge (optional)
code_challenge_methodplain or S256 (optional)

Token Exchange

curl -X POST http://localhost:4005/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=<authorization_code>&\
client_id=example-client-id&\
client_secret=example-client-secret&\
redirect_uri=http://localhost:3000/api/auth/callback/microsoft-entra-id&\
grant_type=authorization_code"

Returns:

{
  "access_token": "microsoft_...",
  "refresh_token": "r_microsoft_...",
  "id_token": "<jwt>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid email profile"
}

The id_token is an RS256 JWT containing sub, oid, tid (tenant ID), email, name, preferred_username, ver ("2.0"), and optional nonce.

For PKCE, include code_verifier in the token request.

Supports Authorization: Basic header with base64-encoded client_id:client_secret as an alternative to body parameters.

Client Credentials

curl -X POST http://localhost:4005/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=example-client-id&\
client_secret=example-client-secret&\
grant_type=client_credentials&\
scope=https://graph.microsoft.com/.default"

Returns an access_token only (no refresh_token or id_token).

Refresh Token

curl -X POST http://localhost:4005/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "refresh_token=r_microsoft_...&\
client_id=example-client-id&\
grant_type=refresh_token"

Returns a new access_token, rotated refresh_token, and new id_token.

User Info

curl http://localhost:4005/oidc/userinfo \
  -H "Authorization: Bearer microsoft_..."

Returns:

{
  "sub": "<oid>",
  "email": "testuser@outlook.com",
  "name": "Test User",
  "given_name": "Test",
  "family_name": "User",
  "preferred_username": "testuser@outlook.com"
}

Microsoft Graph /me

curl http://localhost:4005/v1.0/me \
  -H "Authorization: Bearer microsoft_..."

Returns an OData-style response:

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "displayName": "Test User",
  "mail": "testuser@outlook.com",
  "userPrincipalName": "testuser@outlook.com",
  "id": "<oid>"
}

Logout

curl "http://localhost:4005/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000"

Redirects to the post_logout_redirect_uri if provided and valid.

Token Revocation

curl -X POST http://localhost:4005/oauth2/v2.0/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=microsoft_..."

Returns 200 OK. The token is removed from the emulator's token map.

Common Patterns

Full Authorization Code Flow

MICROSOFT_URL="http://localhost:4005"
CLIENT_ID="example-client-id"
CLIENT_SECRET="example-client-secret"
REDIRECT_URI="http://localhost:3000/api/auth/callback/microsoft-entra-id"

# 1. Open in browser (user picks a seeded account)
#    $MICROSOFT_URL/oauth2/v2.0/authorize?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid+email+profile&response_type=code&state=abc

# 2. After user selection, emulator redirects to:
#    $REDIRECT_URI?code=<code>&state=abc

# 3. Exchange code for tokens
curl -X POST $MICROSOFT_URL/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=<code>&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code"

# 4. Fetch user info with the access_token
curl $MICROSOFT_URL/oidc/userinfo \
  -H "Authorization: Bearer <access_token>"

PKCE Flow

CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43)
CODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | base64 | tr -d '=' | tr '+/' '-_')

# 1. Authorize with challenge
# $MICROSOFT_URL/oauth2/v2.0/authorize?...&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256

# 2. Token exchange with verifier
curl -X POST $MICROSOFT_URL/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=<code>&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code&code_verifier=$CODE_VERIFIER"

OIDC Discovery-Based Setup

Libraries that support OIDC discovery can auto-configure from the discovery document:

import { Issuer } from 'openid-client'

const microsoftIssuer = await Issuer.discover(
  process.env.MICROSOFT_EMULATOR_URL ?? 'https://login.microsoftonline.com/common/v2.0'
)

const client = new microsoftIssuer.Client({
  client_id: process.env.MICROSOFT_CLIENT_ID,
  client_secret: process.env.MICROSOFT_CLIENT_SECRET,
  redirect_uris: ['http://localhost:3000/api/auth/callback/microsoft-entra-id'],
})

vercel tarafından daha fazla skill

benchmark-sandbox
vercel
Vercel Sandbox'larda vercel-plugin eval senaryolarını çalıştırır, yerel WezTerm panelleri yerine. Claude Code ve önceden yüklenmiş plugin ile geçici mikroVM'ler sağlar,…
official
emil-design-eng
vercel
Bu beceri, Emil Kowalski'nin UI cilası, bileşen tasarımı, animasyon kararları ve yazılımı harika hissettiren görünmez detaylar üzerine felsefesini kodlar.
official
vercel-react-best-practices
vercel
Vercel Mühendisliği'nden React ve Next.js performans optimizasyonu yönergeleri. Bu yetenek, React/Next.js yazarken, gözden geçirirken veya yeniden düzenlerken kullanılmalıdır…
official
vercel-react-best-practices
vercel
Vercel Mühendisliği'nden React ve Next.js performans optimizasyonu yönergeleri. Bu yetenek, React/Next.js yazarken, gözden geçirirken veya yeniden düzenlerken kullanılmalıdır…
official
write-guide
vercel
Gerçek dünya kullanım senaryosunu aşamalı örneklerle öğreten bir teknik rehber oluşturur. Kavramlar yalnızca okuyucunun ihtiyaç duyduğu anda tanıtılır.
official
release
vercel
Vercel eklentisini yayınla — gate’leri çalıştır, sürümü yükselt, yapıtlar oluştur, commit yap ve push’la. "Yayınla", "gönder", "yükselt ve push’la" veya "sürüm kes" dendiğinde kullan.
official
deepsec
vercel
dev3000'den bir Vercel proje kontrolüne karşı DeepSec çalıştırın. Tek tıklamayla DeepSec kurulumu, proje bağlamı başlatma, sınırlı ilk geçiş işleme ve… için kullanın.
official
backport-pr
vercel
Birleştirilmiş Next.js çekme isteğini canary'den next-16-2 gibi önceki bir sürüm dalına geri taşı. Kullanıcı geri taşıma, kiraz toplama veya bir… açma talebinde bulunduğunda kullan.
official