ASP.NET MVC5 OWIN:通过Facebook登录后,为什么User.Identity.IsAuthenticated == false?

时间:2014-04-24 18:45:56

标签: facebook authentication cookies asp.net-identity owin

我正在关注VS2013 SPA模板的示例 - 但是我没有使用Bearer Tokens(这可能是问题,但是如果可能的话,我希望能够使用cookie)。

以下是我的API控制器中相关操作方法的缩减版本:

    [HttpGet]
    [AllowAnonymous]
    public async Task<IHttpActionResult> ExternalLogin(string provider, string error = null)
    {

        if (!User.Identity.IsAuthenticated)
        {
            return new ChallengeResult(provider, this);
        }

        ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

        // ...do stuff with externalLogin data
   }

以下是请求的基本流程:

  1. 用户点击Facebook按钮,将GET发送到/ api / externallogin?provider = Facebook

  2. User.Identity.IsAuthenticated返回false - &gt;返回401,中间件将其转换为302,并将“Location”标题设置为facebook登录页面

  3. 浏览器转到facebook登录页面 (https://www.facebook.com/dialog/oauth?response_type=code&client_id={myClientId}&redirect_uri=http%3A%2F%2Flocalhost%3A54819%2Fsignin-facebook&scope=user_birthday&state={someStateCode}

  4. 用户通过Facebook登录 - &gt;导致浏览器调用'redirect_uri',但现在查询字符串中有'code'和'state'参数,即http://localhost:54819/signin-facebook?code={someCode}&state={someStateCode}

  5. 来自对'redirect_uri'的调用的响应是302,其中Location头设置回我的应用程序,还包含两个'Set-Cookie'标题:

    • 地点:http://localhost:54819/api/en-gb/account/externallogin?provider=Facebook
    • Set-Cookie:.AspNet.Correlation.Facebook =; expires =周四,01-Jan-1970 00:00:00 GMT
    • 设置Cookie:.AspNet.ExternalCookie = Rv01CHd2onYtN_MHw2Bt71JSaOP71uRk7AP6kSilnAg7djXMh5fbZxlRCPuZhy8inhEF7ChNB261WVU3LGDuIaQmMXgz7tqXeNI-ji8qQFi2d64a720PbRVpWnkuHm2m8L87fkJAGQMJOku5gMrc0EZJfKNgjXiLv-c6Vo7PEzNch-CqcCPFHP0KBo7tGhDTbgJt-RvTzkkB1NL2JBc23eiaeda70oAW4P0NfIyj_i9mLUexHXz8Qooy9CBoLrN7Z198H_cawBfiMMF0tK1YFee2eH_TQxdmdKkUFVRz58EeIKyKUEEDswbQA9evPEHpD8BIlJPXi6R2scC44_INufXuKjHOt7LW3-sPRkUGbEWCWOn4d1B4FkHR_xOHtRpGpIdZU14xJLLiyFYKR0XxJiRlRIph8KKYnZHy61wMOl2yznOFqq3rzHOGhZ1xXEKmUlByiawPbNpdS9pNZVSHlGMbiz0FsOTf4_EVAKEXRQyxEbYjBBXD_5Ne6f7SpBqE;路径= /;仅Http
  6. 然后,浏览器将GET请求发送到步骤5的Location头中的URL(返回到我的应用程序),并带有以下cookie(根据上面的'Set-Cookie'指令):

    • 曲奇:.AspNet.ExternalCookie = Rv01CHd2onYtN_MHw2Bt71JSaOP71uRk7AP6kSilnAg7djXMh5fbZxlRCPuZhy8inhEF7ChNB261WVU3LGDuIaQmMXgz7tqXeNI-ji8qQFi2d64a720PbRVpWnkuHm2m8L87fkJAGQMJOku5gMrc0EZJfKNgjXiLv-c6Vo7PEzNch-CqcCPFHP0KBo7tGhDTbgJt-RvTzkkB1NL2JBc23eiaeda70oAW4P0NfIyj_i9mLUexHXz8Qooy9CBoLrN7Z198H_cawBfiMMF0tK1YFee2eH_TQxdmdKkUFVRz58EeIKyKUEEDswbQA9evPEHpD8BIlJPXi6R2scC44_INufXuKjHOt7LW3-sPRkUGbEWCWOn4d1B4FkHR_xOHtRpGpIdZU14xJLLiyFYKR0XxJiRlRIph8KKYnZHy61wMOl2yznOFqq3rzHOGhZ1xXEKmUlByiawPbNpdS9pNZVSHlGMbiz0FsOTf4_EVAKEXRQyxEbYjBBXD_5Ne6f7SpBqE
  7. 问题:User.Identity.IsAuthenticated check在此阶段返回False(实际上User字段基本上是空的)

  8. 我想,鉴于AspNet.ExternalCookie肯定是在步骤6的请求中发送的,那么用户就会被认证。

    那么,有没有人知道中间件在这个阶段会寻找什么,以便它解码/解密/反序列化cookie并使用户饱和?

    这是Startup.Auth我有:

        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                //AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AuthenticationType = Constants.AuthenticationTypes.MchAdminApplicationCookie,
                SlidingExpiration = true,
                ExpireTimeSpan = new TimeSpan(10, 0, 0)
            });
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                //AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AuthenticationType = Constants.AuthenticationTypes.MchApiApplicationCookie,
                SlidingExpiration = true,
                ExpireTimeSpan = new TimeSpan(10, 0, 0)
            });
    
            var facebook = new FacebookAuthenticationOptions
            {
                AppId = "mycode",
                AppSecret = "mysecret",
    
                AuthenticationType = "Facebook",
                SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                Provider = new FacebookAuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        if (ctx.User["birthday"] != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, ctx.User["birthday"].ToString()));
                        }
                    }
                }
            };
            facebook.Scope.Add("user_birthday");
            app.UseFacebookAuthentication(facebook);
        }
    

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。您应该为ExternalLogin操作添加两个属性:

[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]