Can you wrap the RolePrincipal in a custom IPrinci

2019-03-21 08:34发布

I am using custom Membership and Role providers inside the ASP.NET framework with Forms Authentication. These are working great. The Role provider is using a cookie to persist the roles, saving a trip to the database on each web request. I am also using the UserData string inside the FormsAuthenticationTicket to store the UserId.

I need to refactor my DAL out of the web project to its own project. The DAL has a dependency on retrieving the Current user’s ID as well as checking the roles for rights. How should my Authentication system change so I can use the Thread.CurrentPrincipal without referencing System.Web in the DAL project?

Currently the Provider Framework creates a RolePrincipal and FormsIdentity object and attaches it the the Thread.CurrentPrincipal.

I thought about creating a custom IPrincipal wrapper around the RolePrincipal during the Application_PostAuthenticateRequest event. In this event I can get the UserID from the FormsAuthenticalTicket and pass it to this new wrapperPrincipal along with the RolePrincipal.

Is this a valid approach? Will I end up causing some issues farther down in the project by messing with the Provider structure?

Thank you, Keith

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条回答
淡お忘
2楼-- · 2019-03-21 09:08

i came across this question recently when i was trying to implement custom principal too. I did wrapper too and i think it is valid. It works perfectly with LukeP's approach in ASP.NET MVC - Set custom IIdentity or IPrincipal. You cant mess anything because it is just wrapper, u just delegete origin principal members, you dont even touch it. I would call it clever solution.

查看更多
登录 后发表回答