Ajout de l'authentification d'identité ASP.NET MVC5 à un projet existant

164

J'ai vu beaucoup de pages similaires sur le Web, mais la plupart d'entre elles utilisent un nouveau projet au lieu d'un projet existant, ou n'ont pas les fonctionnalités nécessaires. J'ai donc un MVC 5projet existant et je souhaite intégrer l' identité ASP.NET MVC5 avec des fonctionnalités de connexion, de confirmation par e-mail et de réinitialisation de mot de passe .

En plus de cela, j'ai également besoin de créer toutes les tables nécessaires sur la base de données c'est-à-dire utilisateur, rôles, groupes, etc. (j'utilise EF Code First dans mon projet). Existe-t-il un article ou un échantillon correspondant à ces besoins? Toute suggestion serait appréciée. Merci d'avance...

Jack
la source
Quelle belle quête et quelle simple solutine donnée juste en dessous. J'ai adoré la lecture et j'ai vraiment besoin de l'intégrer dans mon projet existant.
Ishwor Khanal

Réponses:

282

Configurer l'identité de votre projet existant n'est pas une chose difficile. Vous devez installer un package NuGet et effectuer une petite configuration.

Installez d'abord ces packages NuGet avec la console du gestionnaire de package:

PM> Install-Package Microsoft.AspNet.Identity.Owin 
PM> Install-Package Microsoft.AspNet.Identity.EntityFramework
PM> Install-Package Microsoft.Owin.Host.SystemWeb 

Ajoutez une classe d'utilisateurs et avec IdentityUserhéritage:

public class AppUser : IdentityUser
{
    //add your custom properties which have not included in IdentityUser before
    public string MyExtraProperty { get; set; }  
}

Faites la même chose pour le rôle:

public class AppRole : IdentityRole
{
    public AppRole() : base() { }
    public AppRole(string name) : base(name) { }
    // extra properties here 
}

Changez votre DbContextparent de DbContextpour IdentityDbContext<AppUser>aimer ceci:

public class MyDbContext : IdentityDbContext<AppUser>
{
    // Other part of codes still same 
    // You don't need to add AppUser and AppRole 
    // since automatically added by inheriting form IdentityDbContext<AppUser>
}

Si vous utilisez la même chaîne de connexion et la migration activée, EF créera les tables nécessaires pour vous.

En option, vous pouvez étendre UserManagerpour ajouter la configuration et la personnalisation souhaitées:

public class AppUserManager : UserManager<AppUser>
{
    public AppUserManager(IUserStore<AppUser> store)
        : base(store)
    {
    }

    // this method is called by Owin therefore this is the best place to configure your User Manager
    public static AppUserManager Create(
        IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {
        var manager = new AppUserManager(
            new UserStore<AppUser>(context.Get<MyDbContext>()));

        // optionally configure your manager
        // ...

        return manager;
    }
}

Étant donné que l'identité est basée sur OWIN, vous devez également configurer OWIN:

Ajoutez une classe au App_Startdossier (ou n'importe où ailleurs si vous le souhaitez). Cette classe est utilisée par OWIN. Ce sera votre classe de démarrage.

namespace MyAppNamespace
{
    public class IdentityConfig
    {
        public void Configuration(IAppBuilder app)
        {
            app.CreatePerOwinContext(() => new MyDbContext());
            app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
            app.CreatePerOwinContext<RoleManager<AppRole>>((options, context) =>
                new RoleManager<AppRole>(
                    new RoleStore<AppRole>(context.Get<MyDbContext>())));

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Home/Login"),
            });
        }
    }
}

Presque terminé, ajoutez simplement cette ligne de code à votre web.configfichier pour que OWIN puisse trouver votre classe de démarrage.

<appSettings>
    <!-- other setting here -->
    <add key="owin:AppStartup" value="MyAppNamespace.IdentityConfig" />
</appSettings>

Désormais, dans l'ensemble du projet, vous pouvez utiliser Identity comme n'importe quel nouveau projet déjà installé par VS. Considérez l'action de connexion par exemple

[HttpPost]
public ActionResult Login(LoginViewModel login)
{
    if (ModelState.IsValid)
    {
        var userManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
        var authManager = HttpContext.GetOwinContext().Authentication;

        AppUser user = userManager.Find(login.UserName, login.Password);
        if (user != null)
        {
            var ident = userManager.CreateIdentity(user, 
                DefaultAuthenticationTypes.ApplicationCookie);
            //use the instance that has been created. 
            authManager.SignIn(
                new AuthenticationProperties { IsPersistent = false }, ident);
            return Redirect(login.ReturnUrl ?? Url.Action("Index", "Home"));
        }
    }
    ModelState.AddModelError("", "Invalid username or password");
    return View(login);
}

Vous pouvez créer des rôles et ajouter à vos utilisateurs:

public ActionResult CreateRole(string roleName)
{
    var roleManager=HttpContext.GetOwinContext().GetUserManager<RoleManager<AppRole>>();

    if (!roleManager.RoleExists(roleName))
        roleManager.Create(new AppRole(roleName));
    // rest of code
} 

Vous pouvez également ajouter un rôle à un utilisateur, comme ceci:

UserManager.AddToRole(UserManager.FindByName("username").Id, "roleName");

En utilisant, Authorizevous pouvez protéger vos actions ou contrôleurs:

[Authorize]
public ActionResult MySecretAction() {}

ou

[Authorize(Roles = "Admin")]]
public ActionResult MySecretAction() {}

