ASP.NET MVC如何创建自定义角色提供程序

时间:2017-01-30 16:33:09

标签: asp.net asp.net-mvc asp.net-mvc-5 windows-authentication asp.net-authorization

作为ASP MVC的新手,我不确定哪种更适合我的需求。我使用Windows身份验证构建了一个Intranet站点,并且我能够使用Active Directory角色保护控制器和操作,例如

void fill()//fill combobox with values
{
    try
    {
        string connectionString = "Data Source=cmcentraldb;Initial Catalog=CMLTD;Integrated Security=True";
        SqlConnection con2 = new SqlConnection(connectionString);
        con2.Open();
        string query = "SELECT DISTINCT ITEMDESC  FROM dbo.IV00101"; 
        //select Convert(nvarchar(50),Item_Description)+ ':' +Convert(nvarchar(50),Item#) as Combined from Carimed
        SqlCommand cmd2 = new SqlCommand(query, con2);

        SqlDataReader dr2 = cmd2.ExecuteReader();
        while (dr2.Read())
        {
            string cari_des = dr2.GetString(dr2.GetOrdinal("ITEMDESC"));
            suggestComboBox1.Items.Add(cari_des.Trim());
        }
        //con2.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

我需要独立于AD角色定义自己的安全角色。所需的功能是,根据与我们的应用程序数据库中的配置文件相关联的一个或多个角色,经过身份验证的用户被授予对特定操作的访问权限,例如:" Manager"," User",&#34 ;嘉宾","分析师","开发人员"等

如何创建自定义角色提供程序和/或自定义授权属性?

1 个答案:

答案 0 :(得分:28)

我的解决方案是创建自定义角色提供程序。以下是我采取的步骤,以防其他人以后需要帮助:

创建自定义用户和角色类

using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Security.Models.Security
{
    public class AppRole : IdentityRole
    {
    }
}

using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Security.Models.Security
{
    public class AppUser : IdentityUser
    {
    }
}

设置数据库上下文

using Microsoft.AspNet.Identity.EntityFramework;
using Security.Models.Security;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace Security.Models.DAL
{
    public class UserContext : IdentityDbContext<AppUser>
    {
        public UserContext() : base("UserContext")
        {
            Database.SetInitializer<UserContext>(new CreateDatabaseIfNotExists<UserContext>());
        }
    }
}

创建角色提供程序并实施以下方法

using Security.Models.DAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace Security.Models.Security
{
    public class AppRoleProvider : RoleProvider
    {
        public override string[] GetAllRoles()
        {
            using (var userContext = new UserContext())
            {
                return userContext.Roles.Select(r => r.Name).ToArray();
            }
        }

        public override string[] GetRolesForUser(string username)
        {
            using (var userContext = new UserContext())
            {
                var user = userContext.Users.SingleOrDefault(u => u.UserName == username);
                var userRoles = userContext.Roles.Select(r => r.Name);

                if (user == null)
                    return new string[] { };
                return user.Roles == null ? new string[] { } :
                    userRoles.ToArray();
            }
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            using (var userContext = new UserContext())
            {
                var user = userContext.Users.SingleOrDefault(u => u.UserName == username);
                var userRoles = userContext.Roles.Select(r => r.Name);

                if (user == null)
                    return false;
                return user.Roles != null &&
                    userRoles.Any(r => r == roleName);
            }
        }
    }
}

编辑您的web.config以设置数据库连接和角色提供程序参考

<connectionStrings>
    <add name="UserContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UserContext.mdf;Initial Catalog=UserContext;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

<system.web>
    ...
    <authentication mode="Windows" />        
    <roleManager enabled="true" defaultProvider="AppRoleProvider">
      <providers>
        <clear/>
        <add name="AppRoleProvider" type="Security.Models.Security.AppRoleProvider" connectionStringName = "UserContext"/>
      </providers>
      ...
    </roleManager>
  </system.web>

在包管理器控制台中,启用迁移

enable-migrations

在新创建的Configurations.cs中设置用户/角色存储和管理器,并将用户管理器验证器配置为接受'\'字符

namespace Security.Migrations
{
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Security.Models.Security;
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<Security.Models.DAL.UserContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            ContextKey = "Security.Models.DAL.UserContext";
        }

        protected override void Seed(Security.Models.DAL.UserContext db)
        {
            // Set up the role store and the role manager
            var roleStore = new RoleStore<AppRole>(db);
            var roleManager = new RoleManager<AppRole>(roleStore);

            // Set up the user store and the user mananger
            var userStore = new UserStore<AppUser>(db);
            var userManager = new UserManager<AppUser>(userStore);

            // Ensure that the user manager is able to accept special characters for userNames (e.g. '\' in the 'DOMAIN\username')            
            userManager.UserValidator = new UserValidator<AppUser>(userManager) { AllowOnlyAlphanumericUserNames = false };

            // Seed the database with the administrator role if it does not already exist
            if (!db.Roles.Any(r => r.Name == "Administrator"))
            {
                var role = new AppRole { Name = "Administrator" };
                roleManager.Create(role);
            }

            // Seed the database with the administrator user if it does not already exist
            if (!db.Users.Any(u => u.UserName == @"DOMAIN\admin"))
            {
                var user = new AppUser { UserName = @"DOMAIN\admin" };
                userManager.Create(user);
                // Assign the administrator role to this user
                userManager.AddToRole(user.Id, "Administrator");
            }
        }
    }
}

在包管理器控制台中,确保已创建和播种数据库

update-database

创建自定义授权属性,该属性将在失败时重定向到拒绝访问的页面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Security.Models.Security
{
    public class AccessDeniedAuthorizationAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if(filterContext.Result is HttpUnauthorizedResult)
            {
                filterContext.Result = new RedirectResult("~/Home/AccessDenied");
            }
        }
    }
}

你已经完成了!您现在可以创建拒绝访问页面(在本例中为〜/ Home / AccessDenied)并将该属性应用于任何操作,例如

using Security.Models.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Security.Controllers
{
    public class HomeController : Controller
    {
         ...    

        [AccessDeniedAuthorizationAttribute(Roles = "Administrator")]
        public ActionResult SecureArea()
        {
            return View();
        }

        public ActionResult AccessDenied()
        {
            return View();
        }

        ...
    }
}

希望这可以帮助将来的某个人。祝你好运!