Pour vous connecter avec Microsoft Entra ID (anciennement Azure Active Directory) dans une Capacitor application, inscrivez-vous pour un client public dans le centre d'administration Entra, ajoutez un Applications mobiles et de bureau URI de redirection tel que com.example.app://oauth/azure, et exécutez le flux d'autorisation OpenID Connect code avec PKCE à travers le navigateur système. @capgo/capacitor-social-login ce qui signifie une initialize appeler avec les points de terminaison de la plateforme d'identité Microsoft v2.0 SocialLogin.login({ provider: 'oauth2', options: { providerId: 'azure' } }).
Cette guide couvre l'enregistrement de l'application, la sélection de l'autorité appropriée, le Graph et les champs de portée personnalisés API, la validation des jetons, l'accès conditionnel, la déconnexion et les erreurs AADSTS que vous verrez. Il s'adresse Capacitor 8 en octobre 2026.
Ce dont vous avez besoin
- Un locataire Microsoft Entra et un rôle qui peut créer des enregistrements d'application (développeur d'application ou supérieur).
- Une application Capacitor 8 et ses
appId, que vous reutiliserez comme schéma de redirection. - Optionnellement, un backend API qui doit accepter les jetons Entra.
Pourquoi pas utiliser MSAL.js dans la vue WebView ?
MSAL.js est conçu pour les navigateurs qui possèdent leur origine et peuvent ouvrir des pop-ups. Dans une vue WebView Capacitor, l'origine est capacitor://localhost sur iOS et https://localhost sur Android, les pop-ups sont bloqués, et un redirigeant de page complète ferait dériver votre application loin de son propre bundle. La guidance de Microsoft pour les applications natives est le navigateur système avec PKCE (RFC 8252), ce que fait le plugin :
| Plateforme | Navigateur utilisé | Extra setup |
|---|---|---|
| iOS | ASWebAuthenticationSession |
Aucune |
| Android | Chrome Custom Tabs avec androidUseCustomTabs: true |
Filtre d'intention |
| Web | Pop-up ou redirige | URI de redirection SPA |
On Android, activez les onglets personnalisés. La vue Web intégrée par défaut ne peut pas communiquer avec Microsoft Authenticator, les mots de passe ou le portail de l'entreprise, sur lesquels l'accès conditionnel repose souvent.
Étape 1 : Enregistrer l'application dans Entra ID
- Ouvrez Centre d'administration d'Entra Microsoft et allez à Entra ID > Inscriptions d'applications > Nouvelle inscription.
- Entrez un nom, tel que « Exemple Mobile ».
- Sélectionnez Types de comptes pris en charge. Cela décide de l'autorité que vous utiliserez ensuite.
- Cliquez pour passer à l'étape suivante Inscrivez-vous.
- On Vue d'ensemble, copiez ID d'application (client) et ID de répertoire (locataire).
Sélectionnez l'autorité
| Type de compte lors de l'inscription | Ségment d'autorité dans les URL |
|---|---|
| Locataire unique (seulement votre entreprise) | Votre ID de locataire, par exemple 8f1c... |
| Tout répertoire organisationnel | organizations |
| Tout répertoire d'entreprise plus les comptes Microsoft personnels | common |
| Seuls les comptes Microsoft personnels | consumers |
Utilisez l'ID de locataire chaque fois que possible. Il produit des émetteurs prévisibles et évite les connexions accidentelles provenant d'autres locataires.
Ajoutez les URIs de redirection
Allez à Authentification > Ajoutez une plateforme:
- Applications mobiles et de bureau: ajoutez
com.example.app://oauth/azurecomme une URI de redirection personnalisée. Ajoutezcom.example.app://oauth/logoutsi vous souhaitez une redirection après déconnexion. - Application unique en page (seulement si vous envoyez une build web) : ajoutez
https://app.example.com/auth/callback.
Ne vous inscrivez pas l'URI mobile sous Web. Les plateformes web redirigent des clients confidentiels et nécessitent un secret à l'endpoint de jeton.
Les autorisations API
Les autorisations API contient déjà Microsoft Graph > User.Read. Ajoutez offline_access, openid, profile et email if they are not listed. Some tenants block user consent. In that case an admin must click Accordez le consentement administrateur, sinon les utilisateurs voient AADSTS65001 ou un écran "Besoin d'approbation administrative".
Exposez un champ d'accès pour votre propre API (facultatif)
Si votre serveur backend doit accepter le jeton :
- Ouvrir Exposez un API et définissez l'ID d'application URI, généralement
api://<client-id>. - Ajoutez un champ nommé
access_as_user, who can consent: Admins and users. - Dans Dans le fichier, définissez
"requestedAccessTokenVersion": 2afin que les jetons d'accès utilisent la forme d'émetteur v2.0.
Étape 2 : Installez le plugin et ajoutez le filtre d'intention
bun add @capgo/capacitor-social-login
bunx cap sync
In android/app/src/main/AndroidManifest.xml, à l'intérieur MainActivity:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.example.app" android:host="oauth" />
</intent-filter>
Maintenez android:launchMode="singleTask" sur MainActivity (la valeur par défaut de Capacitor. Si vous ne utilisez pas Google, Apple ou Facebook pour vous connecter, désactivez-les sous plugins.SocialLogin.providers in capacitor.config.ts pour garder leurs SDKs hors de la construction.
Étape 3 : Initialiser le fournisseur Entra ID
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
const TENANT = 'YOUR_TENANT_ID'; // or organizations / common
const AUTHORITY = `https://login.microsoftonline.com/${TENANT}/oauth2/v2.0`;
const isWeb = Capacitor.getPlatform() === 'web';
export async function initAuth() {
await SocialLogin.initialize({
oauth2: {
azure: {
appId: 'YOUR_CLIENT_ID',
authorizationBaseUrl: `${AUTHORITY}/authorize`,
accessTokenEndpoint: `${AUTHORITY}/token`,
redirectUrl: isWeb
? 'https://app.example.com/auth/callback'
: 'com.example.app://oauth/azure',
scope: 'openid profile email offline_access User.Read',
pkceEnabled: true,
resourceUrl: 'https://graph.microsoft.com/v1.0/me',
logoutUrl: `${AUTHORITY}/logout`,
postLogoutRedirectUrl: isWeb ? 'https://app.example.com/' : 'com.example.app://oauth/logout',
androidUseCustomTabs: true,
},
},
});
}
context resourceUrl pointant vers le Graph /meAprès l'authentification, le plugin appelle directement Graph et renvoie le profil dans resourceData.
Si vous êtes en train de migrer depuis Ionic Auth Connect, SocialLoginAuthConnect possède une azure préconfiguration qui ne nécessite que tenantId, clientId et redirectUrl. Consultez la page d'intégration Entra ID.
Étape 4 : S'identifier
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function signInWithMicrosoft() {
try {
const { result } = await SocialLogin.login({
provider: 'oauth2',
options: { providerId: 'azure' },
});
const me = result.resourceData as {
id: string;
displayName?: string;
mail?: string | null;
userPrincipalName?: string;
} | null;
return {
idToken: result.idToken,
graphToken: result.accessToken?.token,
refreshToken: result.refreshToken,
user: me,
};
} catch (error: any) {
if (error?.code === 'USER_CANCELLED') return null;
throw error;
}
}
Options utiles :
loginHint: 'jane@contoso.com'remplit automatiquement le compte et saute le sélectionneur de compte pour cet utilisateur.prompt: 'select_account'affiche toujours le sélectionneur de compte, utile pour les appareils partagés.additionalParameters: { domain_hint: 'contoso.com' }envoie les utilisateurs directement vers leur identifiant fédéré.
mail est souvent null pour les comptes sans boîte aux lettres. Retourner à userPrincipalName ou le preferred_username revendication du jeton d'ID.
Étape 5 : Appelez Microsoft Graph
export async function getMyPhotoBlob(graphToken: string) {
const res = await fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {
headers: { Authorization: `Bearer ${graphToken}` },
});
if (res.status === 404) return null; // no photo set
if (!res.ok) throw new Error(`Graph error ${res.status}`);
return res.blob();
}
Ajoutez chaque champ Graph dont vous avez besoin (par exemple Calendars.Read) les deux permissions d'API et dans le scope et dans la
Étape 6 : Obtenez un jeton pour votre propre API
Un jeton d'accès cible un seul ressource. Pour appeler votre backend, ajoutez une deuxième entrée à côté azure dans le même oauth2 carte de votre initialize appelez, en demandant votre API champ d'application au lieu de Graph :
await SocialLogin.initialize({
oauth2: {
azure: graphConfig, // the object from step 3, moved into a const
azureApi: {
appId: 'YOUR_CLIENT_ID',
authorizationBaseUrl: `${AUTHORITY}/authorize`,
accessTokenEndpoint: `${AUTHORITY}/token`,
redirectUrl: 'com.example.app://oauth/azure-api', // register this URI too
scope: 'openid profile offline_access api://YOUR_CLIENT_ID/access_as_user',
pkceEnabled: true,
androidUseCustomTabs: true,
},
},
});
L’utilisateur a déjà une session Microsoft, donc la deuxième connexion se termine généralement sans invitation. Validez le jeton sur le serveur :
import { createRemoteJWKSet, jwtVerify } from 'jose';
const TENANT_ID = 'YOUR_TENANT_ID';
const jwks = createRemoteJWKSet(
new URL(`https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys`),
);
export async function verifyEntraToken(token: string) {
const { payload } = await jwtVerify(token, jwks, {
issuer: `https://login.microsoftonline.com/${TENANT_ID}/v2.0`,
audience: 'YOUR_CLIENT_ID', // v2 tokens use the client ID as aud
});
if (!String(payload.scp ?? '').split(' ').includes('access_as_user')) {
throw new Error('Missing scope');
}
return payload; // payload.oid is the stable user object ID
}
Pour les applications multilocataires, l'émetteur contient l'ID de locataire de chaque client. Vérifiez que tid acceptez la liste des locataires au lieu d'un émetteur fixe. Les utilisateurs clés sur oid plus tidÉtape 7 : Raffraîchir et se déconnecter
Étape 7 : Raffraîchir et se déconnecter
// Get a valid Graph token, refreshing it when it has expired
export async function getGraphToken() {
const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'azure' });
if (!isLoggedIn) {
try {
await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'azure' } });
} catch {
// no session, or the refresh token expired or was revoked
const loginResult = await signInWithMicrosoft();
if (!loginResult) throw new Error('Sign-in cancelled');
}
}
const { accessToken } = await SocialLogin.getAuthorizationCode({ provider: 'oauth2', providerId: 'azure' });
return accessToken;
}
// Sign out
await SocialLogin.logout({ provider: 'oauth2', providerId: 'azure' });
Entra refresh tokens for public clients last up to 90 days with a sliding window and are replaced on each use. The plugin stores the new one. If you store tokens yourself, use the Keychain or Keystore, for example NativeBiometric.setData from @capgo/capacitor-native-biometriqueet les passez à SocialLogin.refreshToken.
logout clears local tokens and opens the v2.0 logout endpoint in the system browser. Microsoft sometimes shows a “You signed out of your account” page instead of redirecting to a custom scheme, so the user may have to close it. If you only need a local logout, drop logoutUrl et passer prompt: 'select_account' à l'entrée suivante.
Accès conditionnel et Intune
Le travail avec les politiques d'accès conditionnel et les authentifications à plusieurs facteurs nécessite une attention particulière.
- Appareil conforme ou joint hybride: Entra doit voir l'état de l'appareil. Sur les appareils Android, cela fonctionne à travers les onglets personnalisés lorsque le Portail de l'entreprise ou l'Authentificateur est installé. Sur les appareils iOS gérés, le plug-in SSO d'entreprise Microsoft déployé par votre MDM fournit cela. Testez cela tôt avec une politique réelle.
- Politiques de protection des applications Intune (MAM): ces exigent l'application Intune SDK à l'intérieur de l'application native. L’OIDC seul ne satisfait pas aux « exiger une politique de protection d'application ».
Troubleshooting
| Error | Erreur | Fix |
|---|---|---|
| AADSTS50011 | URI de redirection incohérent | Ajoutez l'URI exacte sous Applications mobiles et desktop |
| AADSTS7000218 | La demande de jeton nécessite un secret | La redirection a été enregistrée sous Web. Déplacez-la sous Applications mobiles et desktop |
| AADSTS9002326 | Seul le rachat de jetons d'origine autorisé pour les applications SPA | La build Web utilise une redirection mobile. Enregistrez l'URL Web sous Application à page unique |
| AADSTS700016 | L'application n'est pas trouvée dans le répertoire | Erreur de locataire dans l'autorité, ou application mono-locataire utilisée avec common |
| AADSTS50020 | Compte d'utilisateur provenant d'un autre locataire | Utiliser une inscription multilocataire, ou inviter l'utilisateur en tant que invité |
| AADSTS65001 | Consentement non accordé | Grant admin consent or allow user consent |
| AADSTS53003 | Bloqué par l'accès conditionnel | Vérifier les journaux de connexion, voir la section ci-dessus |
| AADSTS28000 | Étendues pour plus d'un ressource dans une seule demande | Demander les graphiques et vos étendues API séparément dans des connexions |
| No token de rafraîchissement | offline_access manquant |
Ajoutez-l’aux champs d'accès et aux autorisations |
Le centre d'administration Entra Les journaux de connexion montrent la raison exacte d'échec pour chaque tentative, et logsEnabled: true dans la configuration du plugin, imprimez l'URL d'autorisation et la réponse de jeton sur le dispositif.
Actualités de livraison
Policy changes on the Entra side are instant, but client-side fixes still need to reach devices. TypeScript changes such as scopes or error handling can ship through Capgo mises à jour en directNative changes (intent filters, nouveaux schémas) nécessitent une nouvelle mise à jour de l'application, qui Capgo Construction peut produire sans un Mac local.