首页 文章

将ASP.NET MVC5身份验证添加到现有项目

提问于
浏览
131

我在网上看到过很多类似的页面,但大多数都使用新项目而不是现有项目,或者没有必要的功能 . 所以,我有一个现有的 MVC 5 项目,并希望集成 ASP.NET MVC5 Identity with log in, email confirmation and password reset 功能 .

除此之外,我还需要在数据库上创建所有 necessary tables ,即用户,角色,组等(我在我的项目中使用EF Code First) . 是否有符合这些需求的文章或样本?任何建议将不胜感激 . 提前致谢...

3 回答

  • 4

    为现有项目配置标识并不困难 . 您必须安装一些NuGet包并进行一些小配置 .

    首先在Package Manager Console中安装这些NuGet包:

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

    添加用户类并使用 IdentityUser 继承:

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

    为角色做同样的事情:

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

    将您的 DbContext 父表单 DbContext 更改为 IdentityDbContext<AppUser> ,如下所示:

    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>
    }
    

    如果使用相同的连接字符串并启用了迁移,EF将为您创建必要的表 .

    (可选)您可以扩展 UserManager 以添加所需的配置和自定义:

    public class AppUserManager : UserManager<AppUser>
    {
        public AppUserManager(IUserStore<AppUser> store)
            : base(store)
        {
        }
    
        // this method is called by Owin therefore 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;
        }
    }
    

    由于Identity基于OWIN,因此您还需要配置OWIN:

    将类添加到 App_Start 文件夹(如果需要,可以添加到其他任何位置) . 该类由OWIN使用

    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"),
                });
            }
        }
    }
    

    几乎只需将这行代码添加到 web.config 文件中,以便OWIN可以找到您的启动类 .

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

    现在在整个项目中,您可以使用Identity,就像VS已经安装了新项目一样 . 例如,考虑登录操作

    [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);
    }
    

    您可以创建角色并添加到您的用户:

    public ActionResult CreateRole(string roleName)
    {
        var roleManager=HttpContext.GetOwinContext().GetUserManager<RoleManager<AppRole>>();
    
        if (!roleManager.RoleExists(roleName))
            roleManager.Create(new AppRole(roleName));
        // rest of code
    }
    

    您可以向任何用户添加任何角色,如下所示:

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

    通过使用 Authorize ,您可以保护您的操作或控制器:

    [Authorize]
    public ActionResult MySecretAction() {}
    

    要么

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

    您还可以安装其他软件包并配置它们以满足您的要求,例如 Microsoft.Owin.Security.Facebook 或您想要的任何一个 .

    Note: 不要忘记在文件中添加相关的命名空间:

    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;
    

    您还可以看到我的其他答案,如thisthis,以便高级使用Identity .

  • 243

    这就是我将Identity与现有数据库集成的方法 .

    • 使用MVC模板创建示例MVC项目 . 这包含Identity实现所需的所有代码 - Startup.Auth.cs,IdentityConfig.cs,Account Controller代码,Manage Controller,Models和相关视图 .

    • 为Identity和OWIN安装必要的nuget包 . 通过查看示例项目中的引用和@Sam的答案,您将获得一个想法

    • 将所有这些代码复制到现有项目中 . 请注意,不要忘记为Identity添加“DefaultConnection”连接字符串以映射到您的数据库 . 请检查IdentityModel.cs中的ApplicationDBContext类,您将在其中找到对“DefaultConnection”连接字符串的引用 .

    • 这是我在现有数据库上运行的SQL脚本,用于创建必要的表:

    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
    
    • 检查并解决任何剩余的错误,您就完成了 . 身份将处理其余的:)
  • 18

    我推荐IdentityServer . 这是一个.NET Foundation项目,涉及许多有关身份验证和授权的问题 .

    概述

    IdentityServer是一个基于.NET / Katana的框架和托管组件,允许使用OpenID Connect和OAuth2等协议为现代Web应用程序和API实现单点登录和访问控制 . 它支持广泛的客户端,如移动,Web,SPA和桌面应用程序,并且可扩展以允许集成到新的和现有的体系结构中 .

    有关详细信息,例如

    • 支持MembershipReboot和基于ASP.NET身份的用户存储

    • 支持额外的Katana身份验证中间件(例如Google,Twitter,Facebook等)

    • 支持基于EntityFramework的持久性配置

    • 支持WS-Federation

    • 可扩展性

    看看documentationsamples .

相关问题