S'authentifier à l'aide de Microsoft sur des plates-formes Apple

Vous pouvez permettre à vos utilisateurs de s'authentifier auprès de Firebase à l'aide de fournisseurs OAuth tels que Microsoft Azure Active Directory en intégrant une connexion OAuth générique basée sur le Web dans votre application à l'aide du SDK Firebase pour effectuer la procédure de connexion de bout en bout.

Avant de commencer

Pour permettre aux utilisateurs de se connecter à l'aide de comptes Microsoft (Azure Active Directory et comptes Microsoft personnels), vous devez d'abord activer Microsoft en tant que fournisseur de connexion pour votre projet Firebase :

  1. Ajoutez Firebase à votre projet Apple.
  2. Dans la console Firebase, ouvrez la section Authentification.
  3. Dans l'onglet Méthode de connexion, activez le fournisseur Microsoft.
  4. Ajoutez l'ID client et le code secret du client de la console de développement du fournisseur à la configuration du fournisseur :
    1. Pour enregistrer un client OAuth Microsoft, suivez les instructions de la section Démarrage rapide : enregistrer une application avec le point de terminaison Azure Active Directory v2.0. Notez que ce point de terminaison prend en charge la connexion à l'aide de comptes personnels Microsoft ainsi que d'Azure comptes Active Directory. En savoir plus sur Azure Active Directory v2.0
    2. Lorsque vous enregistrez des applications auprès de ces fournisseurs, veillez à enregistrer le domaine *.firebaseapp.com de votre projet en tant que domaine de redirection de votre application.
  5. Cliquez sur Enregistrer.

Gérer le flux de connexion avec le SDK Firebase

