Utilisation de fournisseurs OAuth avec MVC 4

par Tom FitzMacken

Ce tutoriel vous montre comment créer une application web MVC 4 ASP.NET qui permet aux utilisateurs de se connecter avec des informations d’identification à partir d’un fournisseur externe, tel que Facebook, Twitter, Microsoft ou Google, puis d’intégrer certaines des fonctionnalités de ces fournisseurs à votre application web. Par souci de simplicité, ce tutoriel se concentre sur l’utilisation des informations d’identification de Facebook.

Pour utiliser des informations d’identification externes dans une application web MVC 5 ASP.NET, consultez Créer une application MVC 5 ASP.NET avec Facebook et Google OAuth2 et OpenID Sign-on.

L’activation de ces informations d’identification dans vos sites web offre un avantage significatif, car des millions d’utilisateurs ont déjà des comptes auprès de ces fournisseurs externes. Ces utilisateurs peuvent être plus enclins à s’inscrire à votre site s’ils n’ont pas besoin de créer et de mémoriser un nouvel ensemble d’informations d’identification. En outre, une fois qu’un utilisateur s’est connecté via l’un de ces fournisseurs, vous pouvez incorporer des opérations sociales à partir du fournisseur.

Ce que vous allez créer

Ce tutoriel comporte deux objectifs main :

  1. Permettre à un utilisateur de se connecter avec les informations d’identification d’un fournisseur OAuth.
  2. Récupérez les informations de compte du fournisseur et intégrez ces informations à l’inscription du compte pour votre site.

Bien que les exemples de ce tutoriel se concentrent sur l’utilisation de Facebook comme fournisseur d’authentification, vous pouvez modifier le code pour utiliser n’importe quel fournisseur. Les étapes d’implémentation d’un fournisseur sont très similaires à celles que vous verrez dans ce tutoriel. Vous remarquerez uniquement des différences significatives lors des appels directs à l’ensemble d’API du fournisseur.

Prérequis

ou

En outre, cette rubrique suppose que vous avez des connaissances de base sur ASP.NET MVC et Visual Studio. Si vous avez besoin d’une présentation de ASP.NET MVC 4, consultez Introduction à ASP.NET MVC 4.

Créer le projet

Dans Visual Studio, créez une application web MVC 4 ASP.NET et nommez-la « OAuthMVC ». Vous pouvez cibler .NET Framework 4.5 ou 4.

créer un projet

Dans la fenêtre Nouveau projet ASP.NET MVC 4, sélectionnez Application Internet et laissez Razor comme moteur d’affichage.

sélectionnez Application Internet

Activer un fournisseur

Lorsque vous créez une application web MVC 4 avec le modèle Application Internet, le projet est créé avec un fichier nommé AuthConfig.cs dans le dossier App_Start.

Fichier AuthConfig

Le fichier AuthConfig contient du code pour inscrire des clients pour des fournisseurs d’authentification externes. Par défaut, ce code étant commenté, aucun des fournisseurs externes n’est activé.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
        // you must update this site. For more information visit https://go.microsoft.com/fwlink/?LinkID=252166

        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");

        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");

        //OAuthWebSecurity.RegisterFacebookClient(
        //    appId: "",
        //    appSecret: "");

        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

Vous devez annuler les marques de commentaire de ce code pour utiliser le client d’authentification externe. Vous supprimez les marques de commentaire uniquement les fournisseurs que vous souhaitez inclure dans votre site. Pour ce tutoriel, vous allez uniquement activer les informations d’identification Facebook.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");

        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");

        OAuthWebSecurity.RegisterFacebookClient(
            appId: "",
            appSecret: "");

        //OAuthWebSecurity.RegisterGoogleClient();        
    }
}

Notez dans l’exemple ci-dessus que la méthode inclut des chaînes vides pour les paramètres d’inscription. Si vous essayez d’exécuter l’application maintenant, l’application lève une exception d’argument, car les chaînes vides ne sont pas autorisées pour les paramètres. Pour fournir des valeurs valides, vous devez inscrire votre site web auprès des fournisseurs externes, comme indiqué dans la section suivante.

Inscription auprès d’un fournisseur externe

Pour authentifier les utilisateurs avec des informations d’identification d’un fournisseur externe, vous devez inscrire votre site web auprès du fournisseur. Lorsque vous inscrivez votre site, vous recevez les paramètres (tels que la clé ou l’ID et le secret) à inclure lors de l’inscription du client. Vous devez disposer d’un compte auprès des fournisseurs que vous souhaitez utiliser.

