MVC2 :: How do I *USE* a Custom IIdentity Class?
I am trying to store a whole truckload of information about a user from a webservice. As this is information about the currently authenticated user, I thought it would make sense to store that information in a custom IIdentity implementation.
The custom MagicMembershipProvider.GetUser(string id, bool userIsOnline)
calls the webservice and returns a MagicMembershipUser
instance with all the fields populated (department, phone number, other employee info).
The custom membership provider and custom membership user both work fine.
What and where is the best way to put the membership user information into the IPrincipal User
object that is accessible in every controller?
I have been trying to wrap my brain around the program flow of security with IIdentity, IPrincipal and Role authorization in an MVC2 application -- but I'm really struggling here and could use some mentoring. There a Internet Ton of articles about the parts, but not much about the whole.
Edit
My best guess so far is to assign the HttpContext.Current.User
in the FormsAuthenticationService
:
public void SignIn(string userName, bool createPersistentCookie)
{
if (String.IsNullOrEmpty(userName))
throw new ArgumentException("Value cannot be null or empty.", "userName");
try
{
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
MagicMembershipUser magicUser = _provider.GetUser("", false)
as MagicMembershipUser;
MagicIdentity identity = new MagicIdentity(userName, magicUser);
GenericPrincipal principal = new GenericPrincipal(identity, null);
HttpContext.Current.User = principal;
}
catch (Exception)
{
throw;
}
}
What and where is the best way to put the membership user information into the IPrincipal User object that is accessible in every controller?
In a custom [Authorize]
filter implementation. You could override the AuthorizeCore method and call the base method and if it returns true query your membership provider and inject the custom magic identity into the context.
Example:
public class MagicAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (isAuthorized)
{
var username = httpContext.User.Identity.Name;
var magicUser = _provider.GetUser(username, false) as MagicMembershipUser;
var identity = new MagicIdentity(username, magicUser);
var principal = new GenericPrincipal(identity, null);
httpContext.User = principal;
}
return isAuthorized;
}
}
Now all that's left is decorate your base controller with the [MagicAuthorize]
attribute.