ASP.NET MVC Custom RoleProvider


  1. 說明
    1. Custom Provider
    2. ASP.NET Identity Database Schema
  2. 相關連結
  3. 參考資料

筆記如何客製 ASP.NET RoleProvider,從而實現使用 AuthorizeAttribute 驗證使用者的 Roles 時,定義 Roles 的來源。

logo

說明

Custom Provider

需要在專案中加入類別,並繼承 RoleProvider 後覆寫相關方法。

Custom/CustomRoleProvider.cs

public class CustomRoleProvider : RoleProvider
{
    public override string ApplicationName
    {
      get => throw new NotImplementedException();
      set => throw new NotImplementedException();
    }

    public override string[] GetRolesForUser(string username)
    {
        return new string[] { "Admin" };
    }

    public override bool IsUserInRole(string username, string roleName)
    {
        throw new NotImplementedException();
    }

    public override string[] GetUsersInRole(string roleName)
    {
        throw new NotImplementedException();
    }

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    {
        throw new NotImplementedException();
    }

    public override bool RoleExists(string roleName)
    {
        throw new NotImplementedException();
    }

    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        throw new NotImplementedException();
    }

    public override void CreateRole(string roleName)
    {
        throw new NotImplementedException();
    }

    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    {
        throw new NotImplementedException();
    }

    public override string[] FindUsersInRole(string roleName, string usernameToMatch)
    {
        throw new NotImplementedException();
    }

    public override string[] GetAllRoles()
    {
        throw new NotImplementedException();
    }
}

接著在 Config 加入 RoleProvider 的註冊。

Web.config

<system.web>
  <roleManager enabled="true" defaultProvider="CustomRoleProvider">
  <providers>
  <clear />
  <add name="CustomRoleProvider" type="NorthwindShop2.Web.Custom.CustomRoleProvider" />
  </providers>
  </roleManager>
</system.web>

ASP.NET Identity Database Schema

在客製化 Role 的資料儲存上,仍可以參考 ASP.NET Identity 的設置方式,並且在依照需求進行客製。

dbo.AspNetUsers

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

dbo.AspNetRoles

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

dbo.AspNetUserRoles

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

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

需要注意在匿名驗證的情況下,Authorize Filter 不會發揮作用,必須要是 Windows 驗證或者是 Form 驗證才能夠搭配 Authorize Filter 使用。

相關連結

ASP.NET MVC 5 如何客製化驗證與授權並實作帳號登入機制 (How to custom ASP.NET MVC Auth Filters & Login / Logoff systems)

參考資料

ASP.NET MVC How to create a custom role provider | stackoverflow