【发布时间】:2014-03-07 22:32:51
【问题描述】:
我尝试将自定义属性添加到使用 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; }
}
我没有找到太多关于如何做到这一点的文档,我已经阅读了这些文章:
第二个链接中的 cmets 指出我可能使用了声明 (http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp) ,但链接到的文章没有显示如何将它们添加到 IPrincipal (这就是 HttpContext.Current.User 是什么),或者在管道中,您应该将它们添加到ClaimsIdentity(这是User 的具体类)。我倾向于使用声明,但我需要知道在哪里向用户添加这些新声明。
即使声明是要走的路,我也很好奇我的自定义 IPrincipal 做错了什么,因为我似乎已经实现了它所需的一切。
【问题讨论】:
-
把我之前的更新移到了一个答案,好像更合适
-
这是我写的一个例子,它利用了像
AuthenticationFilter这样的 MVC5 特性:http://stackoverflow.com/a/25731422/264672 -
嗨,黑冰。你是如何让这些角色发挥作用的?
WindowsBuiltInRole是什么?我还遵循了 LukeP 的确切代码(在您链接的线程中),但对我来说,当我执行[Authorize(Roles="Admin")]时它不起作用。 -
@Ciwan WindowsBuiltInRole 是来自 Windows 安全的枚举,msdn.microsoft.com/en-us/library/…
-
没关系,事实证明 LukeP 的答案是“旧的”。在 MVC5 上,我们假设使用 Claims。这是真的!效果很好。
标签: c# asp.net-mvc-5 claims-based-identity owin iprincipal