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


164

我在网络上看到过很多类似的页面,但是大多数页面使用的是新项目而不是现有的项目,或者没有必要的功能。因此,我有一个现有MVC 5项目,希望将ASP.NET MVC5 Identity与登录,电子邮件确认和密码重置功能集成在一起。

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


下面是一个很棒的课题,一个简单的solutin。我喜欢它可以通读,也非常需要集成到我现有的项目中。
伊什沃尔·卡纳尔(Ishwor Khanal),

Answers:


282

为您现有的项目配置身份并非易事。您必须安装一些NuGet软件包并进行一些小的配置。

首先使用程序包管理器控制台安装以下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父母从更改DbContextIdentityDbContext<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 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;
    }
}

由于身份基于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(无论您愿意还是希望使用它)。

注意:不要忘记在文件中添加相关的名称空间:

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;

你也可以看到我的其他答案喜欢这个这个先进的使用身份。


2
两种解决方案看起来都很相似。我已经使用了AppRoleIdentity的角色管理器对用户进行分类。并且由于RoleRoleManager并且已经由Identity本身实现,因此您无需重写已实现的代码。我将更新该帖子,向您展示如何使用角色。正如我之前所说,您只需要添加AppUserAppRole实体即可初始化Identity。通过DbContextIdentityDbContext<AppUser>所有必需的表继承您的表,添加表。您无需执行任何操作即可启用迁移。
Sam Farajpour Ghamari 2015年

2
我只是添加了一些示例用法。安装Microsoft.AspNet.Identity.EntityFramework到您的域和其他UI。
Sam Farajpour Ghamari 2015年

2
1)不用担心您的web.config。不要替换旧的。阅读此以获得更多信息。我认为您的MVC也已升级。
Sam Farajpour Ghamari 2015年

1
2)你做对了。3)没问题。您将拥有5张新桌子,AspNetRoles AspNetUserClaims AspNetUserLogins AspNetUserRoles以及AspNetUsers
Sam Farajpour Ghamari 2015年

3
我刚刚读完您留下的所有评论,这些评论帮助Clint Eastwood,《尼斯工作》!世界需要像You plusOne这样的更多人
Chef_Code 2016年

24

这是我将Identity与现有数据库集成在一起的工作。

  1. 使用MVC模板创建一个示例MVC项目。这具有身份实施所需的所有代码-Startup.Auth.cs,IdentityConfig.cs,帐户控制器代码,管理控制器,模型和相关视图。

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

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

  4. 这是我在现有数据库上运行的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
  5. 检查并解决所有剩余的错误,您已完成。身份将处理其余的问题:)


1
非常感谢您的答复和很好的解释。实际上,我考虑使用另一种方法,但我也会尝试一下。投票+
杰克

2
我认为这是一种更清洁的方法
niico

3
除了Startup.Auth.cs类外,您还需要复制位于示例项目根目录下的Startup.cs。
Padmika '17

Shyamal可以从@Padmika的评论中添加Startup.cs吗?这个很重要。
迈克

4

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

总览

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

有关更多信息,例如

  • 支持MembershipReboot和基于ASP.NET Identity的用户存储
  • 支持其他的Katana身份验证中间件(例如Google,Twitter,Facebook等)
  • 支持基于EntityFramework的配置持久性
  • 支持WS-Federation
  • 可扩展性

查看文档演示


6
在盲目进入IdentityServer实现之前,应考虑IdentityServer的实际用法。
hanzolo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.