案例:我有一个MVC5应用程序(基本上是带有脚手架视图的MVC5模板),启用了Google身份验证方法.该应用程序已经被配置成接受电子邮件作为用户名和存储来自谷歌分配了类似的姓,给定名称,电子邮件的NameIdentifier等方面的要求,对会员数据库(AspNetUserClaims).
当我注册并使用"本地"用户登录时,一切都很好.如果我使用Google用户登录,则可以.如果我使用设置为同时具有本地和外部登录的帐户登录,则会收到以下错误.
我尝试使用Application_Start中的AntiForgeryConfig选项将令牌的类型更改为不同的设置(示例)
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
但是,当组合本地和外部登录时,似乎所有声明都是重复的.最奇怪的是,声明集合(我假设有答案)对于组合和外部唯一登录是相同的.
以本地用户身份登录时,将分配这些声明
[0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: a71ff9c0-8dc4-478b-a6f1-2c4cc34b1e46} [1]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: some@email.com} [2]: {http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider: ASP.NET Identity}
使用仅限远程帐户或组合帐户登录时,claim-list如下所示
[0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: 4ab33d77-c2a0-4eff-a759-5cca4323ecbf} [1]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: some.other@email.com} [2]: {http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider: ASP.NET Identity} [3]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: https://www.google.com/accounts/o8/id?id=AitOGoogleIdentifierRemovedForPrivacygwgwgw} [4]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: some.other@email.com} [5]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname: Other} [6]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname: Some} [7]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: Some Other Person}
任何帮助都感激不尽!
Server Error in '/' Application. Sequence contains more than one matching element Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.InvalidOperationException: Sequence contains more than one matching element
Source Error: Line 10: @using (Html.BeginForm()) Line 11: { Line 12: @Html.AntiForgeryToken() Line 13: Line 14:Source File: x:\someweb\Views\someEntity\Create.cshtml Line: 12
Stack Trace: [InvalidOperationException: Sequence contains more than one matching element] System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source, Func`2 predicate) +2533810 System.Web.Helpers.AntiXsrf.ClaimUidExtractor.GetUniqueIdentifierParameters(ClaimsIdentity claimsIdentity, String uniqueClaimTypeIdentifier) +701 System.Web.Helpers.AntiXsrf.ClaimUidExtractor.ExtractClaimUid(IIdentity identity) +186 System.Web.Helpers.AntiXsrf.TokenValidator.GenerateFormToken(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken) +242 System.Web.Helpers.AntiXsrf.AntiForgeryWorker.GetTokens(HttpContextBase httpContext, AntiForgeryToken oldCookieToken, AntiForgeryToken& newCookieToken, AntiForgeryToken& formToken) +174 System.Web.Helpers.AntiXsrf.AntiForgeryWorker.GetFormInputElement(HttpContextBase httpContext) +109 System.Web.Helpers.AntiForgery.GetHtml() +146 System.Web.Mvc.HtmlHelper.AntiForgeryToken() +39 ASP._Page_Views_Bruker_Create_cshtml.Execute() in x:\prosjekter\Laudi\TFS\Laudi\IWeb\Inspector\Inspector\Views\Bruker\Create.cshtml:12 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +271 System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +120 System.Web.WebPages.StartPage.RunPage() +63 System.Web.WebPages.StartPage.ExecutePageHierarchy() +100 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +131 System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +695 System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +382 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +431 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +116 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +106 System.Web.Mvc.Async.<>c__DisplayClass28.b__19() +321 System.Web.Mvc.Async.<>c__DisplayClass1e. b__1b(IAsyncResult asyncResult) +185 System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40 System.Web.Mvc.Controller. b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44 System.Web.Mvc.Controller. b__15(IAsyncResult asyncResult, Controller controller) +39 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39 System.Web.Mvc.MvcHandler. b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +39 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9688704 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Adi Bilauca.. 12
从以下方法(在创建用户标识时调用)可以看出,行为是正常的:
await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)在
SignInAsync
方法中.在执行中CreateIdentityAsync
:... ClaimsIdentity claimsIdentity = new ClaimsIdentity(authenticationType, this.UserNameClaimType, this.RoleClaimType); claimsIdentity.AddClaim(new Claim(this.UserIdClaimType, user.Id, "http://www.w3.org/2001/XMLSchema#string")); claimsIdentity.AddClaim(new Claim(this.UserNameClaimType, user.UserName, "http://www.w3.org/2001/XMLSchema#string")); claimsIdentity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string")); if (manager.SupportsUserRole) { foreach (string rolesAsync in await manager.GetRolesAsync(user.Id)) { claimsIdentity.AddClaim(new Claim(this.RoleClaimType, rolesAsync, "http://www.w3.org/2001/XMLSchema#string")); } } if (manager.SupportsUserClaim) { claimsIdentity.AddClaims(await manager.GetClaimsAsync(user.Id)); } ...如您所见,默认情况下添加了三个声明.向他们添加您的"自定义"声明.这就是为什么你会有重复的声明,这意味着
SingleOrDefault
对声明集合的调用将抛出你提到的错误.作为一种解决方案,您可以使用其他声明更新它们,在创建身份后,它可以满足您的业务需求.1 个回答
从以下方法(在创建用户标识时调用)可以看出,行为是正常的:
await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)在
SignInAsync
方法中.在执行中CreateIdentityAsync
:... ClaimsIdentity claimsIdentity = new ClaimsIdentity(authenticationType, this.UserNameClaimType, this.RoleClaimType); claimsIdentity.AddClaim(new Claim(this.UserIdClaimType, user.Id, "http://www.w3.org/2001/XMLSchema#string")); claimsIdentity.AddClaim(new Claim(this.UserNameClaimType, user.UserName, "http://www.w3.org/2001/XMLSchema#string")); claimsIdentity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string")); if (manager.SupportsUserRole) { foreach (string rolesAsync in await manager.GetRolesAsync(user.Id)) { claimsIdentity.AddClaim(new Claim(this.RoleClaimType, rolesAsync, "http://www.w3.org/2001/XMLSchema#string")); } } if (manager.SupportsUserClaim) { claimsIdentity.AddClaims(await manager.GetClaimsAsync(user.Id)); } ...如您所见,默认情况下添加了三个声明.向他们添加您的"自定义"声明.这就是为什么你会有重复的声明,这意味着
SingleOrDefault
对声明集合的调用将抛出你提到的错误.作为一种解决方案,您可以使用其他声明更新它们,在创建身份后,它可以满足您的业务需求.2023-02-10 10:16 回答媣栺葒尘_383撰写答案