Ce tutoriel n’affiche pas toutes les étapes que vous devez effectuer pour vous inscrire auprès de ces fournisseurs. Les étapes ne sont généralement pas difficiles. Pour inscrire correctement votre site, suivez les instructions fournies sur ces sites. Pour commencer à inscrire votre site, consultez le site du développeur pour :

Lors de l’inscription de votre site auprès de Facebook, vous pouvez fournir « localhost » pour le domaine du site et "http://localhost/" pour l’URL, comme illustré dans l’image ci-dessous. L’utilisation de localhost fonctionne avec la plupart des fournisseurs, mais ne fonctionne actuellement pas avec le fournisseur Microsoft. Pour le fournisseur Microsoft, vous devez inclure une URL de site web valide.

inscrire le site

Dans l’image précédente, les valeurs de l’ID d’application, du secret de l’application et de l’e-mail de contact ont été supprimées. Lorsque vous inscrivez réellement votre site, ces valeurs sont présentes. Vous devez noter les valeurs de l’ID d’application et du secret d’application, car vous allez les ajouter à votre application.

Création d’utilisateurs de test

Si cela ne vous dérange pas d’utiliser un compte Facebook existant pour tester votre site, vous pouvez ignorer cette section.

Vous pouvez facilement créer des utilisateurs de test pour votre application dans la page de gestion des applications Facebook. Vous pouvez utiliser ces comptes de test pour vous connecter à votre site. Pour créer des utilisateurs de test, cliquez sur le lien Rôles dans le volet de navigation gauche, puis cliquez sur le lien Créer .

créer des utilisateurs de test

Le site Facebook crée automatiquement le nombre de comptes de test que vous demandez.

Ajout de l’ID d’application et du secret à partir du fournisseur

Maintenant que vous avez reçu l’ID et le secret de Facebook, revenez au fichier AuthConfig et ajoutez-les en tant que valeurs de paramètre. Les valeurs indiquées ci-dessous ne sont pas des valeurs réelles.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");

        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");

        //OAuthWebSecurity.RegisterFacebookClient(
        //    appId: "",
        //    appSecret: "");

        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

Se connecter avec des informations d’identification externes

C’est tout ce que vous avez à faire pour activer les informations d’identification externes dans votre site. Exécutez votre application et cliquez sur le lien de connexion dans le coin supérieur droit. Le modèle reconnaît automatiquement que vous avez inscrit Facebook en tant que fournisseur et inclut un bouton pour le fournisseur. Si vous inscrivez plusieurs fournisseurs, un bouton pour chacun d’eux est automatiquement inclus.

connexion externe

Ce tutoriel ne décrit pas comment personnaliser les boutons de connexion pour les fournisseurs externes. Pour obtenir ces informations, consultez Personnalisation de l’interface utilisateur de connexion lors de l’utilisation d’OAuth/OpenID.

Cliquez sur le bouton Facebook pour vous connecter avec les informations d’identification Facebook. Lorsque vous sélectionnez l’un des fournisseurs externes, vous êtes redirigé vers ce site et invité par ce service à vous connecter.

L’image suivante montre l’écran de connexion pour Facebook. Il note que vous utilisez votre compte Facebook pour vous connecter à un site nommé oauthmvcexample.

Authentification facebook

Après s’être connecté avec les informations d’identification Facebook, une page informe l’utilisateur que le site aura accès aux informations de base.

demander l’autorisation

Après avoir sélectionné Accéder à l’application, l’utilisateur doit s’inscrire au site. L’image suivante montre la page d’inscription une fois qu’un utilisateur s’est connecté avec les informations d’identification Facebook. Le nom d’utilisateur est généralement prérempli avec un nom du fournisseur.

Capture d’écran montrant une page Inscrire dans laquelle vous pouvez associer votre compte Facebook à cette application.

Cliquez sur Inscrire pour terminer l’inscription. Fermez le navigateur.

Vous pouvez voir que le nouveau compte a été ajouté à votre base de données. Dans Server Explorer, ouvrez la base de données DefaultConnection et ouvrez le dossier Tables.

tables de base de données

Cliquez avec le bouton droit sur la table UserProfile et sélectionnez Afficher les données de table.

afficher les données

Vous verrez le nouveau compte que vous avez ajouté. Examinez les données dans webpage_OAuthMembership table. Vous verrez plus de données liées au fournisseur externe pour le compte que vous venez d’ajouter.

Si vous souhaitez uniquement activer l’authentification externe, vous avez terminé. Toutefois, vous pouvez intégrer davantage d’informations du fournisseur dans le nouveau processus d’inscription d’utilisateur, comme indiqué dans les sections suivantes.

