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