6

对于ASP MVC来说相对较新,我不确定哪个更适合我的需求。我已经使用Windows身份验证构建了一个Intranet站点,并且我能够使用Active Directory角色保护控制器和操作,例如,ASP.NET MVC如何创建一个自定义角色提供者

我需要定义独立于AD角色的自己的安全角色。所需的功能是根据与我的应用程序数据库中的配置文件相关的一个或多个角色,例如:“经理”,“用户”,“客户”,“分析师”,“开发人员”等,授权用户被授予访问特定操作的权限。

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

编辑:编辑标题和问题,使其他用户更容易识别帖子的内容。

+0

我认为要求最好/最干净的方式会得到很多不同的答案。一种好的方法是自上而下的。也就是 - 在控制器级授权,然后根据需要限制方法/操作级别。您也可以实施区域基础控制器,然后该区域中的每个控制器实施基础。如果授权级别不符合,区域基础控制器可以重定向到适当的页面。 – Benthon

回答

8

我的解决方案是创建一个自定义角色提供程序。下面是我的步骤,万一别人需要帮助后:

创建自定义的用户和角色等级

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 

在新创建的配置。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(); 
     } 

     ... 
    } 
} 

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

相关问题