I trying to add custom properties to the ApplicationUser for a web site using MVC5 and OWIN authentication. I've read https://mcmap.net/q/63665/-asp-net-mvc-set-custom-iidentity-or-iprincipal and I like how it integrates with the base controller for easy access to the new properties. My issue is that when I set the HTTPContext.Current.User property to my new IPrincipal I get a null reference error:
[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.Security.UrlAuthorizationModule.OnEnter(Object source, EventArgs eventArgs) +127
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
Here is my code:
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
ApplicationUser user = userManager.FindByName(HttpContext.Current.User.Identity.Name);
PatientPortalPrincipal newUser = new PatientPortalPrincipal();
newUser.BirthDate = user.BirthDate;
newUser.InvitationCode = user.InvitationCode;
newUser.PatientNumber = user.PatientNumber;
//Claim cPatient = new Claim(typeof(PatientPortalPrincipal).ToString(), );
HttpContext.Current.User = newUser;
}
}
public class PatientPortalPrincipal : ClaimsPrincipal, IPatientPortalPrincipal
{
public PatientPortalPrincipal(ApplicationUser user)
{
Identity = new GenericIdentity(user.UserName);
BirthDate = user.BirthDate;
InvitationCode = user.InvitationCode;
}
public PatientPortalPrincipal() { }
public new bool IsInRole(string role)
{
if(!string.IsNullOrWhiteSpace(role))
return Role.ToString().Equals(role);
return false;
}
public new IIdentity Identity { get; private set; }
public WindowsBuiltInRole Role { get; set; }
public DateTime BirthDate { get; set; }
public string InvitationCode { get; set; }
public string PatientNumber { get; set; }
}
public interface IPatientPortalPrincipal : IPrincipal
{
WindowsBuiltInRole Role { get; set; }
DateTime BirthDate { get; set; }
string InvitationCode { get; set; }
string PatientNumber { get; set; }
}
I haven't found much in the way of documentation on how to do this, I've read these articles:
The comments in the second link pointed me to perhaps using claims (http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp) , but the article linked to doesn't show how to add those to an IPrincipal
(which is what HttpContext.Current.User
is), or where in the pipeline you're supposed to add them to a ClaimsIdentity
(which is the concrete class the User
is). I'm leaning towards using claims, but I need to know where to add these new claims to the user.
Even if claims are the way to go, I'm curious as to what I'm doing wrong with my custom IPrincipal, as I seem to have implemented everything it requires.
AuthenticationFilter
for this purpose: https://mcmap.net/q/66053/-how-can-i-get-the-specific-fields-of-the-currently-logged-in-user-in-mvc5 – FeuchtwangerWindowsBuiltInRole
? I also followed exact code as LukeP (in thread you linked) but for me when I do[Authorize(Roles="Admin")]
it doesn't work. – Natashianatassia