Vous pouvez également installer des packages supplémentaires et les configurer pour répondre à vos besoins, comme Microsoft.Owin.Security.Facebookvous le souhaitez.

Remarque: n'oubliez pas d'ajouter des espaces de noms pertinents à vos fichiers:

using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;

Vous pouvez également voir mes autres réponses comme celle-ci et ceci pour une utilisation avancée de l'identité.

Sam Farajpour Ghamari
la source
2
Les deux solutions se ressemblent. J'ai utilisé AppRolele gestionnaire de rôles et Identity pour classer l'utilisateur. Et puisque Roles et RoleManageront déjà implémenté par Identity lui-même, vous n'avez pas besoin de réécrire le code déjà implémenté. Je mettrai à jour le message pour vous montrer comment vous pouvez utiliser les rôles. Et comme je l'ai déjà dit, il vous suffit d'ajouter AppUseret d' AppRoleentités pour initialiser l'identité. En héritant DbContextde IdentityDbContext<AppUser>toutes les tables nécessaires, ajoutez votre table. Vous n'avez rien à faire, il suffit d'activer la migration.
Sam Farajpour Ghamari
2
Je viens d'ajouter quelques exemples d'utilisation. Installez Microsoft.AspNet.Identity.EntityFrameworksur votre domaine et autres pour l'interface utilisateur.
Sam Farajpour Ghamari
2
1) Ne vous inquiétez pas pour votre web.config. Ne remplacez pas l'ancien. Lisez ceci pour plus d'informations . Je pense que votre MVC a également été mis à niveau.
Sam Farajpour Ghamari
1
2) Vous avez bien fait. 3) pas de problème. Vous aurez 5 nouvelle table AspNetRoles AspNetUserClaims AspNetUserLogins AspNetUserRolesetAspNetUsers
Sam Farajpour Ghamari
3
Je viens de lire tous les commentaires que vous avez laissés pour aider Clint Eastwood, Nice Job !! Le monde a besoin de plus de gens comme You plusOne
Chef_Code
24

