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

Jac*_*ack 151 asp.net authentication asp.net-mvc owin asp.net-identity

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

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

Sam*_*ari 263

为现有项目配置标识并不困难.您必须安装一些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 
Run Code Online (Sandbox Code Playgroud)

添加用户类和IdentityUser继承:

public class AppUser : IdentityUser
{
    //add your custom properties which have not included in IdentityUser before
    public string MyExtraProperty { get; set; }  
}
Run Code Online (Sandbox Code Playgroud)

为角色做同样的事情:

public class AppRole : IdentityRole
{
    public AppRole() : base() { }
    public AppRole(string name) : base(name) { }
    // extra properties here 
}
Run Code Online (Sandbox Code Playgroud)

将您的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>
}
Run Code Online (Sandbox Code Playgroud)

如果使用相同的连接字符串并启用了迁移,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

由于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"),
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<appSettings>
    <!-- other setting here -->
    <add key="owin:AppStartup" value="MyAppNamespace.IdentityConfig" />
</appSettings>
Run Code Online (Sandbox Code Playgroud)

现在在整个项目中,您可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

    if (!roleManager.RoleExists(roleName))
        roleManager.Create(new AppRole(roleName));
    // rest of code
} 
Run Code Online (Sandbox Code Playgroud)

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

UserManager.AddToRole(UserManager.FindByName("username").Id, "roleName");
Run Code Online (Sandbox Code Playgroud)

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

[Authorize]
public ActionResult MySecretAction() {}
Run Code Online (Sandbox Code Playgroud)

要么

[Authorize(Roles = "Admin")]]
public ActionResult MySecretAction() {}
Run Code Online (Sandbox Code Playgroud)

您还可以安装其他软件包并对其进行配置以满足您的要求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;
Run Code Online (Sandbox Code Playgroud)

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

  • 我刚看完了你帮助克林特伊斯特伍德,好工作的所有评论!世界需要更多像你一样的人 (3认同)
  • 两种解决方案看起来都很相似。我已经使用AppRole和Identity的角色管理器对用户进行分类。而且由于Identity本身已经实现了`Role`s和`RoleManager`,因此您无需重写已实现的代码。我将更新该帖子,向您展示如何使用角色。正如我之前所说,您只需要添加`AppUser`和`AppRole`实体即可初始化Identity。通过从IdentityDbContext &lt;AppUser&gt;继承您的DbContext,所有必要的表都将添加您的表。您无需执行任何操作即可启用迁移。 (2认同)
  • 我只是添加了一些示例用法。将“ Microsoft.AspNet.Identity.EntityFramework”安装到您的Domain和其他UI中。 (2认同)
  • 1)不要担心你的`web.config`.不要更换旧的.[阅读此内容以获取更多信息](https://msdn.microsoft.com/en-us/library/dd465326(v = vs.110).aspx).我认为你的MVC也升级了. (2认同)
  • 它几乎奏效了。但是我在迁移过程中遇到错误`EntityType 'IdentityUserRole' has no key defined`,我通过将 `base.OnModelCreating(modelBuilder);` 添加到 `OnModelCreating` 函数来解决它。 (2认同)

Shy*_*ikh 21

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

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

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

  3. 将所有这些代码复制到现有项目中.请注意,不要忘记为Identity添加"DefaultConnection"连接字符串以映射到您的数据库.请检查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
    
    Run Code Online (Sandbox Code Playgroud)
  5. 检查并解决任何剩余的错误,您就完成了.身份将处理其余的:)

  • 除了Startup.Auth.cs类之外,您还需要复制位于示例项目根目录的Startup.cs. (3认同)
  • 非常感谢您的回复和很好的解释。其实我想用另一种方法,但我也会尝试一下。投票+ (2认同)
  • 我认为这是一种更清洁的方法 (2认同)
  • Shyamal 您可以添加 @Padmika 评论中的 Startup.cs 吗?这个很重要。 (2认同)