Créer des modèles pour obtenir des informations supplémentaires sur l’utilisateur

Comme vous l’avez remarqué dans les sections précédentes, vous n’avez pas besoin de récupérer d’informations supplémentaires pour que l’inscription du compte intégré fonctionne. Toutefois, la plupart des fournisseurs externes transmettent des informations supplémentaires sur l’utilisateur. Les sections suivantes montrent comment conserver ces informations et les enregistrer dans une base de données. Plus précisément, vous conserverez des valeurs pour le nom complet de l’utilisateur, l’URI de la page web personnelle de l’utilisateur et une valeur qui indique si Facebook a vérifié le compte.

Vous allez utiliser Migrations Code First pour ajouter une table afin de stocker des informations utilisateur supplémentaires. Comme vous ajoutez la table à une base de données existante, vous devez d’abord créer une instantané de la base de données active. En créant une instantané de la base de données active, vous pouvez créer ultérieurement une migration qui contient uniquement la nouvelle table. Pour créer une instantané de la base de données active :

  1. Ouvrir la console du Gestionnaire de package
  2. Exécuter la commande enable-migrations
  3. Exécutez la commande add-migration initial –IgnoreChanges
  4. Exécuter la commande update-database

Maintenant, vous allez ajouter les nouvelles propriétés. Dans le dossier Models, ouvrez le fichier AccountModels.cs et recherchez la classe RegisterExternalLoginModel. La classe RegisterExternalLoginModel contient des valeurs qui proviennent du fournisseur d’authentification. Ajoutez des propriétés nommées FullName et Link, comme indiqué ci-dessous.

public class RegisterExternalLoginModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    public string ExternalLoginData { get; set; }

    [Display(Name = "Full name")]
    public string FullName { get; set; }

    [Display(Name = "Personal page link")]
    public string Link { get; set; }
}

Également dans AccountModels.cs, ajoutez une nouvelle classe appelée ExtraUserInformation. Cette classe représente la nouvelle table qui sera créée dans la base de données.

[Table("ExtraUserInformation")]
public class ExternalUserInformation
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string FullName { get; set; }
    public string Link { get; set; }
    public bool? Verified { get; set; }
}

Dans la classe UsersContext, ajoutez le code en surbrillance ci-dessous pour créer une propriété DbSet pour la nouvelle classe.

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<ExternalUserInformation> ExternalUsers { get; set; }
}

Vous êtes maintenant prêt à créer la table. Ouvrez à nouveau la console du Gestionnaire de package et cette fois :

  1. Exécutez la commande add-migration AddExtraUserInformation
  2. Exécuter la commande update-database

La nouvelle table existe maintenant dans la base de données.

Récupérer les données supplémentaires

Il existe deux façons de récupérer des données utilisateur supplémentaires. La première méthode consiste à conserver les données utilisateur qui sont transmises par défaut pendant la demande d’authentification. La deuxième méthode consiste à appeler spécifiquement l’API du fournisseur et à demander plus d’informations. Les valeurs de FullName et Link sont automatiquement renvoyées par Facebook. Valeur qui indique si Facebook a vérifié que le compte est récupéré via un appel à l’API Facebook. Tout d’abord, vous remplirez les valeurs pour FullName et Link, puis plus tard, vous obtiendrez la valeur vérifiée.

Pour récupérer les données utilisateur supplémentaires, ouvrez le fichier AccountController.cs dans le dossier Controllers .

Ce fichier contient la logique de journalisation, d’inscription et de gestion des comptes. En particulier, notez les méthodes appelées ExternalLoginCallback et ExternalLoginConfirmation. Dans ces méthodes, vous pouvez ajouter du code pour personnaliser les opérations de connexion externe pour votre application. La première ligne de la méthode ExternalLoginCallback contient :

AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
    Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

Des données utilisateur supplémentaires sont renvoyées dans la propriété ExtraData de l’objet AuthenticationResult retourné par la méthode VerifyAuthentication . Le client Facebook contient les valeurs suivantes dans la propriété ExtraData :

  • id
  • name
  • link
  • gender
  • accesstoken

Les autres fournisseurs auront des données similaires, mais légèrement différentes dans la propriété ExtraData.

Si l’utilisateur est nouveau sur votre site, vous allez récupérer certaines données supplémentaires et passer ces données à la vue de confirmation. Le dernier bloc de code de la méthode est exécuté uniquement si l’utilisateur est nouveau sur votre site. Remplacez la ligne suivante :

