服务器端Blazor Asp.Net身份SignInAsync错误:无法修改响应头

时间:2019-06-26 22:42:32

标签: asp.net-core blazor-server-side asp.net-core-3.0

我正在尝试通过Blazor在Visual Studio模板应用程序中使用Asp.Net Identity登录,它仍然使用Razor Pages和MVC进行登录,但只能使其在事件OnInitAsync下使用,这没什么用,因为它需要在单击按钮时完成,而不是在页面加载时完成。

我的失败代码是

protected async Task LoginTest()
{
   await _SignInManager.SignInAsync(new ApplicationUser()
   { UserName = "test@test.com" }, true);
   UriHelper.NavigateTo("/", true);
}

我得到了错误:

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.Internal.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 WebApplication3.Pages.Account.Login.RegUser() in C:\Users\david\source\repos\WebApplication3\WebApplication3\Pages\Account\Login.razor:line 28
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.Rendering.Renderer.GetErrorHandledTask(Task taskToHandle)

有人能成功完成这项工作吗?正如我提到的,如果将上面的函数放在OnInitAsync方法中,我可以使它正常工作,但是在那做不好。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

我发现了与此相关的GitHub问题http://github.com/aspnet/AspNetCore/issues/11411

我最终使用重定向后获取方法创建了一个变通解决方案。在帖子中,我使用用户详细信息对登录令牌进行了加密,然后将其作为查询字符串(带有查询字符串中的令牌)传递给另一个页面,然后读取加密的令牌并登录用户。

答案 1 :(得分:0)

您能否提供一些示例代码来说明如何实现您的解决方法?我刚刚花了大约5个小时来处理此问题,但无法解决。

答案 2 :(得分:0)

在阅读了 David Hawkins 帖子并进行了一些挖掘之后,我找到了他在 https://github.com/dotnet/aspnetcore/issues/13601#issuecomment-679870698 中描述的解决方法。简单有效。

在建议的解决方案中,中间件中没有对用户/密码详细信息进行加密,因为它保留在服务器上。

截至目前(2021 年 4 月),ASP.Net Core 5 和 Identity 似乎不支持 Blazor 调用 SignInManager*SignIn 方法。到它被调用时,HTTP 标头已经发送,也不能修改/附加。