S'authentifier avec OpenID Connect sur Android

Si vous êtes passé à Firebase Authentication with Identity Platform, vous pouvez authentifier vos utilisateurs avec Firebase en utilisant le fournisseur compatible OIDC (OpenID Connect) de votre choix. Ce permet d'utiliser des fournisseurs d'identité non compatibles de manière native avec Firebase.

Avant de commencer

Pour connecter des utilisateurs à l'aide d'un fournisseur OIDC, vous devez d'abord collecter certaines informations auprès du fournisseur :

  • ID client : chaîne propre au fournisseur qui identifie votre application. Votre fournisseur peut vous attribuer un ID client différent pour chaque plate-forme que vous prenez en charge. Il s'agit de l'une des valeurs de la revendication aud dans les jetons d'identification émis par votre un fournisseur de services agréé.

  • Code secret du client: chaîne secrète utilisée par le fournisseur pour confirmer la propriété. d'un ID client. Pour chaque ID client, vous aurez besoin d'un code secret du client correspondant. (Cette valeur n'est requise que si vous utilisez le flux avec code d'autorisation, qui est fortement recommandé.)

  • Issuer (Émetteur) : chaîne qui identifie votre fournisseur. Cette valeur doit être une URL Lorsqu'on y ajoute /.well-known/openid-configuration, il s'agit de l'emplacement du document de découverte OIDC du fournisseur. Par exemple, si l'émetteur est https://auth.example.com, le document de découverte doit être disponible à l'adresse https://auth.example.com/.well-known/openid-configuration.

Une fois que vous disposez des informations ci-dessus, activez OpenID Connect en tant que connexion pour votre projet Firebase:

  1. Ajoutez Firebase à votre projet Android.

  2. Si vous n'avez pas encore migré vers Firebase Authentication with Identity Platform, faites-le. L'authentification OpenID Connect n'est disponible que dans les projets migrés.

  3. Sur la page Fournisseurs de connexion, page de la console Firebase, cliquez sur Ajouter un fournisseur, puis sur OpenID Connect.

  4. Indiquez si vous utilisez le flux avec code d'autorisation ou le flux d'attribution implicite.

    Vous devez toujours utiliser le flux de code si votre fournisseur le prend en charge. La le flux implicite est moins sécurisé et son utilisation est fortement déconseillée.

  5. Attribuez un nom à ce fournisseur. Notez l'ID du fournisseur généré : oidc.example-provider, par exemple. Vous en aurez besoin lorsque vous ajouterez de connexion à votre application.

  6. Spécifiez votre ID client et votre code secret du client, ainsi que la chaîne d'émetteur de votre fournisseur. Ces valeurs doivent correspondre exactement à celles que votre fournisseur vous a attribuées.

  7. Enregistrez les modifications.

Gérer le flux de connexion avec le SDK Firebase

Si vous développez une application Android, le moyen le plus simple d'authentifier vos utilisateurs avec Firebase avec votre fournisseur OIDC, c'est de gérer l'intégralité du processus de connexion le SDK Firebase pour Android.

