web-dev-qa-db-fra.com

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

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 ne possèdent pas les fonctionnalités nécessaires. J'ai donc un projet MVC 5 existant et je souhaite intégrer Identité ASP.NET MVC5 avec connexion, confirmation de courrier électronique et réinitialisation du mot de passe.

En plus de cela, j'ai également besoin de créer tous les tables nécessaires sur la base de données, c'est-à-dire l'utilisateur, les rôles, 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...

147
Jack

Configurer l'identité sur votre projet existant n'est pas une chose difficile. Vous devez installer un paquet NuGet et faire une petite configuration.

Commencez par installer ces packages NuGet avec la console Package Manager:

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'utilisateur et avec IdentityUser un hé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 DbContext parent de DbContext en IdentityDbContext<AppUser> comme 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 pour vous les tables nécessaires.

Vous pouvez éventuellement étendre UserManager pour 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;
    }
}

Comme Identity est basé sur OWIN, vous devez également configurer OWIN:

Ajoutez une classe au dossier App_Start (ou 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"),
            });
        }
    }
}

Vous avez presque fini d'ajouter cette ligne de code à votre fichier web.config afin qu'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 si tout nouveau projet avait déjà été 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 Authorize, vous pouvez protéger vos actions ou vos 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.Facebook ou selon votre choix.

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 this et this pour une utilisation avancée de l'identité.

259

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. Cela contient tout le code nécessaire à la mise en œuvre d'Identity - Startup.Auth.cs, IdentityConfig.cs, le code du contrôleur de compte, le gestionnaire de contrôleur, les modèles et les vues associées.

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

  3. Copiez tous ces codes dans votre projet existant. Remarque: n'oubliez pas d'ajouter la chaîne de connexion "DefaultConnection" pour que l'identité soit mappée à 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 les erreurs restantes et vous avez terminé. Identity se chargera du reste :)

21
Shyamal Parikh

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

Vue d'ensemble

IdentityServer est une structure et un composant hébergeables basés sur .NET/Katana qui permet de mettre en place une connexion et un contrôle d'accès uniques pour les applications Web modernes et les API utilisant des 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 MembershipReboot et ASP.NET Identity
  • prise en charge de middleware d'authentification Katana supplémentaire (Google, Twitter, Facebook, etc.)
  • prise en charge de la persistance de la configuration basée sur EntityFramework
  • support pour WS-Federation
  • extensibilité

découvrez le documentation et le échantillons .

3
TotPeRo