gpt4 book ai didi

c# - 使用 MVC5 和 OWIN 的自定义标识

转载 作者:IT王子 更新时间:2023-10-29 04:30:56 25 4
gpt4 key购买 nike

我尝试将自定义属性添加到使用 MVC5 和 OWIN 身份验证的网站的 ApplicationUser。我读过 https://stackoverflow.com/a/10524305/264607我喜欢它如何与基本 Controller 集成以便轻松访问新属性。我的问题是,当我将 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://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx

http://blogs.msdn.com/b/webdev/archive/2013/07/03/understanding-owin-forms-authentication-in-mvc-5.aspx

第二个链接中的评论指出我可能使用声明(http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp),但是链接到的文章没有显示如何将这些添加到 IPrincipal(这就是 HttpContext.Current.User 是),或者在管道中您应该将它们添加到 ClaimsIdentity 的位置(这是 User 的具体类是)。我倾向于使用声明,但我需要知道在哪里向用户添加这些新声明。

即使声明是可行的方法,我也很好奇我的自定义 IPrincipal 做错了什么,因为我似乎已经实现了它需要的一切。

最佳答案

我可以使用基于 Claims 的安全性来完成一些工作,所以如果你想快速完成一些事情,这就是我目前所拥有的:

AccountController 的登录过程中(我的在 SignInAsync 方法中),向 UserManager 创建的身份添加一个新声明:

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim("PatientNumber", user.PatientNumber)); //This is what I added
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

然后在我的 Controller 基类中我简单地添加了一个属性:

private string _patientNumber;
public string PatientNumber
{
get
{
if (string.IsNullOrWhiteSpace(_patientNumber))
{
try
{
var cp = ClaimsPrincipal.Current.Identities.First();
var patientNumber = cp.Claims.First(c => c.Type == "PatientNumber").Value;
_patientNumber = patientNumber;
}
catch (Exception)
{
}
}
return _patientNumber;
}
}

此链接有助于理赔知识:http://msdn.microsoft.com/en-us/library/ms734687.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1


IPrincipal 问题的更新

我追踪到 Identity 属性。问题是我在未设置 Identity 属性的 PatientPortalPrincipal 类上提供了默认构造函数。我最终做的是删除默认构造函数并从 Application_PostAuthenticateRequest 中调用正确的构造函数,更新后的代码如下

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(user);
newUser.BirthDate = user.BirthDate;
newUser.InvitationCode = user.InvitationCode;
newUser.PatientNumber = user.PatientNumber;

//Claim cPatient = new Claim(typeof(PatientPortalPrincipal).ToString(), );

HttpContext.Current.User = newUser;
}
}

这让整个事情都成功了!

关于c# - 使用 MVC5 和 OWIN 的自定义标识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21679836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com