Identidade personalizada usando MVC5 e OWIN
Estou tentando adicionar propriedades personalizadas ao ApplicationUser para um site usando a autenticação MVC5 e OWIN. Eu lihttps://stackoverflow.com/a/10524305/264607 e gosto de como ele se integra ao controlador base para facilitar o acesso às novas propriedades. Meu problema é que, quando defino a propriedade HTTPContext.Current.User como meu novo IPrincipal, recebo um erro de referência nula:
[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
Aqui está o meu código:
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; }
}
Não encontrei muita documentação sobre como fazer isso. Li estes artigos:
Os comentários no segundo link apontaram para talvez usar reivindicações (http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp), mas o artigo vinculado a não mostra como adicioná-los a umIPrincipal
(que é o queHttpContext.Current.User
é) ou onde no pipeline você deve adicioná-los a umClaimsIdentity
(que é a classe concreta doUser
é). Estou inclinado a usar reivindicações, mas preciso saber onde adicionar essas novas reivindicações ao usuário.
Mesmo que as reivindicações sejam o caminho a seguir, estou curioso para saber o que estou fazendo de errado com meu IPrincipal personalizado, pois pareço ter implementado tudo o que é necessário.