【问题标题】:HttpContext.Current is null in OpenId Connect OWIN middleware on SecurityTokenValidatedSecurityTokenValidated 上的 OpenId Connect OWIN 中间件中的 HttpContext.Current 为空
【发布时间】:2020-03-29 11:02:51
【问题描述】:

我正在处理与向 Azure AD 进行身份验证的 ASP.NET Web 窗体应用程序中的 OpenId Connect 中间件 (OWIN) 相关的错误。我对 OWIN 和 OpenID 完全陌生,并没有编写此代码,所以请耐心等待。

该解决方案已经过测试,看起来运行良好,但一旦投入生产,我们就会看到多个空引用异常,因为调用 SecurityTokenValidated 通知中间件时 HttpContex.Current 为空。

在用户尝试登录生产环境的时间中,大约 30%-40% 的时间似乎都会出现此问题。我们最初无法在本地重现该问题,但我们最终发现,通过将 Chrome 中的网络速度设置为 Fast/Slow 3G 速度(很有趣),我们可以 100% 地重现该问题。

这是我们在 Startup.cs 类中配置中间件的代码:

[assembly: OwinStartup(typeof(Namespace.Startup))]
namespace Namespace
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var openIdConnectProvider = OpenIdConnectProviderDAO.GetOpenIdConnectProviders().Single(x => x.ClientId == "ClientIdHere");
            app.Use((context, next) =>
            {
                var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
                httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
                return next();
            });

            app.UseStageMarker(PipelineStage.MapHandler);
            app.SetDefaultSignInAsAuthenticationType(OpenIdConnectAuthenticationDefaults.AuthenticationType);
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = openIdConnectProvider.ClientId,
                    Authority = openIdConnectProvider.Authority,
                    RedirectUri = ConfigurationHelper.GetAppSetting("applicationRoot").ToLower(),
                    AuthenticationType = openIdConnectProvider.Key,
                    AuthenticationMode = AuthenticationMode.Passive,
                    ResponseType = OpenIdConnectResponseType.IdToken,
                    Scope = OpenIdConnectScope.Email,
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = openIdConnectProvider.ValidIssuer,
                        ValidateIssuer = true,
                        ValidAudience = openIdConnectProvider.ClientId,
                        ValidateAudience = true
                    },
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        SecurityTokenValidated = OnSecurityTokenValidated,
                        AuthenticationFailed = OnAuthenticationFailed
                    }
                });
        }

        private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> arg)
        {
            // This is null when connection speed is set to Slow/Fast 3G
            var context = HttpContext.Current;

            return Task.FromResult(0);
        }

        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
        {
            context.HandleResponse();
            context.Response.Redirect("Login.aspx");

            return Task.FromResult(0);
        }
    }
}

我们需要访问 HttpContext.Current 才能访问 SecurityTokenValidated 中间件中的 Session。所以我们按照这些帖子中的建议添加了中间件:

Can OWIN middleware use the http session?

HttpContext.Current.Session is null + OWIN

这看起来效果很好,直到问题开始在生产中出现。

我尝试在各种 PipelinesStages(Authenticate、PostAcquireState 等)中使用不同的 UseStageMarker 组合,但都没有奏效。

任何帮助将不胜感激!

【问题讨论】:

  • 嗨@Abragsta。你能解决这个问题吗?
  • 不,很遗憾我无法解决这个问题。不确定是代码还是服务器有问题。但是我们现在要更改生产服务器,所以也许这会有所帮助。当我们尝试过时会发布更新。

标签: webforms azure-active-directory owin openid-connect owin-middleware


【解决方案1】:

遇到同样的问题,进入这个链接。我在github 上找到了我的问题的解决方案。

基本上,在 Global.asax 上添加一个空的 Session_OnStart() 方法

希望它可以帮助其他遇到此问题的人。

【讨论】:

    猜你喜欢
    • 2017-06-05
    • 2016-02-13
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2017-01-13
    • 2015-01-09
    • 2016-12-18
    • 2021-01-09
    相关资源
    最近更新 更多