Blazor SignInManager PasswordSignIn() 方法抛出 InvalidOperationException

Posted

技术标签:

【中文标题】Blazor SignInManager PasswordSignIn() 方法抛出 InvalidOperationException【英文标题】:Blazor SignInManager PasswordSignIn() method throws InvalidOperationException 【发布时间】:2020-10-18 15:38:47 【问题描述】:

我正在开发一个 Blazor 服务器端项目,我目前正在为其创建自定义登录页面。由于我对 Web 应用了解不多(这就是我使用 blazor 的原因),所以目前发布在 ***/github 上的可能解决方案对我不起作用。

直截了当:我希望内置的SignInManager 来处理用户提供的凭据的验证。这些凭据被设置为FormLoginUser 类实例的属性。

公共类 FormLoginUser

    [必填,DataType(DataType.EmailAddress)]
    公共字符串电子邮件获取;放; 

    [必需的]
    公共字符串密码获取;放; 

登录页面的代码如下:

公共类 LoginBase : ComponentBase

    [注入]
    私人用户管理器用户管理器得到;放; 

    [注入]
    私人 SignInManager signInManager  获取;放; 

    [注入]
    私人 NavigationManager NavigationManager  获取;放; 

    受保护的 FormLoginUser 用户  获取;放; 

    受保护的布尔 IsLoginFailed  获取;放; 

    受保护的覆盖无效 OnInitialized()
    
        base.OnInitialized();
        IsLoginFailed = 假;
        用户 = 新的 FormLoginUser();
    

    受保护的异步任务 ValidateUser()
    
        SignInResult 结果 = 等待 signInManager.PasswordSignInAsync(
            用户名:用户.电子邮件,
            密码:用户密码,
            是持久的:真,
            lockoutOnFailure: false);
        如果(结果。成功)
            NavigationManager.NavigateTo("/");
        别的
            IsLoginFailed = true;
        应该渲染();
    

当用户提交登录表单时,方法ValidateUser() 被调用,此时User 属性将被表单中的数据填充。 ValidateUser() 方法的第一行马上就出错了。

这是抛出的异常:

Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: The response headers cannot be modified because the response has already started.

System.InvalidOperationException: The response headers cannot be modified because the response has already started.
   at Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.ThrowIfReadOnly()
   at Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.set_Item(String key, StringValues value)
   at Microsoft.AspNetCore.Http.ResponseCookies.Append(String key, String value, CookieOptions options)
   at Microsoft.AspNetCore.Authentication.Cookies.ChunkingCookieManager.AppendResponseCookie(HttpContext context, String key, String value, CookieOptions options)
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, String scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Identity.SignInManager`1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable`1 additionalClaims)
   at Microsoft.AspNetCore.Identity.SignInManager`1.SignInOrTwoFactorAsync(TUser user, Boolean isPersistent, String loginProvider, Boolean bypassTwoFactor)
   at Microsoft.AspNetCore.Identity.SignInManager`1.PasswordSignInAsync(TUser user, String password, Boolean isPersistent, Boolean lockoutOnFailure)
   at Microsoft.AspNetCore.Identity.SignInManager`1.PasswordSignInAsync(String userName, String password, Boolean isPersistent, Boolean lockoutOnFailure)
   at EvaluationPortal.Pages.Authentication.LoginBase.ValidateUser() in C:\dev\EvaluationPortal\Src\EvaluationPortal\Pages\Authentication\Login.razor.cs:line 33
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost: Error: Unhandled exception in circuit 'j2FiQ7xmyQgNWl9lQDS5yHURzyFSUDlJyCeOu33qd-8'.

System.InvalidOperationException: The response headers cannot be modified because the response has already started.
   at Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.ThrowIfReadOnly()
   at Microsoft.AspNetCore.HttpSys.Internal.HeaderCollection.set_Item(String key, StringValues value)
   at Microsoft.AspNetCore.Http.ResponseCookies.Append(String key, String value, CookieOptions options)
   at Microsoft.AspNetCore.Authentication.Cookies.ChunkingCookieManager.AppendResponseCookie(HttpContext context, String key, String value, CookieOptions options)
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, String scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Identity.SignInManager`1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable`1 additionalClaims)
   at Microsoft.AspNetCore.Identity.SignInManager`1.SignInOrTwoFactorAsync(TUser user, Boolean isPersistent, String loginProvider, Boolean bypassTwoFactor)
   at Microsoft.AspNetCore.Identity.SignInManager`1.PasswordSignInAsync(TUser user, String password, Boolean isPersistent, Boolean lockoutOnFailure)
   at Microsoft.AspNetCore.Identity.SignInManager`1.PasswordSignInAsync(String userName, String password, Boolean isPersistent, Boolean lockoutOnFailure)
   at EvaluationPortal.Pages.Authentication.LoginBase.ValidateUser() in C:\dev\EvaluationPortal\Src\EvaluationPortal\Pages\Authentication\Login.razor.cs:line 33
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

有没有人知道可能导致此问题的原因,我一直在寻找整个互联网,但似乎找不到任何可以为我解决此问题的方法。请帮忙。

【问题讨论】:

【参考方案1】:

我在 Blazor 身份验证方面也遇到了很多问题,但 this tutorial 确实帮了我大忙。

我相信他实施的身份验证与您尝试使用的身份验证相同(Microsoft 身份)。

【讨论】:

感谢您向我指出这一点,但是如果您在启动时选择用户授权,这些教程基本上只会重新创建您开箱即用的内容。我正在寻找的是为什么SignInManager 不允许我登录用户。

以上是关于Blazor SignInManager PasswordSignIn() 方法抛出 InvalidOperationException的主要内容,如果未能解决你的问题,请参考以下文章

外部 UserManager 和内存中 SignInManager

_signInManager.GetExternalLoginInfoAsync() 为 Apple 登录返回 null

Identity 3 SignInManager.PasswordSignInAsync() 不返回任何结果

SignInManager.PasswordSignInAsync() 成功,但 User.Identity.IsAuthenticated 为 false

ASP.Net Core SignInManager lockoutOnFailure

是否必须在 SignInManager 中使用 IdentityUser?