I've tried to extend the UserPrincipal method in MVC but I can't figure out why its not working.
My Code:
interface ICustomPrincipal : IPrincipal
{
Guid AuthId { get; set; }
Role UserRole { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
public IIdentity Identity { get; private set; }
public bool IsInRole(string role) { return false; }
public CustomPrincipal(string email)
{
this.Identity = new GenericIdentity(email);
}
public Guid AuthId { get; set; }
public Role UserRole { get; set; }
}
public class CustomPrincipalSerializeModel
{
public Guid AuthId { get; set; }
public Role UserRole { get; set; }
}
My IdentityUser:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public Guid UserIdMatch { get; set; }
public Role Role { get; set; }
}
So When a user is created they get a authId and a role.
When a user login / register:
var user = db.Users.Include(i => i.Role).FirstOrDefault(i => i.UserName == model.Username);
CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
serializeModel.AuthId = user.UserIdMatch;
serializeModel.UserRole = user.Role;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
user.UserName,
DateTime.Now,
DateTime.Now.AddDays(1),
false,
userData
);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
At last in my Global.asax
I have the following code:
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.AuthId = serializeModel.AuthId;
HttpContext.Current.User = newUser;
}
}
It should all be fine in my eyes, but when I call @((User as CustomPrincipalSerializeModel).AuthId)
on any page, It throws the following error:
Object reference not set to an instance of an object.
Note: let say when i debug login. I dont get any error and i can see the cookie has the correct data.
Can someone point out what the problem is?
You are setting the user to be the CustomPrincipal
but then you expect it to be the CustomPrincipalSerializeModel
. Since the two are unrelated, this won't work for sure.
I bet you meant
@((User as CustomPrincipal).AuthId
since the AuthId
property seems to be present in both classes.