asp.net mvc-MVC5和OWIN facebook身份验证提供商不适用于IE11和Firefox(但适用于Ch



我使用Asp.Net MVC 5,并利用Microsoft的Identity(v2)实现进行身份验证和外部(facebook)登录。

我的外部登录代码如下:

在Startup.Auth.cs中,我声明提供者:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions();
        facebookAuthenticationOptions.Scope.Add("email");
        (...)
        facebookAuthenticationOptions.AppId = "<my fb app id>";
        facebookAuthenticationOptions.AppSecret = "<my fb app secret>";
        facebookAuthenticationOptions.Provider = new FacebookAuthenticationProvider()
        {
            OnAuthenticated = async context =>
            {
                //Get the access token from FB and store it in the database
                context.Identity.AddClaim(
                new System.Security.Claims.Claim("FacebookAccessToken",
                                                     context.AccessToken));
            }
        };
        app.UseFacebookAuthentication(facebookAuthenticationOptions);

在我发布facebook登录表单的控制器功能中,

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult ExternalLogin(string provider, string returnUrl)
    {
        returnUrl = !String.IsNullOrEmpty(returnUrl) ? returnUrl : "/";
        // Request a redirect to the external login provider
        return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
        return null;
    }

在我的基本控制器中(我从中获得所有控制器),我使用owin OAuth:

internal class ChallengeResult : HttpUnauthorizedResult
    {
        public ChallengeResult(string provider, string redirectUri)
            : this(provider, redirectUri, null)
        {
        }
        public ChallengeResult(string provider, string redirectUri, string userId)
        {
            LoginProvider = provider;
            RedirectUri = redirectUri;
            UserId = userId;
        }
        public string LoginProvider { get; set; }
        public string RedirectUri { get; set; }
        public string UserId { get; set; }
        public override void ExecuteResult(ControllerContext context)
        {
            var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
            if (UserId != null)
            {
                properties.Dictionary[XsrfKey] = UserId;
            }
            context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
        }
    }

然后,我用一个外部回调函数获得回调(正如我在上面的ChalangeResult对象中声明的那样):

[AllowAnonymous]
    public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }
        // Sign in the user with this external login provider if the user already has a login
        var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
        switch (result)
        {
        // login logic code here.    
        // and return some View(""); or RedirerctToAction("somewhere");
        }
    }

另外值得注意的是,我使用StructureMap 3.0进行依赖注入,根据下面的代码,它将任何控制器代码的生命周期限制为请求的生命周期。

public void Init(HttpApplication context) {
        context.BeginRequest += (sender, e) => StructuremapMvc.StructureMapDependencyScope.CreateNestedContainer();
        context.EndRequest += (sender, e) => {
            HttpContextLifecycle.DisposeAndClearAll();
            StructuremapMvc.StructureMapDependencyScope.DisposeNestedContainer();
        };
    }

现在,这一切都工作得很好,当我从chrome运行应用程序时,确实为我处理了facebook登录。但当我使用internet explorer(尝试11)或firefox时,它会挂在/{controller}/ExternalLogin的黑屏中,并且不进行任何重定向。

如果这是国际奥委会对结构图控制的问题,我相信它在铬上也不应该顺利运行。所以我一直在网上搜索,找不到解决方案,也找不到任何关于发生了什么的迹象。由于我没有得到任何例外或类似的情况,我不知道自己做错了什么。

综上所述:

  • 我使用的是:ASP.NET MVC 5+OWIN(v3.0.1)+Identity(v2)+StructureMap 3+Facebook登录
  • 这一切都很好用铬
  • 在IE11或Firefox中不起作用
  • 我的问题是(1)为什么?以及(2)我该如何解决这个问题

谢谢。

好吧,我想的有点太复杂了。问题出在我发布的输入标签上。

如果你的post操作是采用像public ActionResult ExternalLogin(string provider, string returnUrl)这样的表单数据(即没有模型),并且你使用输入图像的名称和值来提供表单操作,比如:

<input type="image" id="@facebookLogin.AuthenticationType" name="provider" value="@facebookLogin.AuthenticationType"...>

然后,由于某种原因,Chrome会发送正确的帖子数据,而internet explorer和firefox则不能。

因此,没有依赖性注入、中间件或OAuth问题,只有这个简单的旧html。

最新更新