return View("ExternalLoginConfirmation", new RegisterExternalLoginModel 
{ 
    UserName = result.UserName, 
    ExternalLoginData = loginData 
});

Avec cette ligne :

return View("ExternalLoginConfirmation", new RegisterExternalLoginModel
{
    UserName = result.UserName,
    ExternalLoginData = loginData,
    FullName = result.ExtraData["name"],
    Link = result.ExtraData["link"]
});

Cette modification inclut simplement des valeurs pour les propriétés FullName et Link.

Dans la méthode ExternalLoginConfirmation , modifiez le code comme indiqué ci-dessous pour enregistrer les informations utilisateur supplémentaires.

if (user == null)
{
    // Insert name into the profile table
    UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
    db.SaveChanges();

    db.ExternalUsers.Add(new ExternalUserInformation 
    { 
        UserId = newUser.UserId, 
        FullName = model.FullName, 
        Link = model.Link 
    });
    db.SaveChanges();

    OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
    OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);

    return RedirectToLocal(returnUrl);
}
else
{
    ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
}

Ajustement de la vue

Les données utilisateur supplémentaires que vous récupérez à partir du fournisseur s’affichent dans la page d’inscription.

Dans le dossier Views/Account , ouvrez ExternalLoginConfirmation.cshtml. Sous le champ existant pour le nom d’utilisateur, ajoutez des champs pour FullName, Link et PictureLink.

<li>
    @Html.LabelFor(m => m.FullName)
    @Html.TextBoxFor(m => m.FullName)
</li>
<li>
    @Html.LabelFor(m => m.Link)
    @Html.TextBoxFor(m => m.Link)
</li>

Vous êtes maintenant presque prêt à exécuter l’application et à inscrire un nouvel utilisateur avec les informations supplémentaires enregistrées. Vous devez disposer d’un compte qui n’est pas déjà inscrit auprès du site. Vous pouvez utiliser un autre compte de test ou supprimer les lignes dans les tables UserProfile et webpages_OAuthMembership pour le compte que vous souhaitez réutiliser. En supprimant ces lignes, vous vous assurerez que le compte est à nouveau inscrit.

Exécutez l’application et inscrivez le nouvel utilisateur. Notez que cette fois la page de confirmation contient plus de valeurs.

Capture d’écran montrant où vous pouvez entrer un nom d’utilisateur et d’autres informations après avoir associé un compte Facebook à l’application.

Une fois l’inscription terminée, fermez le navigateur. Regardez dans la base de données pour remarquer les nouvelles valeurs dans la table ExtraUserInformation .

Installer le package NuGet pour l’API Facebook

Facebook fournit une API que vous pouvez appeler pour effectuer des opérations. Vous pouvez appeler l’API Facebook en dirigeant l’envoi de requêtes HTTP ou en installant un package NuGet qui facilite l’envoi de ces requêtes. L’utilisation d’un package NuGet est présentée dans ce didacticiel, mais l’installation du package NuGet n’est pas essentielle. Ce tutoriel montre comment utiliser le package du Kit de développement logiciel (SDK) C# Facebook. Il existe d’autres packages NuGet qui vous aident à appeler l’API Facebook.

Dans les fenêtres Gérer les packages NuGet , sélectionnez le package du SDK C# Facebook.

installer le package

Vous allez utiliser le Kit de développement logiciel (SDK) C# Facebook pour appeler une opération qui nécessite le jeton d’accès pour l’utilisateur. La section suivante montre comment obtenir le jeton d’accès.

Récupérer le jeton d’accès

La plupart des fournisseurs externes transmettent un jeton d’accès une fois les informations d’identification de l’utilisateur vérifiées. Ce jeton d’accès est très important, car il vous permet d’appeler des opérations qui ne sont disponibles que pour les utilisateurs authentifiés. Par conséquent, la récupération et le stockage du jeton d’accès sont essentiels lorsque vous souhaitez fournir davantage de fonctionnalités.

Selon le fournisseur externe, le jeton d’accès peut être valide pendant une durée limitée. Pour vous assurer que vous disposez d’un jeton d’accès valide, vous allez le récupérer chaque fois que l’utilisateur se connecte et le stocker en tant que valeur de session au lieu de l’enregistrer dans une base de données.

