你可以将RolePrincipal包装在自定义IPrincipal对象中吗?

时间:2012-04-11 21:45:47

标签: asp.net-mvc asp.net-membership wrapper iprincipal

我在ASP.NET框架内使用表单身份验证使用自定义成员身份和角色提供程序。这些都很有效。角色提供程序使用cookie来保留角色,从而在每个Web请求上保存数据库之旅。我还使用FormsAuthenticationTicket中的UserData字符串来存储UserId。

我需要将我的DAL从Web项目重构为自己的项目。 DAL依赖于检索当前用户的ID以及检查权限的角色。 我的身份验证系统应如何更改,以便我可以使用Thread.CurrentPrincipal而无需在DAL项目中引用System.Web?

目前,Provider Framework创建了一个RolePrincipal和FormsIdentity对象,并将它附加到Thread.CurrentPrincipal。

我考虑过在Application_PostAuthenticateRequest事件期间围绕RolePrincipal创建自定义IPrincipal包装器。在这种情况下,我可以从FormsAuthenticalTicket获取UserID,并将其与RolePrincipal一起传递给这个新的wrapperPrincipal。

这是一种有效的方法吗?我是否会因为搞乱提供者结构而在项目中导致更多问题?

谢谢你, 基思

protected void Application_PostAuthenticateRequest()
{
    if (Request.IsAuthenticated)
    {
        FormsIdentity identity = (FormsIdentity)User.Identity;

        if (identity != null)
        {
            FormsAuthenticationTicket ticket = identity.Ticket;

            int id = 1;

            if (identity != null)
            {
                int.TryParse(identity.Ticket.UserData, out id);
            }

            var wrapperPrincipal = new WrapperPrincipal(User, id);
            System.Threading.Thread.CurrentPrincipal = WrapperPrincipal;
        }
    }
}   



[Serializable]
public class WrapperPrincipal : IPrincipal
{        
    private IPrincipal principal;

    public WrapperPrincipal(IPrincipal principal, int userId)
    {
        this.principal = principal;
        this.Id = userId;
    }

    public int Id { get; set; }

    public IIdentity Identity
    {
        get { return principal.Identity; }
    }

    public bool IsInRole(string role)
    {
        return principal.IsInRole(role);
    }
}

1 个答案:

答案 0 :(得分:0)

我最近在尝试实施自定义委托时遇到了这个问题。我也做包装,我认为它是有效的。它与ASP.NET MVC - Set custom IIdentity or IPrincipal中的LukeP方法完美配合。 你不能弄乱任何东西,因为它只是包装,你只是删除原始主要成员,你甚至不接触它。我会称之为聪明的解决方案。