【问题标题】:asp.net MVC Controllers and authenticationasp.net MVC 控制器和身份验证
【发布时间】:2012-03-06 07:40:05
【问题描述】:

我有一堆需要应用基于角色的身份验证的控制器和相关视图。我正在考虑拥有一个带有 [authorize] 属性定义的基本控制器,以便我可以让从该基类继承的所有控制器仅在登录后可用。我已经测试过它可以正常工作。我不确定这是否是最佳做法,或者在这种方法中是否会出现任何坑。

将来我需要让某些页面只对特定角色的用户开放。角色列表将来自数据库表。因此,我没有更改所有相关的控制器,而是在它继承的基本控制器中进行更改。这是正确的做法吗?

感谢您的宝贵时间。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 forms-authentication authorization


    【解决方案1】:

    您可以组合任意数量的Authorize 属性。

    即您可以在基本控制器上拥有Authorize 属性,在另一个控制器上拥有更具体的属性(例如指定角色),在控制器操作上拥有最具体的属性(指定角色或用户)

    [Authorize]
    public class BaseController : Controller
    {}
    
    [Authorize(Roles="Administrator")]
    public class AdminController : BaseController
    {
        [Authorize(Roles="SuperUser")]
        public ActionResult SuperSecret()
        {}
    }
    

    它将检查所有属性,只有在任何属性失败时才撤销访问权限。

    将来我需要让某些页面只对特定角色的用户开放。

    这就是基于角色的身份验证的工作原理。

    角色列表将来自数据库表。

    将角色加载到 global.asax 中 OnPostAuthenticate 方法中的自定义 IPrincipal 中。

    所以我没有更改所有相关的控制器,而是在它继承的基本控制器中进行更改。

    在这个要求上我不关注你。您想避免在控制器上指定角色吗?

    【讨论】:

    • 主题发起者希望避免将角色列表附加到他的每个控制器,而是在其他地方指定角色分组。否则,您的建议是完美的(并且是授权方案的默认建议)
    • 您好,有没有使用您在 global.asax 中的 OnPostAuthenticate 方法中提到的自定义 IPrincipal 的示例。据我所知 iPrincipal 存储一个 HttpContext.Current.User 对象。如何将 AppRoles 表中的角色分配给它?
    • 这里有几个例子。在 MSDN 中搜索 custom principal onpostauthenticate 或阅读有关 IPrincipal 的信息
    • 我周末检查了这个...kitsula.com/Article/Custom-Role-Provider-for-MVC ...您如何看待这种方法?它基本上覆盖了 asp.net Roleprovider 类。我尝试调用两个不同的安全页面。但是在我的 CustomRoleProvider 中调用 GetRolesForUser(..) 方法: RoleProvider 类只调用了一次。因此,这意味着只需调用一次数据库即可获取 UserRoles ... 这种方法是否有问题,我现在没有看到,这让您决定改用 IPrincipal?
    【解决方案2】:

    可以为您的控制器使用基本控制器类。

    但是,我认为您不应该将控制器的继承与您的角色层次结构联系起来。我觉得它不干净。

    我会实现一个属性继承树,例如:

    class NormalUserRolesAttribute: AuthorizeAttribute
    class AdvancedUserRolesAttribute: AuthorizeAttribute
    class AdminUserRolesAttribute: AuthorizeAttribute
    

    OnAuthorization 行为略有不同,然后用这些属性标记您的控制器。

    【讨论】:

    • 你能解释一下与[Authorize(Roles = "AdvancedUser")]相比有什么优势吗?在我看来,你只是把事情复杂化了。
    • 请看我对你的回答的评论:)
    • 静止。你的属性和我的建议一样。我只是建议将角色加载到 IPrincipal 中,因为 .NET 中的所有安全功能都使用它
    • 我的方法允许您避免在整个项目中分发[Authorize(Roles="admin1,admin2,admin3,superadmin,hyperadmin,backdoor")],并将角色列表保存在某个位置(在AdminRolesAttribute 定义内),仅此而已
    • 只是角色继承。创建一个名为SuperAdmins 的角色,其中包括来自角色Admin1Admin2 等的所有用户。并使用Authorize(Roles="SuperAdmins")]。该代码属于IAuthorizationService,而不属于多个授权属性。
    猜你喜欢
    • 2023-04-10
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 2012-12-23
    • 2016-05-30
    • 2010-12-30
    • 1970-01-01
    相关资源
    最近更新 更多