【问题标题】:Response already started Exception has been thrown on HttpContext.SignOutAsync() method call in Blazor响应已开始 Blazor 中的 HttpContext.SignOutAsync() 方法调用引发异常
【发布时间】:2020-09-28 06:41:34
【问题描述】:

我正在尝试在我的 ASP.NET 核心 Blazor 服务器应用程序中使用 HttpContext.SignOutAsync() 来注销当前用户。调用 Httpcontext.SignOutAsync() 时已引发异常。有谁知道如何解决这个问题?提前致谢。以下是异常的详细信息:

消息:

响应已经开始

堆栈跟踪:

在 Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.OnStarting(Func2 callback, Object state) at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.OnStarting(Func2 回调,对象状态) 在 Microsoft.AspNetCore.Http.DefaultHttpResponse.OnStarting(Func2 callback, Object state) at Microsoft.AspNetCore.Http.HttpResponse.OnStarting(Func1 回调) 在 Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.InitializeHandlerAsync() 在 Microsoft.AspNetCore.Authentication.AuthenticationHandler1.<InitializeAsync>d__42.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.<GetHandlerAsync>d__5.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() 在 Microsoft.AspNetCore.Authentication.AuthenticationService.d__17.MoveNext() 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 ScrumPortal.Application.Base.Common.ImpersonateUserBase.ImpersonateLogin.d__0.MoveNext() 在 D:\ScrumPortal\Impersonateuser\scrum-portal\ScrumPortal.Application\Base\Common\ImpersonateUserBase.cs:line 130

内部异常:

Startup.cs

           services.AddAuthentication(auth => {
            auth.DefaultScheme = AzureADDefaults.AuthenticationScheme;
            auth.DefaultChallengeScheme = AzureADDefaults.OpenIdScheme;
            auth.DefaultSignInScheme = AzureADDefaults.AuthenticationScheme;
            }).AddAzureAD(options => this.Configuration.Bind("AzureAd", options)).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
            options =>
            {
                options.LoginPath = "/signin";
                options.SlidingExpiration = true;
                options.ExpireTimeSpan = new TimeSpan(7, 0, 0, 0);
            });
        services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme,
            options =>
            {
                Configuration.Bind("AzureAd", options);
                options.Events = new OpenIdConnectEvents
                {
                    OnTokenValidated = ctx =>
                    {
                        ClaimsIdentity identity = (ClaimsIdentity)ctx.Principal.Identity;
                        var emailid = identity.Name;
                        var username = identity.Claims.FirstOrDefault(x => x.Type == "name").Value;
                        var res = new LoginUserModel().GetAuthenticatedUserDetails(emailid);
                        if (res != null && res.UserId > 0)
                        {
                            var claims = new LoginUserModel().AddUserClaims(res);
                            identity.AddClaims(claims);
                        }
                        else
                        {
                            ctx.Properties.RedirectUri = "/unauthorized";
                            return Task.FromResult(0);
                        }

                        return Task.FromResult(ctx);
                    }
                };
            });
        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                         .RequireAuthenticatedUser()
                         .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
            config.EnableEndpointRouting = false;
        });

基类

    public partial class ImpersonateLogin : PageModel
    {
        
        public async Task<IActionResult> ImpersonateBtnClick(string impersonateUserId, HttpContext httpcontext)
        {
            string returnUrl = "~/";
            try
            {                    
                string schema = CookieAuthenticationDefaults.AuthenticationScheme;
                await httpcontext.SignOutAsync(schema);
                CommonModel model = new CommonModel();
                int impersonateUser = 0;
                int currentUser = 0;
                int.TryParse(impersonateUserId, out impersonateUser);
                var result = model.GetUserDetailsForImpersonate(impersonateUser);
                if (result != null)
                {
                    bool impersonateUserCheck = (currentUser == impersonateUser) ? false : true;
                    var claims = new System.Collections.Generic.List<Claim>
            {
             new Claim(SessionInfo.RoleId.ToString(), result.RoleId.ToString()),
             new Claim(SessionInfo.EmailId.ToString(), result.EmailId),
             new Claim(SessionInfo.EmployeeName.ToString(), result.DisplayName),
             new Claim(SessionInfo.UserId.ToString(), impersonateUserId.ToString()),
             new Claim(SessionInfo.IsImpersonateUser.ToString(), impersonateUserCheck.ToString().ToLower()),
             new Claim(SessionInfo.CurrentUserId.ToString(), currentUser.ToString()),
             new Claim(SessionInfo.HRRoleId.ToString(), result.HrRoleId.ToString()),
             new Claim(SessionInfo.HRUserId.ToString(), result.HrUserId.ToString()),
            };

                    var claimsIdentity = new ClaimsIdentity(claims, schema);
                    await httpcontext.SignInAsync(schema, new ClaimsPrincipal(claimsIdentity));
                }                   
            }
            catch (Exception ex)
            {

            }

            return LocalRedirect(returnUrl);
        }
    }

【问题讨论】:

  • 你解决了吗?

标签: c# azure blazor-server-side azure-authentication


【解决方案1】:

这是设计使然。 Blazor 服务器应用程序不在 HTTP 请求的上下文中运行。您的代码不应使用HttpContext。有关它的文档可从Threat mitigation guidance for ASP.NET Core Blazor Server | Blazor and shared state 获得。

在 Blazor 服务器应用程序中注销用户的正确方法是将用户定向到负责注销的 MVC/Razor 页面端点。

【讨论】:

    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 2019-01-22
    • 2021-12-27
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多