你能不能把角色主体包装在自定义的IPrincipal对象中



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

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

目前,提供程序框架创建一个 RolePrincipal 和 FormsIdentity 对象,并将其附加到 Thread.CurrentPrincipal。

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

这是一种有效的方法吗? 我最终会通过弄乱提供程序结构而导致项目中更远处的一些问题吗?

谢谢基思

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

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

最新更新