Pour gérer le flux de connexion avec le SDK Firebase pour Android, procédez comme suit:

  1. Créez une instance d'un objet OAuthProvider à l'aide de son Builder avec le paramètre ID du fournisseur

    Kotlin+KTX

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");

  2. Facultatif: spécifiez les autres paramètres OAuth personnalisés que vous souhaitez avec la requête OAuth.

    Kotlin+KTX

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com")

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com");

    Vérifiez auprès de votre fournisseur OIDC pour les paramètres qu'il accepte. Notez que vous ne pouvez pas transmettre de paramètres requis par Firebase avec setCustomParameters(). Il s'agit de client_id, response_type, redirect_uri, state, scope et response_mode.

  3. 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.

    Kotlin+KTX

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    providerBuilder.scopes = listOf("mail.read", "calendars.read")

    Java

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    List<String> scopes =
            new ArrayList<String>() {
                {
                    add("mail.read");
                    add("calendars.read");
                }
            };
    providerBuilder.setScopes(scopes);

    Vérifiez auprès de votre fournisseur OIDC pour les niveaux d'accès qu'il utilise.

  4. Authentifiez-vous auprès de Firebase à l'aide de l'objet du fournisseur OAuth. Notez que contrairement d'autres FirebaseAuth des opérations, celui-ci prendra le contrôle de votre interface utilisateur en affichant Onglet Chrome personnalisé. Par conséquent, ne faites pas référence à votre activité dans OnSuccessListener. et OnFailureListener que vous joignez, car ils se dissocient immédiatement l'opération démarre l'UI.

    Commencez par vérifier si vous avez déjà reçu une réponse. Se connecter avec cette méthode place votre activité en arrière-plan, ce qui signifie qu'elle peut être récupérées par le système lors du processus de connexion. Afin de nous assurer que vous n'obligez pas l'utilisateur à réessayer dans ce cas, vérifiez si résultat est déjà présent.

    Pour vérifier s'il y a un résultat en attente, appelez getPendingAuthResult:

    Kotlin+KTX

    val pendingResultTask = firebaseAuth.pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                // The OAuth secret can be retrieved by calling:
                // ((OAuthCredential)authResult.getCredential()).getSecret().
            }
            .addOnFailureListener {
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
                .addOnSuccessListener(
                        new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                // User is signed in.
                                // IdP data available in
                                // authResult.getAdditionalUserInfo().getProfile().
                                // The OAuth access token can also be retrieved:
                                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                                // The OAuth secret can be retrieved by calling:
                                // ((OAuthCredential)authResult.getCredential()).getSecret().
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Handle failure.
                            }
                        });
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Pour démarrer le flux de connexion, appelez startActivityForSignInWithProvider :

    Kotlin+KTX

    firebaseAuth
        .startActivityForSignInWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is signed in.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // ((OAuthCredential)authResult.getCredential()).getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    firebaseAuth
            .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is signed in.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // ((OAuthCredential)authResult.getCredential()).getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

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

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForLinkWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // Provider credential is linked to the current user.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // authResult.getCredential().getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // authResult.getCredential().getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Provider credential is linked to the current user.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // authResult.getCredential().getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // authResult.getCredential().getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  6. Le même modèle peut être utilisé avec startActivityForReauthenticateWithProvider, qui permet de récupérer de nouveaux identifiants pour les opérations sensibles nécessitant une connexion récente ;

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForReauthenticateWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is re-authenticated with fresh tokens and
                            // should be able to perform sensitive operations
                            // like account deletion and email or password
                            // update.
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

Gérer le flux de connexion manuellement

Si vous avez déjà implémenté la procédure de connexion OpenID Connect dans votre application, vous Vous pouvez utiliser le jeton d'ID directement pour vous authentifier auprès de Firebase:

Kotlin+KTX

val providerId = "oidc.example-provider" // As registered in Firebase console.
val credential = oAuthCredential(providerId) {
    setIdToken(idToken) // ID token from OpenID Connect flow.
}
Firebase.auth
    .signInWithCredential(credential)
    .addOnSuccessListener { authResult ->
        // User is signed in.

        // IdP data available in:
        //    authResult.additionalUserInfo.profile
    }
    .addOnFailureListener { e ->
        // Handle failure.
    }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

Étapes suivantes

Lorsqu'un utilisateur se connecte pour la première fois, un compte utilisateur est créé et associés aux identifiants, c'est-à-dire au nom d'utilisateur et au mot de passe, ou des informations sur le fournisseur d'authentification, c'est-à-dire l'utilisateur avec lequel il s'est connecté. Cette nouvelle est stocké dans votre projet Firebase et peut servir à identifier un utilisateur dans toutes les applications de votre projet, quelle que soit la façon dont l'utilisateur se connecte.

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

  • Dans votre Firebase Realtime Database et votre Cloud Storage Règles de sécurité, vous pouvez obtenez 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:

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();