I am building a intranet application using MVC3 with a MSSQL backend. I have authentication and roles (through a custom roles provider) working properly.
Instead of doing it this way, you should override the Application_AuthenticateRequest method in global.asax, then use Current.User rather than HttpContext.Current.User (not sure why, but there is a difference).
Then, an easy way to access this in your controller is to create an extension method? Something like this:
public static class IIdentityExtensions {
public static IMyIdentity MyIdentity(this IIdentity identity) {
return (IMyIdentity)identity;
}
}
then you can just say User.Identity.IMyIdenty().FirstName
. You could probably do this as a property as well.
Here is the code I use:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
FormsAuthenticationTicket authTicket = FormsAuthentication
.Decrypt(authCookie.Value);
var identity = new MyIdentity(authTicket.Name, "Forms",
FormsAuthenticationHelper.RetrieveAuthUserData(authTicket.UserData));
Context.User = new GenericPrincipal(identity,
DependencyResolver.Current.GetService<ISecurityHandler>()
.GetRoles(identity.Name).ToArray());
}
Now, ignoring the DependencyResolver stuff and the custom auth ticket stuff, this is pretty basic and works correctly for me.
Then, in my app, when i'm need info from my custom identity, i just cast it with ((IMyIdentity)User.Identity).FirstName
or whatever I need. It's not rocket science, and it works.
What am I doing wrong?
Probably the [Authorize]
attribute is overriding your changes. So instead of doing this in the WindowsAuthentication_OnAuthenticate
method in your Global.asax
write a custom Authorize
attribute, like so:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var user = httpContext.User as WindowsIdentity;
CPrincipal cPrincipal = new CPrincipal(user);
httpContext.User = cPrincipal;
return true;
}
}
and then use your custom attribute instead of the default one:
[MyAuthorize]
public ActionResult SomeAction()
{
// User.Identity will be your custom principal here
}
In ASP.NET MVC the standard way to perform authorization is through authorization action filters, not through events in Global.asax.