Pour gérer le flux de connexion avec le SDK Firebase pour les plates-formes Apple, procédez comme suit :

  1. Ajoutez des schémas d'URL personnalisés à votre projet Xcode :

    1. Ouvrez la configuration de votre projet : double-cliquez sur le nom du projet dans l'arborescence de gauche. Sélectionnez votre application dans la section TARGETS, puis sélectionnez l'onglet Infos et développez la section Types d'URL.
    2. Cliquez sur le bouton +, puis ajoutez votre ID d'application encodé en tant qu'URL. d'un schéma. Vous trouverez votre ID d'application encodé sur la page Paramètres généraux de la console Firebase, dans la section de votre application iOS. Laissez les autres champs vides.

      Une fois l'opération terminée, votre configuration doit ressembler à l'exemple (mais avec les valeurs propres à votre application):

      Capture d'écran de l'interface de configuration du schéma d'URL personnalisé d'Xcode
  2. Créez une instance d'un OAuthProvider à l'aide de l'ID de fournisseur microsoft.com.

        var provider = OAuthProvider(providerID: "microsoft.com")
        
        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"microsoft.com"];
        
  3. Facultatif : spécifiez des paramètres OAuth personnalisés supplémentaires que vous souhaitez envoyer avec la requête OAuth.

        provider.customParameters = [
          "prompt": "consent",
          "login_hint": "user@firstadd.onmicrosoft.com"
        ]
        
        [provider setCustomParameters:@{@"prompt": @"consent", @"login_hint": @"user@firstadd.onmicrosoft.com"}];
        

    Pour connaître les paramètres compatibles avec Microsoft, consultez les Documentation Microsoft OAuth Notez que vous ne pouvez pas transmettre de paramètres requis par Firebase avec setCustomParameters. Ces paramètres sont client_id, response_type, redirect_uri, state, scope et response_mode.

    Pour autoriser uniquement les utilisateurs d'un locataire Azure AD particulier à signer dans l'application, soit le nom de domaine convivial du locataire Azure AD ou l'identifiant GUID du locataire peut être utilisé. Pour ce faire, spécifiez le "locataire" de l'objet des paramètres personnalisés.

        provider.customParameters = [
          // Optional "tenant" parameter in case you are using an Azure AD
          // tenant. eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
          // 'contoso.onmicrosoft.com' or "common" for tenant-independent
          // tokens. The default value is "common".
          "tenant": "TENANT_ID"
        ]
        
        // Optional "tenant" parameter in case you are using an Azure AD tenant.
        // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
        // 'contoso.onmicrosoft.com' or "common" for tenant-independent tokens.
        // The default value is "common".
        provider.customParameters = @{@"tenant": @"TENANT_ID"};
        
  4. Facultatif: spécifiez des champs d'application OAuth 2.0 supplémentaires en plus du profil de base pour lequel que vous souhaitez demander au fournisseur d'authentification.

        provider.scopes = ["mail.read", "calendars.read"]
        
        [provider setScopes:@[@"mail.read", @"calendars.read"]];
        

    Pour en savoir plus, consultez la documentation Microsoft sur les autorisations et le consentement.

  5. Facultatif: Si vous souhaitez personnaliser la façon dont votre application présente les SFSafariViewController ou UIWebView lorsque présentant le reCAPTCHA à l'utilisateur, créez une classe personnalisée au protocole AuthUIDelegate, puis le transmettre à credentialWithUIDelegate

  6. Authentifiez-vous avec Firebase à l'aide de l'objet du fournisseur OAuth.

        // Replace nil with the custom class that conforms to AuthUIDelegate
        // you created in last step to use a customized web view.
        provider.getCredentialWith(nil) { credential, error in
          if error != nil {
            // Handle error.
          }
          if credential != nil {
            Auth().signIn(with: credential) { authResult, error in
              if error != nil {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // OAuth access token can also be retrieved:
              // (authResult.credential as? OAuthCredential)?.accessToken
              // OAuth ID token can also be retrieved:
              // (authResult.credential as? OAuthCredential)?.idToken
            }
          }
        }
        
        [provider getCredentialWithUIDelegate:nil
                                   completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
          if (error) {
           // Handle error.
          }
          if (credential) {
            [[FIRAuth auth] signInWithCredential:credential
                                      completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
              if (error) {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // OAuth access token can also be retrieved:
              // ((FIROAuthCredential *)authResult.credential).accessToken
              // OAuth ID token can also be retrieved:
              // ((FIROAuthCredential *)authResult.credential).idToken
            }];
          }
        }];
        

    Avec le jeton d'accès OAuth, vous pouvez appeler la méthode API Microsoft Graph :

    Par exemple, pour obtenir des informations de base sur le profil, vous pouvez appeler l'API REST en transmettant le jeton d'accès dans l'en-tête Authorization :

    https://graph.microsoft.com/v1.0/me

    Contrairement aux autres fournisseurs compatibles avec Firebase Auth, fournir une URL de photo. À la place, les données binaires d'une photo de profil doivent être demandé par API Microsoft Graph :

    En plus du jeton d'accès OAuth, l'authentification OAuth Jeton d'ID peut également être récupérée à partir de l'objet OAuthCredential. La revendication sub dans le jeton d'identification est spécifique à l'application et ne correspond pas à l'identifiant utilisateur fédéré utilisé par Firebase Auth et accessible via user.providerData[0].uid. Le champ de revendication oid doit être utilisé à la place. Lorsque vous utilisez un locataire Azure AD pour vous connecter, la revendication oid correspond exactement. Toutefois, dans le cas des non locataires, le champ oid est rempli. Pour un ID fédéré 4b2eabcdefghijkl, oid aura la forme 00000000-0000-0000-4b2e-abcdefghijkl.

  7. Si les exemples ci-dessus se concentrent sur les procédures de connexion, possibilité d'associer un fournisseur Microsoft à un utilisateur existant à l'aide de linkWithCredential Par exemple, vous pouvez associer plusieurs au même utilisateur, ce qui leur permet de se connecter avec l'un ou l'autre.

        Auth().currentUser.link(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // Microsoft credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
        
        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // Microsoft credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
        
  8. Le même modèle peut être utilisé avec reauthenticateWithCredential, qui permet de récupérer de nouvelles identifiants pour les opérations sensibles qui nécessitent une connexion récente.

        Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // Additional OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
        
        [[FIRAuth auth].currentUser
            reauthenticateWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // Additional OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
        

Si vous avez activé le paramètre Un seul compte par adresse e-mail dans la console Firebase : lorsqu'un utilisateur tente de se connecter à un fournisseur (Microsoft, par exemple) avec une adresse e-mail déjà existe pour le fournisseur d'un autre utilisateur Firebase (tel que Google), l'erreur FIRAuthErrorCodeAccountExistsWithDifferentCredential est généré avec un message Objet FIRAuthCredential (identifiant Microsoft). Pour terminer la connexion au fournisseur souhaité, l'utilisateur doit d'abord se connecter au fournisseur existant (Google), puis l'associer à l'ancien FIRAuthCredential (identifiant Microsoft). Cela se présente comme suit :

  // Sign-in with an OAuth credential.
  provider.getCredentialWith(nil) { credential, error in
    // An account with the same email already exists.
    if (error as NSError?)?.code == AuthErrorCode.accountExistsWithDifferentCredential.rawValue {
      // Get pending credential and email of existing account.
      let existingAcctEmail = (error! as NSError).userInfo[AuthErrorUserInfoEmailKey] as! String
      let pendingCred = (error! as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as! AuthCredential
      // Lookup existing account identifier by the email.
      Auth.auth().fetchProviders(forEmail:existingAcctEmail) { providers, error in
        // Existing email/password account.
        if (providers?.contains(EmailAuthProviderID))! {
          // Existing password account for email. Ask user to provide the password of the
          // existing account.
          // Sign in with existing account.
          Auth.auth().signIn(withEmail:existingAcctEmail, password:password) { user, error in
            // Successfully signed in.
            if user != nil {
              // Link pending credential to account.
              Auth.auth().currentUser?.linkAndRetrieveData(with: pendingCred) { result, error in
                // ...
              }
            }
          }
        }
      }
      return
    }

    // Other errors.
    if error != nil {
      // handle the error.
      return
    }

    // Sign in with the credential.
    if credential != nil {
      Auth.auth().signInAndRetrieveData(with: credential!) { result, error in
        if error != nil {
          // handle the error.
          return
        }
      }
    }
  }

  
  // Sign-in with an OAuth credential.
  [provider getCredentialWithUIDelegate:nil
                             completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
    // An account with the same email already exists.
    if (error.code == FIRAuthErrorCodeAccountExistsWithDifferentCredential) {
      // Get pending credential and email of existing account.
      NSString *existingAcctEmail = error.userInfo[FIRAuthErrorUserInfoEmailKey];
      FIRAuthCredential *pendingCred = error.userInfo[FIRAuthErrorUserInfoUpdatedCredentialKey];
      // Lookup existing account identifier by the email.
      [[FIRAuth auth] fetchProvidersForEmail:existingAcctEmail
                                 completion:^(NSArray<NSString *> *_Nullable providers,
                                              NSError *_Nullable error) {
        // Existing email/password account.
        if ( [providers containsObject:FIREmailAuthProviderID] ) {
          // Existing password account for email. Ask user to provide the password of the
          // existing account.

          // Sign in with existing account.
          [[FIRAuth auth] signInWithEmail:existingAcctEmail
                                 password:password
                               completion:^(FIRUser *user, NSError *error) {
            // Successfully signed in.
            if (user) {
              // Link pending credential to account.
              [[FIRAuth auth].currentUser linkWithCredential:pendingCred
                                                  completion:^(FIRUser *_Nullable user,
                                                               NSError *_Nullable error) {
                // ...
              }];
            }
          }];
        }
      }];
      return;
    }

    // Other errors.
    if (error) {
      // handle the error.
      return;
    }

    // Sign in with the credential.
    if (credential) {
      [[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
          completion:^(FIRAuthDataResult *_Nullable authResult,
                       NSError *_Nullable error) {
        if (error) {
          // handle the error.
          return;
        }
      }];
    }
  }];
  

Contrairement aux autres fournisseurs OAuth compatibles avec Firebase, et Twitter, où la connexion se fait directement à l'aide d'un jeton d'accès OAuth à l'aide d'identifiants basés sur des requêtes, Firebase Auth ne permet pas de fournisseurs tiers tels que Microsoft, en raison de l'incapacité du Serveur d'authentification pour vérifier l'audience des jetons d'accès Microsoft OAuth. Il s'agit d'une exigence de sécurité critique qui peut exposer les applications sites Web de rejouer les attaques où un jeton d'accès Microsoft OAuth a été obtenu pour un projet (attaquant) peut être utilisé pour se connecter à un autre projet (victime). Firebase Auth permet de gérer l'intégralité du flux OAuth l'échange du code d'autorisation à l'aide de l'ID et du code secret du client OAuth. configurés dans la console Firebase. Comme le code d'autorisation ne peut être utilisé qu'avec un ID client/secret spécifique, un code d'autorisation obtenu pour un projet ne peut pas être utilisé avec un autre.

Si vous devez utiliser ces fournisseurs dans des environnements non compatibles, vous devez utiliser une bibliothèque OAuth tierce et l'authentification personnalisée Firebase. Le premier est nécessaire pour s'authentifier auprès du fournisseur et le second pour échanger les identifiants du fournisseur contre un jeton personnalisé.

Lorsqu'un utilisateur se connecte pour la première fois, un compte utilisateur est créé et associé aux identifiants (nom et mot de passe de l'utilisateur, numéro de téléphone ou informations du fournisseur d'authentification) avec lesquels l'utilisateur s'est connecté. Ce nouveau compte est stocké dans votre projet Firebase et peut être utilisé pour identifier un utilisateur dans toutes les applications de votre projet, quelle que soit la manière dont il se connecte.

  • Dans vos applications, vous pouvez obtenir les informations de base du profil de l'utilisateur à partir des User . Consultez Gérer les utilisateurs.

  • Dans vos règles de sécurité Firebase Realtime Database et Cloud Storage, vous pouvez obtenir l'ID utilisateur unique de l'utilisateur connecté à partir de la variable auth et l'utiliser pour contrôler les données auxquelles un utilisateur peut accéder.

Vous pouvez autoriser les utilisateurs à se connecter à votre appli à l'aide de plusieurs authentifications fournisseurs en associant leurs identifiants compte utilisateur existant.

Pour déconnecter un utilisateur, appelez . signOut:.

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Vous pouvez également ajouter du code de gestion des erreurs pour l'ensemble des erreurs d'authentification. Consultez la section Gérer les erreurs.