Dans la méthode ExternalLoginCallback , le jeton d’accès est également repassé dans la propriété ExtraData de l’objet AuthenticationResult . Ajoutez le code mis en surbrillance à ExternalLoginCallback pour enregistrer le jeton d’accès dans l’objet Session . Ce code est exécuté chaque fois que l’utilisateur se connecte avec un compte Facebook.

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
    AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
        Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
    if (!result.IsSuccessful)
    {
        return RedirectToAction("ExternalLoginFailure");
    }

    if (result.ExtraData.Keys.Contains("accesstoken"))
    {
        Session["facebooktoken"] = result.ExtraData["accesstoken"];
    }

    if (OAuthWebSecurity.Login(
        result.Provider, 
        result.ProviderUserId, 
        createPersistentCookie: false))
    {
        return RedirectToLocal(returnUrl);
    }

    if (User.Identity.IsAuthenticated)
    {
        // If the current user is logged in add the new account
        OAuthWebSecurity.CreateOrUpdateAccount(
            result.Provider,
            result.ProviderUserId, 
            User.Identity.Name);
        return RedirectToLocal(returnUrl);
    }
    else
    {
        // User is new, ask for their desired membership name
        string loginData = OAuthWebSecurity.SerializeProviderUserId(
            result.Provider, 
            result.ProviderUserId);
        ViewBag.ProviderDisplayName =
            OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
        ViewBag.ReturnUrl = returnUrl;
        return View("ExternalLoginConfirmation", new RegisterExternalLoginModel
        {
            UserName = result.UserName,
            ExternalLoginData = loginData,
            FullName = result.ExtraData["name"],
            Link = result.ExtraData["link"]
        });    
    }
}

Bien que cet exemple récupère un jeton d’accès à partir de Facebook, vous pouvez récupérer le jeton d’accès auprès de n’importe quel fournisseur externe via la même clé nommée « accesstoken ».

Déconnexion

La méthode LogOff par défaut journalise l’utilisateur hors de votre application, mais ne le déconnecte pas du fournisseur externe. Pour déconnecter l’utilisateur de Facebook et empêcher la persistance du jeton une fois que l’utilisateur s’est déconnecté, vous pouvez ajouter le code en surbrillance suivant à la méthode LogOff dans AccountController.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    WebSecurity.Logout();
    if (Session["facebooktoken"] != null)
    {
        var fb = new Facebook.FacebookClient();
        string accessToken = Session["facebooktoken"] as string;
        var logoutUrl = fb.GetLogoutUrl(new { access_token = accessToken, next = "http://localhost:39852/" });

        Session.RemoveAll();
        return Redirect(logoutUrl.AbsoluteUri);
    }

    return RedirectToAction("Index", "Home");
}

La valeur que vous fournissez dans le next paramètre est l’URL à utiliser une fois que l’utilisateur s’est déconnecté de Facebook. Lors du test sur votre ordinateur local, vous devez fournir le numéro de port correct pour votre site local. En production, vous devez fournir une page par défaut, telle que contoso.com.

Récupérer les informations utilisateur qui nécessitent le jeton d’accès

Maintenant que vous avez stocké le jeton d’accès et installé le package du SDK C# Facebook, vous pouvez les utiliser ensemble pour demander des informations supplémentaires à l’utilisateur auprès de Facebook. Dans la méthode ExternalLoginConfirmation, créez un instance de la classe FacebookClient en transmettant la valeur du jeton d’accès. Demandez la valeur de la propriété vérifiée pour l’utilisateur actuel et authentifié. La propriété verified indique si Facebook a validé le compte par d’autres moyens, comme l’envoi d’un message à un téléphone portable. Enregistrez cette valeur dans la base de données.

if (user == null)
{
    // Insert name into the profile table
    UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
    db.SaveChanges();

    bool facebookVerified;

    var client = new Facebook.FacebookClient(Session["facebooktoken"].ToString());
    dynamic response = client.Get("me", new { fields = "verified" });
    if (response.ContainsKey("verified"))
    {
        facebookVerified = response["verified"];
    }
    else
    {
        facebookVerified = false;
    }

    db.ExternalUsers.Add(new ExternalUserInformation 
    { 
        UserId = newUser.UserId, 
        FullName = model.FullName, 
        Link = model.Link, 
        Verified = facebookVerified 
    });
    db.SaveChanges();

    OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
    OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);

    return RedirectToLocal(returnUrl);
}

Vous devrez à nouveau supprimer les enregistrements de la base de données pour l’utilisateur ou utiliser un autre compte Facebook.

Exécutez l’application et inscrivez le nouvel utilisateur. Examinez la table ExtraUserInformation pour voir la valeur de la propriété Verified.

Conclusion

Dans ce tutoriel, vous avez créé un site intégré à Facebook pour les données d’authentification et d’inscription des utilisateurs. Vous avez découvert le comportement par défaut configuré pour l’application web MVC 4 et comment personnaliser ce comportement par défaut.