ASP.NET MVC5 ID認証を既存のプロジェクトに追加する


164

Webで類似のページをたくさん見ましたが、それらのほとんどは、既存のプロジェクトの代わりに新しいプロジェクトを使用しているか、必要な機能を持っていません。そのため、既存のMVC 5プロジェクトがあり、ASP.NET MVC5 IDをログイン、電子メール確認、パスワードリセット機能統合したいと考えています。

これに加えて、ユーザー、ロール、グループなど、データベースに必要なすべてのテーブルを作成する必要もあります(プロジェクトではEF Code Firstを使用しています)。これらのニーズに対応する記事またはサンプルはありますか?任意の提案をいただければ幸いです。前もって感謝します...


なんと素晴らしい質問で、そのすぐ下にある単純なソルティンです。私はそれを読み通すのが好きで、私の既存のプロジェクトにも統合する必要がありました。
Ishwor Khanal 2018

回答:


282

Identityを既存のプロジェクトに構成することは難しくありません。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 
}

DbContextDbContextを次の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 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;
    }
}

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.configOWINがスタートアップクラスを見つけることができるように、ほとんどの場合、このコード行をファイルに追加するだけです。

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

これで、プロジェクト全体で、VSによってすでにインストールされている新しいプロジェクトと同じようにIdentityを使用できます。たとえば、ログインアクションを検討してください

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

また、Identityの高度な使用について、これこれのような他の私の答えを見ることができます。


2
どちらのソリューションも似ています。私が使用しているAppRoleと分類ユーザーへのアイデンティティの役割マネージャー。そして、以来、RolesおよびRoleManagerすでにアイデンティティ自体によって実装されているあなたはすでに実装コードを書き換える必要はありません。投稿を更新して、ロールの使用方法を紹介します。前に言ったようにAppUserAppRoleIDを初期化するには、エンティティとエンティティを追加するだけです。必要なすべてのテーブルDbContextからを継承することで、IdentityDbContext<AppUser>テーブルを追加します。移行を有効にするだけで、何もする必要はありません。
Sam Farajpour Ghamari 2015

2
サンプルの使用法を追加しました。Microsoft.AspNet.Identity.EntityFrameworkあなたのドメインやその他のUIにインストールしてください。
Sam Farajpour Ghamari 2015

2
1)あなたのことを心配しないでくださいweb.config。古いものを交換しないでください。詳細はこちらをご覧ください。MVCもアップグレードされたと思います。
Sam Farajpourガマリ

1
2)あなたは正しい。3)問題ありません。5つの新しいテーブルAspNetRoles AspNetUserClaims AspNetUserLogins AspNetUserRolesAspNetUsers
Sam Farajpour Ghamari 2015

3
Clint Eastwood、Nice Jobを支援するために残したすべてのコメントを読んだところです。世界はあなたplusOneのようなより多くの人々を必要としています
Chef_Code

24

これは、Identityを既存のデータベースと統合するために行ったものです。

  1. MVCテンプレートを使用してサンプルMVCプロジェクトを作成します。これには、Identityの実装に必要なすべてのコード(Startup.Auth.cs、IdentityConfig.cs、アカウントコントローラーコード、コントローラーの管理、モデル、および関連するビュー)が含まれています。

  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
  5. 残っているエラーを確認して解決すれば完了です。アイデンティティは残りを処理します:)


1
返信と素晴らしい説明に感謝します。実は別のアプローチを考えていますが、やってみます。投票済み
ジャック

2
これはもっと
すっきりした

3
Startup.Auth.csクラスに加えて、サンプルプロジェクトのルートにあるStartup.csをコピーする必要があります。
Padmika

Shyamal @PadmikaのコメントからStartup.csを追加できますか?これは重要。
マイク

4

IdentityServerをお勧めします。これは.NET Foundationプロジェクトであり、認証と承認に関する多くの問題をカバーしています。

概観

IdentityServerは、.NET / Katanaベースのフレームワークとホスト可能なコンポーネントであり、OpenID ConnectやOAuth2などのプロトコルを使用して、最新のWebアプリケーションとAPIのシングルサインオンとアクセス制御を実装できます。モバイル、Web、SPA、デスクトップアプリケーションなどの幅広いクライアントをサポートし、新しいアーキテクチャと既存のアーキテクチャとの統合を可能にするように拡張可能です。

詳細については、例えば

  • MembershipRebootおよびASP.NET Identityベースのユーザーストアのサポート
  • 追加のカタナ認証ミドルウェア(Google、Twitter、Facebookなど)のサポート
  • EntityFrameworkベースの構成の永続化のサポート
  • WS-Federationのサポート
  • 拡張性

ドキュメントデモを確認してください。


6
IdentityServerの実用的な使用法は、IdentityServer実装に盲目的に飛び込む前に検討する必要があります。
ハンゾロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.