Azure广告b2c身份验证质询失去会话对象

时间:2017-07-03 10:21:08

标签: c# asp.net-mvc webforms azure-ad-b2c

我正在使用github示例active-directory-b2c-dotnet-webapp-and-webapi。

我配置了自己的b2c租户并让MVC示例成功运行。

但是,我需要使用它来使用WebForms应用程序。我创建了一个新的Webforms应用程序,检查引用是否指向与工作示例相同的dll版本,并调整代码以在WebForms中工作。

在我发出Authentication.Challenge并处理OnAuthorizationCodeReceived函数中的AuthorizationCodeReceivedNotification之前,一切正常。

notification.OwinContext.Environment [“System.Web.HttpContextBase”]中的Session对象为null,而此时在MVC示例中为notification.OwinContext.Environment [“System.Web.HttpContextBase”]中的会话对象。 Session是一个带有有效SessionId的System.Web.HttpSessionStateWrapper。

在WebForms中,HttpContext.GetOwinContext抛出一个错误,因为我没有可用,所以我尝试了HttpContext.Current.GetOwinContext,它返回了一个HttpContext对象而不是一个HttpContextBase对象。所以我最后用了

if (!Request.IsAuthenticated)
{    
   HttpContextBase context = new HttpContextWrapper(HttpContext.Current);    
   context.GetOwinContext().Authentication.Challenge();
   return;
}

而不是MVC示例中使用的以下内容

if (!Request.IsAuthenticated)
{
   HttpContext.GetOwinContext().Authentication.Challenge();
   return;
}

在代码的这一点上,在MVC和WebForms中,Authentication对象在发出Challenge之前的OwinContext.Environment中有一个有效的Session对象。问题是,在MVC版本中,生成的通知包括会话对象,通知的WebForms版本具有空对象。

通过调用使用httpContext.Session对象的MSALSessionCache(MVC正常; Webforms抛出Null引用异常)获取TokenCache时,问题最终浮出水面

我知道MVC和Webforms对会话的处理方式不同,但无法解决如何解决这个问题。

修改

虽然这有效但它没有解决有关会话ID的问题。我添加了

Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = AuthenticationFailed,
                    AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                    MessageReceived = OnMessageReceived,
                    SecurityTokenReceived=OnSecurityTokenReceived,
                    SecurityTokenValidated= OnSecurityTokenValidated
                },

使用适用于这些函数的存根来代码。 MessageReceived的调用与SecurityTokenReceived和Validated一样。但是,从未调用AuthorizationCodeReceived。当前三个被调用时,我检查了notification.OwinContext.Environment [“System.Web.HttpContextBase”]并且在所有情况下Session对象都是null - 这就是我的问题所在。

编辑(包括答案​​)

感谢@Ramakrishna,解决方案是在ConfigureAuth的开头添加一个RequireAspNetSession帮助函数。他的样本的修订代码段如下:

public void ConfigureAuth(IAppBuilder app)
    {
        RequireAspNetSession(app);

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        // Configure OpenID Connect middleware for each policy
        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignUpPolicyId));
        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(ProfilePolicyId));
        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignInPolicyId));
    }

    public static void RequireAspNetSession(IAppBuilder app)
    {
        app.Use((context, next) =>
        {
            var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
            httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
            return next();
        });

        // To make sure the above `Use` is in the correct position:
        app.UseStageMarker(PipelineStage.MapHandler);
    }

您需要添加以下参考:

using System.Web.SessionState;
using Microsoft.Owin.Extensions;

1 个答案:

答案 0 :(得分:0)

if (!Request.IsAuthenticated)
{
   HttpContext.Current.GetOwinContext().Authentication.Challenge(
   new AuthenticationProperties() { RedirectUri = "/" }, Startup.SignUpPolicyId);
}

在网络表单中尝试此操作。

修改

示例应用程序托管在https://github.com/Zen3InfoSolutions/B2CSamples/tree/master/B2C-WebForms

运行和验证策略所需的零配置。