C'est ce que j'ai fait pour intégrer Identity à une base de données existante.

  1. Créez un exemple de projet MVC avec un modèle MVC. Il contient tout le code nécessaire à l'implémentation d'identité - Startup.Auth.cs, IdentityConfig.cs, code de contrôleur de compte, gérer le contrôleur, modèles et vues associées.

  2. Installez les packages nuget nécessaires pour Identity et OWIN. Vous aurez une idée en voyant les références dans l'exemple de projet et la réponse de @Sam

  3. Copiez tous ces codes dans votre projet existant. Veuillez noter que n'oubliez pas d'ajouter la chaîne de connexion "DefaultConnection" pour Identity à mapper à votre base de données. Veuillez vérifier la classe ApplicationDBContext dans IdentityModel.cs où vous trouverez la référence à la chaîne de connexion "DefaultConnection".

  4. Voici le script SQL que j'ai exécuté sur ma base de données existante pour créer les tables nécessaires:

    USE ["YourDatabse"]
    GO
    /****** Object:  Table [dbo].[AspNetRoles]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetRoles](
    [Id] [nvarchar](128) NOT NULL,
    [Name] [nvarchar](256) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetRoles] PRIMARY KEY CLUSTERED 
    (
      [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserClaims]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserClaims](
       [Id] [int] IDENTITY(1,1) NOT NULL,
       [UserId] [nvarchar](128) NOT NULL,
       [ClaimType] [nvarchar](max) NULL,
       [ClaimValue] [nvarchar](max) NULL,
    CONSTRAINT [PK_dbo.AspNetUserClaims] PRIMARY KEY CLUSTERED 
    (
       [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserLogins]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserLogins](
        [LoginProvider] [nvarchar](128) NOT NULL,
        [ProviderKey] [nvarchar](128) NOT NULL,
        [UserId] [nvarchar](128) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUserLogins] PRIMARY KEY CLUSTERED 
    (
        [LoginProvider] ASC,
        [ProviderKey] ASC,
        [UserId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserRoles]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserRoles](
       [UserId] [nvarchar](128) NOT NULL,
       [RoleId] [nvarchar](128) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUserRoles] PRIMARY KEY CLUSTERED 
    (
        [UserId] ASC,
        [RoleId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUsers]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUsers](
        [Id] [nvarchar](128) NOT NULL,
        [Email] [nvarchar](256) NULL,
        [EmailConfirmed] [bit] NOT NULL,
        [PasswordHash] [nvarchar](max) NULL,
        [SecurityStamp] [nvarchar](max) NULL,
        [PhoneNumber] [nvarchar](max) NULL,
        [PhoneNumberConfirmed] [bit] NOT NULL,
        [TwoFactorEnabled] [bit] NOT NULL,
        [LockoutEndDateUtc] [datetime] NULL,
        [LockoutEnabled] [bit] NOT NULL,
        [AccessFailedCount] [int] NOT NULL,
        [UserName] [nvarchar](256) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
     GO
     ALTER TABLE [dbo].[AspNetUserClaims]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserClaims] CHECK CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId]
     GO
     ALTER TABLE [dbo].[AspNetUserLogins]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserLogins] CHECK CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId]
     GO
     ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId] FOREIGN KEY([RoleId])
     REFERENCES [dbo].[AspNetRoles] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId]
     GO
     ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId]
     GO
  5. Vérifiez et résolvez toutes les erreurs restantes et vous avez terminé. L'identité s'occupera du reste :)

Shyamal Parikh
la source
1
Merci beaucoup pour votre réponse et vos belles explications. En fait, je pense utiliser une autre approche, mais je vais aussi l'essayer. A voté +
Jack
2
Je pense que c'est une approche beaucoup plus propre
niico
3
En plus de la classe Startup.Auth.cs, vous devez copier le fichier Startup.cs situé à la racine de l'exemple de projet.
Padmika
Shyamal pouvez-vous ajouter le Startup.cs du commentaire de @ Padmika? C'est important.
Mike le
4

Je recommande IdentityServer . Il s'agit d'un projet .NET Foundation et couvre de nombreux problèmes d'authentification et d'autorisation.

Aperçu

IdentityServer est un framework basé sur .NET / Katana et un composant hébergable qui permet de mettre en œuvre une connexion unique et un contrôle d'accès pour les applications Web modernes et les API à l'aide de protocoles tels que OpenID Connect et OAuth2. Il prend en charge un large éventail de clients tels que les applications mobiles, Web, SPA et de bureau et est extensible pour permettre l'intégration dans les architectures nouvelles et existantes.

Pour plus d'informations, par exemple

  • prise en charge des magasins d'utilisateurs basés sur MembershipReboot et ASP.NET Identity
  • prise en charge d'un middleware d'authentification Katana supplémentaire (par exemple Google, Twitter, Facebook, etc.)
  • prise en charge de la persistance de la configuration basée sur EntityFramework
  • prise en charge de WS-Federation
  • extensibilité

consultez la documentation et la démo .

TotPeRo
la source
6
Les utilisations pratiques d'IdentityServer doivent être prises en compte avant de se lancer aveuglément dans une implémentation d'IdentityServer.
hanzolo