我有一个asp.net MVC 5 web项目,它在我的开发系统上运行良好。但由于某种原因,当我在生产系统上部署解决方案时,使用Microsoft Owin与Facebook的登录就停止了。
回调总是检索。。。。error=access_denied作为参数,我追踪到owin为我的身份返回null的事实。知道这里发生了什么吗?
更新
我在Owin代码中实现了log4net,并能够深入研究:
Response status code does not indicate success: 400 (Bad Request).
Stack trace:
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Microsoft.Owin.Security.Facebook.FacebookAuthenticationHandler<AuthenticateCoreAsync>d__0.MoveNext()
请不要说我已经修改了脸书应用程序,以匹配生产网址,响应等
private void ConfigureAuth(IAppBuilder app)
{
var cookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
};
app.UseCookieAuthentication(cookieOptions);
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Passive
app.SetDefaultSignInAsAuthenticationType(cookieOptions.AuthenticationType);
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],
AppId = ConfigurationManager.AppSettings["FacebookAppId"],
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim(
IdentityUtility.ExtendedClaimTypes.IdentityProvider,
"Facebook"));
return Task.FromResult(0);
},
OnReturnEndpoint = (context) =>
{
if(context.Identity == null)
throw new Exception(context.Response.StatusCode.ToString());
return Task.FromResult(0);
}
}
});
}
谨致问候,Martin
也许你已经解决了!无论如何我会发布这个答案,以防其他迷失的灵魂(?)来这里寻找其他选择或解决方案。
我和一个类似的问题斗争了好几天!为了节省时间,我建议您先尝试以下方法:
- 阅读本github线程,了解OWIN在使用网络cookie管理器(Correlationcookie、externalcookie和SystemWebCookieManager)时需要的解决方法:
https://github.com/aspnet/AspNetKatana/issues/331
- 此外。。。(长版本)当你在负载均衡器或某个反向处理流量的代理后面工作时,你的服务器可能会覆盖请求方案,并最终使用http协议调用facebook端点(/oauth)(这就是为什么它在localhost或任何开发环境中都能很好地工作,因为它在前面没有LB)。由于Facebook需要https来交换代币并完成登录过程,您将收到?error=access_denied响应(这太令人沮丧了)
(简短版本):你可以断言某个请求(在反向之前)使用了https,并覆盖context.request属性来恢复它。你也可以使用中间件(OWIN)来检查原始请求中的"x-forwarded-proto"请求头。
在声明外部cookie为默认登录身份验证类型(SetDefaultSignInAsAuthenticationType)之前,只需应用OWIN中间件。订单在这里很重要,因为中间件就像管道一样工作!(更多信息请点击此处->https://learn.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline)
示例代码片段:
// This is the middleware fixing the request scheme
app.Use((context, next) => {
if (context.Request.Headers["x-forwarded-proto"] == "https")
{
context.Request.Scheme = "https";
}
return next();
});
// The following lines are related with the step 1 issue!
app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
AuthenticationMode = AuthenticationMode.Passive,
CookieName = CookiePrefix + DefaultAuthenticationTypes.ExternalCookie,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
CookieManager = new SystemWebCookieManager()
});
...
关于x-forwardedproto标头的更多信息,请点击此处->https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto。这里的关键点是:
X-Forwarded-Proto(XFP)标头是识别客户端用于连接的协议(HTTP或HTTPS)到您的代理或负载均衡器。