我正在使用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;
答案 0 :(得分:0)
if (!Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties() { RedirectUri = "/" }, Startup.SignUpPolicyId);
}
在网络表单中尝试此操作。
修改强>
示例应用程序托管在https://github.com/Zen3InfoSolutions/B2CSamples/tree/master/B2C-WebForms
运行和验证策略所需的零配置。