当前位置: 首页 > 编程语言 > C#

共享

时间:2023-04-11 11:37:30 C#

使用MVC5和OWIN的自定义身份使用MVC5和OWIN的自定义身份我正在尝试使用MVC5和OWIN身份验证向网站的ApplicationUser添加自定义属性。我读过https://stackoverflow.com/a/10524305/264607我喜欢它如何与基本控制器集成以便轻松访问新属性。我的问题是,当我将HTTPContext.Current.User属性设置为我的新IPrincipal时,出现空引用错误:[NullReferenceException:对象引用未设置为对象的实例。]System.Web.Security。UrlAuthorizationModule.OnEnter(Objectsource,EventArgseventArgs)+127System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+136System.Web.HttpApplication.ExecuteStep(IExecutionStepstep,Boolean&completedSynchronous)+136这是我代码:protectedvoidApplication_PostAuthenticateRequest(Objectsender,EventArgse){if(HttpContext.Current.User.Identity.IsAuthenticated){userManager=newUserManager(newUserStore(newApplicationDbContext()));ApplicationUseruser=userManager.FindByName(HttpContext.Current.User.Identity.Name);PatientPortalPrincipalnewUser=newPatientPortalPrincipal();newUser.BirthDate=user.BirthDate;newUser.InvitationCode=user.InvitationCode;newUser.PatientNumber=user.PatientNumber;//声明cPatient=newClaim(typeof(PatientPortalPrincipal).ToString(),);HttpContext.Current.User=newUser;}}publicclassPatientPortalPrincipal:ClaimsPrincipal,IPatientPortalPrincipal{publicPatientPortalPrincipal(ApplicationUseruser){Identity=newGenericIdentity(user.UserDthName);出生日期;邀请码=user.InvitationCode;}publicPatientPortalPrincipal(){}publicnewboolIsInRole(stringrole){if(!string.IsNullOrWhiteSpace(role))returnRole.ToString().Equals(role);返回假;}publicnewIIdentityIdentity{get;私有集;}公共WindowsBuiltInRole角色{get;放;}publicDateTimeBirthDate{get;放;}publicstringInvitationCode{get;放;}publicstringPatientNumber{get;IPatientPortalPrincipal:IPrincipal{WindowsBuiltInRole角色{get;放;}DateTime出生日期{get;放;}stringInvitationCode{得到;放;}stringPatientNumber{得到;放;,我读过这些文章:http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspxhttp://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(这是用户的具体类)我倾向于使用声明,但我需要知道在哪里将这些新声明添加到用户。尽管它声称是要走的路,但我很好奇我的自定义IPrincipal有什么问题,因为我似乎已经实现了它需要的一切。我能够使用基于声明的安全性来实现一些工作,所以如果你想快速做一些事情,我现在拥有的是:在AccountController的登录过程中(我的是SignInAsync方法),添加到UserManager新创建的身份声明:私有异步任务SignInAsync(ApplicationUseruser,boolisPersistent){AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);varidentity=awaitUserManager.CreateIdentityAsync(用户,DefaultAuthenticationTypes.ApplicationCookie);identity.AddClaim("PatiumberClaim(new,user.PatientNumber));//这是我添加的属性:私有字符串_patientNumber;公共字符串PatientNumber{get{if(string.IsNullOrWhiteSpace(_patientNumber)){try{varcp=ClaimsPrincipal.Current.Identities.First();varpatientNumber=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属性问题是我在PatientPortalPrincipal类上提供了一个默认构造函数,它没有设置标识属性。我最终做的是删除默认构造函数并从Application_PostAuthenticateRequest调用正确的构造函数,更新后的代码如下新UserManager(新UserStore(新ApplicationDbContext()));ApplicationUseruser=userManager.FindByName(HttpContext.Current.User.Identity.Name);PatientPortalPrincipalnewUser=newPatientPortalPrincipal(user);newUser.BirthDate=user.BirthDate;newUser.InvitationCode=user.InvitationCode;newUser.PatientNumber=user.PatientNumber;//声明cPatient=newClaim(typeof(PatientPortalPrincipal).ToString(),);HttpContext.Current.User=newUser;}}这使得整个事情工作!您会遇到异常,因为HttpContext.Current.User.Identity.IsAuthenticated在检查点返回false(HttpContext.Current.Request.IsAuthenticated也是如此)。如果删除if(HttpContext.Current.User.Identity.IsAuthenticated)语句,它工作正常(至少这部分代码)。我尝试过这样一个简单的事情:BaseController.cspublicabstractclassBaseController:Controller{protectedvirtualnewCustomPrincipalUser{get{}}}CustomPrincipal.cs公共类CustomPrincipal:IPrincipal{publicIIdentityIdentity{get;私有集;}publicboolIsInRole(stringrole){returnfalse;}publicCustomPrincipal(stringusername){this.Identity=newGenericIdentity(username);}publicDateTimeBirthDate{get;放;}publicstringInvitationCode{get;放;}publicintPatientNumber{get;放;}}的Global.asax.csprotectedvoidApplication_PostAuthenticateRequest(Objectsender,EventArgse){CustomPrincipalcustomUser=newCustomPrincipal(User.Identity.Name);customUser.BirthDate=DateTime.Now;customUser.InvitationCode="1234567890A";customUser.PatientNumber=100;HttpContext.Current.User=customUser;}HomeController.cspublicActionResultIndex(){ViewBag.BirthDate=User.BirthDate;ViewBag.InvitationCode=User.InvitationCode;ViewBag.PatientNumber=User.PatientNumber;返回视图();这工作正常,所以除非这段代码:userManager=newUserManager(newUserStore(newApplicationDbContext()));ApplicationUseruser=userManager.FindByName(HttpContext.Current.User.Identity.Name);不返回有效(自定义)用户对象,问题出在if()语句上。您的更新看起来不错,如果您愿意将数据作为语句存储在cookie中,您可以使用它,尽管我个人讨厌那里的try{}catch块。我所做的是:BaseController.cs[AuthorizeEx]publicabstractpartialclassBaseController:Controller{publicIOwinContextOwinContext{get{returnHttpContext.GetOwinContext();}}publicnewClaimsPrincipalUser{get{returnbase.UserasClaimsPrincipal;}}publicWorkContextWorkContext{get;放;我用自定义属性装饰基控制器类。AuthorizeExAttribute.cs:publicclassAuthorizeExAttribute:AuthorizeAttribute{publicoverridevoidOnAuthorization(AuthorizationContextfilterContext){Ensure.Argument.NotNull(filterContext);base.OnAuthorization(filterContext);IPrincipaluser=filterContext.HttpContext.User;如果(user.Identity.IsAuthenticated){varctrl=filterContext.ControllerasBaseController;ctrl.WorkContext=newWorkContext(user.Identity.Name);}}}和WorkContext.cs:publicclassWorkContext{privatestring_email;私人惰性当前用户;私有IAuthenticationServiceauthService;私有ICacheManager缓存管理器;publicUserCurrentUser{get{varcachedUser=cacheManager.Get(Constants.CacheUserKeyPrefix+this._email);if(cachedUser!=null){返回cachedUser;}else{varuser=currentUser.Value;cacheManager.Set(Constants.CacheUserKeyPrefix+this._email,user,30);返回用户;}}}publicWorkContext(stringemail){Ensure.Argument.NotNullOrEmpty(电子邮件);this._email=电子邮件;this.authService=DependencyResolver.Current.GetService();this.cacheManager=DependencyResolver.Current.GetService();this.currentUser=newLazy(()=>authService.GetUserByEmail(email));然后我像这样访问WorkContext:publicclassDashboardController:BaseController{publicActionResultIndex(){ViewBag.User=WorkContext.CurrentUser;返回视图();我正在使用Ninject的DependencyResolver来解析authService和cacheManager但我相信你可以跳过缓存并用ASP.NETIdentityUserManager替换authService我也想给予应有的信任,因为WorkContext类的灵感来自NugetGallery项目。我敢打赌HttpContext.Current.User为空。所以不是这个:如果(HttpContext.Current.User.Identity.IsAuthenticated)你可以试试这个:如果(HttpContext.Current.Request.IsAuthenticated)我有同样的错误。我的问题是我没有为匿名用户在IPrincipal上设置IIdentity。我只在用户使用他们的用户名登录时才这样做。否则,IIdentity为空。我的解决方案是始终设置IIdentity。如果用户未通过身份验证(匿名用户),则IIdentity.IsAuthenticated将设置为false。否则,是的。我的代码:以上是C#学习教程:使用MVC5和OWIN的自定义标识,分享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注~Browser=RequestHelper.GetBrowserFromCurrentRequest(HttpContext.Current.Request),/*用户未通过身份验证,但无论如何都必须设置身份。如果没有发生,err/Identity=newIdentityCustom{IsAuthenticated=false}};}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