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

     ... 
    } 
} 

希望這可以幫助未來的人。祝你好運!

相關問題