简体   繁体   English

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

[英]Adding ASP.NET MVC5 Identity Authentication to an existing project

I have seen lots of similar pages on the web, but most of them use a new project instead of an existing one, or don't have the necessary features.我在网上看到过很多类似的页面,但大多数都使用新项目而不是现有项目,或者没有必要的功能。 So, I have an existing MVC 5 project and want to integrate ASP.NET MVC5 Identity with log in, email confirmation and password reset features.所以,我有一个现有的MVC 5项目,并希望将ASP.NET MVC5 Identity 与登录、电子邮件确认和密码重置功能集成在一起。

In addition to this, I also need to create all the necessary tables on the database ie User, Roles, groups, etc. (I use EF Code First in my project).除此之外,我还需要在数据库上创建所有必要的表,即用户、角色、组等(我在我的项目中使用 EF Code First)。 Is there an article or sample that corresponds to these needs?是否有符合这些需求的文章或样本?

Configuring Identity to your existing project is not hard thing.为您现有的项目配置 Identity 并不是一件难事。 You must install some NuGet package and do some small configuration.您必须安装一些 NuGet 包并进行一些小的配置。

First install these NuGet packages with 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 

Add a user class and with IdentityUser inheritance:添加一个用户类并带有IdentityUser继承:

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

Do same thing for role:对角色做同样的事情:

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

Change your DbContext parent from DbContext to IdentityDbContext<AppUser> like this:像这样将您的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>
}

If you use the same connection string and enabled migration, EF will create necessary tables for you.如果您使用相同的连接字符串并启用迁移,EF 将为您创建必要的表。

Optionally, you could extend UserManager to add your desired configuration and customization:或者,您可以扩展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;
    }
}

Since Identity is based on OWIN you need to configure OWIN too:由于 Identity 基于 OWIN,因此您也需要配置 OWIN:

Add a class to App_Start folder (or anywhere else if you want).将类添加到App_Start文件夹(或其他任何地方,如果需要)。 This class is used by OWIN.此类由 OWIN 使用。 This will be your startup class.这将是您的启动课程。

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

Almost done just add this line of code to your web.config file so OWIN could find your startup class.快完成了,只需将这行代码添加到您的web.config文件中,这样 OWIN 就可以找到您的启动类。

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

Now in entire project you could use Identity just like any new project had already installed by VS.现在在整个项目中,您可以像 VS 已经安装的任何新项目一样使用 Identity。 Consider login action for example例如,考虑登录操作

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

You could make roles and add to your users:您可以创建角色并添加到您的用户:

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

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

You could also add a role to a user, like this:您还可以为用户添加角色,如下所示:

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

By using Authorize you could guard your actions or controllers:通过使用Authorize您可以保护您的操作或控制器:

[Authorize]
public ActionResult MySecretAction() {}

or或者

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

You can also install additional packages and configure them to meet your requirement like Microsoft.Owin.Security.Facebook or whichever you want.您还可以安装其他软件包并对其进行配置以满足您的要求,例如Microsoft.Owin.Security.Facebook或任何您想要的。

Note: Don't forget to add relevant namespaces to your files:注意:不要忘记将相关的命名空间添加到您的文件中:

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;

You could also see my other answers like this and this for advanced use of Identity.您还可以看到我的其他类似这样的答案和这个关于身份的高级使用。

This is what I did to integrate Identity with an existing database.这就是我为将 Identity 与现有数据库集成所做的工作。

  1. Create a sample MVC project with MVC template.使用 MVC 模板创建示例 MVC 项目。 This has all the code needed for Identity implementation - Startup.Auth.cs, IdentityConfig.cs, Account Controller code, Manage Controller, Models and related views.这具有身份实现所需的所有代码 - Startup.Auth.cs、IdentityConfig.cs、帐户控制器代码、管理控制器、模型和相关视图。

  2. Install the necessary nuget packages for Identity and OWIN.为 Identity 和 OWIN 安装必要的 nuget 包。 You will get an idea by seeing the references in the sample Project and the answer by @Sam通过查看示例项目中的参考资料和@Sam 的回答,您将获得一个想法

  3. Copy all these code to your existing project.将所有这些代码复制到您现有的项目中。 Please note don't forget to add the "DefaultConnection" connection string for Identity to map to your database.请注意不要忘记为 Identity 添加“DefaultConnection”连接字符串以映射到您的数据库。 Please check the ApplicationDBContext class in IdentityModel.cs where you will find the reference to "DefaultConnection" connection string.请检查 IdentityModel.cs 中的 ApplicationDBContext 类,您将在其中找到对“DefaultConnection”连接字符串的引用。

  4. This is the SQL script I ran on my existing database to create necessary tables:这是我在现有数据库上运行以创建必要表的 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. Check and solve any remaining errors and you are done.检查并解决任何剩余的错误,您就完成了。 Identity will handle the rest :)身份将处理其余的:)

I recommend IdentityServer .This is a .NET Foundation project and covers many issues about authentication and authorization.我推荐IdentityServer 。这是一个.NET Foundation项目,涵盖了许多有关身份验证和授权的问题。

Overview概述

IdentityServer is a .NET/Katana-based framework and hostable component that allows implementing single sign-on and access control for modern web applications and APIs using protocols like OpenID Connect and OAuth2. IdentityServer 是一个基于 .NET/Katana 的框架和可托管组件,它允许使用 OpenID Connect 和 OAuth2 等协议为现代 Web 应用程序和 API 实现单点登录和访问控制。 It supports a wide range of clients like mobile, web, SPAs and desktop applications and is extensible to allow integration in new and existing architectures.它支持广泛的客户端,如移动、Web、SPA 和桌面应用程序,并且可扩展以允许集成到新的和现有的架构中。

For more information, eg有关更多信息,例如

  • support for MembershipReboot and ASP.NET Identity based user stores支持 MembershipReboot 和基于 ASP.NET Identity 的用户存储
  • support for additional Katana authentication middleware (eg Google, Twitter, Facebook etc)支持额外的 Katana 身份验证中间件(例如 Google、Twitter、Facebook 等)
  • support for EntityFramework based persistence of configuration支持基于 EntityFramework 的配置持久性
  • support for WS-Federation支持 WS-Federation
  • extensibility可扩展性

check out the documentation and the demo .查看文档演示

well, I know I am probably too late.好吧,我知道我可能为时已晚。 This is for those who already did one or many migration.这适用于那些已经做过一次或多次迁移的人。 those that there project works perfectly, those who have the AspNet tables in there database , but don't have controllers, models and view related to those.那些项目完美运行的,那些在数据库中有 AspNet 表,但没有与这些相关的控制器、模型和视图的。
I also cam across the same issue.我也遇到了同样的问题。 I started my project without activating the authentication at the beginning.我在开始时没有激活身份验证就开始了我的项目。 Then I realized I did no have all the element for the authentication(Account and Manage in the Views folder, accountController and ManageControler in the controller, and AccountViewModel and ManageViewModel in the Model).然后我意识到我没有用于身份验证的所有元素(Views 文件夹中的 Account 和 Manage,控制器中的 accountController 和 ManageControler,以及模型中的 AccountViewModel 和 ManageViewModel)。 I just created and other project with similar settings, name and I activated the authentication at the creation of that project.我刚刚创建了其他具有类似设置、名称的项目,并在创建该项目时激活了身份验证。 then I manage to copie the missing file to my initial project.然后我设法将丢失的文件复制到我的初始项目中。 After that, I went through each of then to change the namespaces and imports to the namespace of my project在那之后,我经历了每个然后更改命名空间并导入到我的项目的命名空间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM