我尝试使用 MVC5 和 OWIN 身份验证为网站的 ApplicationUser 添加自定义属性。我已经阅读了https://stackoverflow.com/a/10524305/264607并且我喜欢它如何与基本控制器集成以轻松访问新属性。我的问题是,当我将 HTTPContext.Current.User 属性设置为我的新 IPrincipal 时,我得到一个空引用错误:
[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
这是我的代码:
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; }
}
我没有找到太多关于如何做到这一点的文档,我已经阅读了这些文章:
第二个链接中的评论指出我可能使用声明(http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp),但文章链接to 没有显示如何将它们添加到IPrincipal
(这是什么HttpContext.Current.User
),或者您应该在管道中的哪个位置将它们添加到 a ClaimsIdentity
(这是具体的类User
)。我倾向于使用声明,但我需要知道在哪里向用户添加这些新声明。
即使索赔是要走的路,我也很好奇我的自定义 IPrincipal 做错了什么,因为我似乎已经实现了它所需的一切。