Asp.net mvc 4 表单身份验证和数据库支持的嵌套角色

Asp.net mvc 4 表单身份验证和数据库支持的嵌套角色,asp.net-mvc-4,nhibernate,forms-authentication,Asp.net Mvc 4,Nhibernate,Forms Authentication,我正在阅读迁移遗留应用程序的FormsAuthentication。此应用程序对用户的角色/权限使用以下结构: class Account { public ISet<Role> Roles { get; set; } public static bool Has(Permission permission_) { foreach (Role role in Roles) {

我正在阅读迁移遗留应用程序的FormsAuthentication。此应用程序对用户的角色/权限使用以下结构:

class Account
{
    public ISet<Role> Roles
    {
        get;
        set;
    }

    public static bool Has(Permission permission_)
    {
        foreach (Role role in Roles) {
            if (role.Permissions.Contains(permission_)) {
                return true;
            }
        }

        return false;
    }

}

class Role
{
    public ISet<Permission> Permissions
    {
        get;
        set;
    }
}

public enum Permission
{
    ACCESS_COMPONENT_XYZ
    EDIT_FIELD_ABC
    VIEW_ENTITY_123
}
所有这些都由使用NHibernate的数据库支持。现在,正如我对FormsAuthentication的理解,这使用了一种“一维”角色方法。也就是说,我在AuthenticationToken中只有一个字段可以填写我的权限

我认为我需要以某种方式将帐户实体的所有权限都放入当前经过身份验证的令牌中。我的问题是:我该怎么做?我知道如何进行身份验证,但不知道如何将自定义权限集(例如字符串)放入该令牌

当前我的登录控制器如下所示:

// "Accounts" is a NHibernate repository on the base controller
Account account = Accounts.Unique(form_.Name);

if (account != null) {
    byte[] salt = Convert.FromBase64String(account.Salt);
    byte[] password = Convert.FromBase64String(account.Password);

    if (PWDTK.ComparePasswordToHash(salt, form_.Password, password)) {
        FormsAuthentication.SetAuthCookie(form_.Name, false);
        // How to get the complete set of "account.Roles -> Permission" into the Cookie/Token?
    }
    else {
        throw new AuthenticateException("Wrong credentials");
    }
}
else  {
    throw new AuthenticateException("Wrong credentials");
}

当然,我可以从数据库中获取每个请求的当前帐户,然后在其中设置角色/权限(感谢nhibernate延迟加载等),但鉴于FormsAuthenticate已经提供了类似的功能,这似乎是错误的?

角色应该由角色提供程序处理。在你的情况下,你应该和你自己的角色提供者

登录时,您的代码将不必关心提供角色,框架将使用您在配置中定义的角色提供程序。您只需在成功登录时调用
RedirectFromLoginPage
(如果不想使用内置重定向,则调用
SetAuthCookie


对于检查角色,您应该使用
IsInRole
方法。

谢谢您的提示,这已经很有帮助了。但有一个问题:如何将我的NHibernate存储库放入该类?在本例中,它使用连接字符串进行手动连接,这与我当前构建的所有内容(Fluent NHibernate配置等)背道而驰。有没有办法将这些连接注入提供程序?它只是一个示例提供程序。您应该使用自己选择的数据访问方法(逻辑上是NHibernate)编写自己的。不幸的是,您无法控制角色提供程序的生命周期,因此在其中注入依赖项是很麻烦的。您可以在其
Initialize
方法中执行一些依赖项解析。(通过示例使用
System.Web.Mvc.DependencyResolver.Current.GetService()
),但您的依赖关系框架可能尚未在该步骤中初始化。
// "Accounts" is a NHibernate repository on the base controller
Account account = Accounts.Unique(form_.Name);

if (account != null) {
    byte[] salt = Convert.FromBase64String(account.Salt);
    byte[] password = Convert.FromBase64String(account.Password);

    if (PWDTK.ComparePasswordToHash(salt, form_.Password, password)) {
        FormsAuthentication.SetAuthCookie(form_.Name, false);
        // How to get the complete set of "account.Roles -> Permission" into the Cookie/Token?
    }
    else {
        throw new AuthenticateException("Wrong credentials");
    }
}
else  {
    throw new AuthenticateException("Wrong credentials");
}