IE зацикливается бесконечно при использовании Authorize - PullRequest
1 голос
/ 17 мая 2011

Я занимаюсь разработкой приложения для Facebook и хочу разрешить доступ к определенным представлениям только в том случае, если посетитель авторизован через Facebook. Это должно быть довольно простой задачей, и я думал, что это было, пока я не попробовал это в IE. Следующий код отлично работает в Chrome и Safari. Я хочу использовать проверку подлинности с помощью форм, и поэтому я установил

<forms loginUrl="~/Account/Login" timeout="2880" />

в web.config. Это приведет посетителя к следующему значению ActionResult при входе в мое приложение:

    public ActionResult Login(string returnUrl)
    {
        ManagerGame2.Utilities.StaticDataContent.InitStaticData();

        var oAuthClient = new FacebookOAuthClient();
        oAuthClient.AppId = FacebookApplication.Current.AppId;
        oAuthClient.RedirectUri = new Uri(redirectUrl);
        var loginUri = oAuthClient.GetLoginUrl(new Dictionary<string, object> { { "state", returnUrl } });
        return Redirect(loginUri.AbsoluteUri);
    }

Затем пользователь перенаправляется на страницу Facebook, и токен доступа отправляется обратно в мой OAuth ActionResult:

public ActionResult OAuth(string code, string state)
    {
        FacebookOAuthResult oauthResult;
        if (FacebookOAuthResult.TryParse(Request.Url, out oauthResult))
        {
            if (oauthResult.IsSuccess)
            {
                var oAuthClient = new FacebookOAuthClient();
                oAuthClient.AppId = FacebookApplication.Current.AppId;
                oAuthClient.AppSecret = FacebookApplication.Current.AppSecret;
                oAuthClient.RedirectUri = new Uri(redirectUrl);
                dynamic tokenResult = oAuthClient.ExchangeCodeForAccessToken(code);
                string accessToken = tokenResult.access_token;

                DateTime expiresOn = DateTime.MaxValue;

                if (tokenResult.ContainsKey("expires"))
                {
                    DateTimeConvertor.FromUnixTime(tokenResult.expires);
                }

                FacebookClient fbClient = new FacebookClient(accessToken);
                dynamic me = fbClient.Get("me?fields=id,name");
                long facebookID = Convert.ToInt64(me.id);


                Account acc = (from x in db.Account.OfType<Account>() where x.FaceBookID == facebookID select x).FirstOrDefault();
                if (acc == null)
                {
                    acc = CreateAccount(me);
                }
                acc.LatestLogin = DateTime.Now;
                db.Entry(acc).State = EntityState.Modified;
                db.SaveChanges();

                MemoryUserStore.CurrentAccount = acc;

                UserRoleProvider usp = new UserRoleProvider();
                usp.GetRolesForUser(acc.AccountID.ToString());
                FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);

                if (Url.IsLocalUrl(state))
                {
                    return Redirect(state);
                }
                return RedirectToAction("Details", "Account", new { id = acc.AccountID });
            }
        }

        return RedirectToAction("Index", "Account");
    }

То, что я пытаюсь сделать здесь, - это сначала проверить, действителен ли токен, который я получил от перенаправления. Если это так, то я извлекаю некоторые данные о посетителе, такие как FacebookID и Имя. Затем я сопоставляю его с моей базой данных, чтобы увидеть, существует ли пользователь, и если нет, я его создаю. Я также назначил роль для пользователя в моем собственном поставщике ролей, но у меня была проблема бесконечного цикла до этого. Тогда я установил

FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);

и я предполагаю, что это является основой отслеживания того, авторизован посетитель или нет. Насколько я понимаю, когда посетитель пытается вызвать ActionResult, который требует [Авторизовать], тогда система проверит этот cookie.

Хорошо, может кто-нибудь объяснить, почему приведенный выше код работает в Chrome / Safari, но продолжает бесконечно циклически проходить через Login и затем OAuth в IE?

Мое приложение использует MVC 3, EF Code First и Facebook C # SDK 5.0.25

Ответы [ 2 ]

1 голос
/ 18 мая 2011

Хорошо, я понял, что проблема была вызвана аннотацией [Authorize], как и ожидалось. В Facebook SDK есть аннотация [CanvasAuthorize], и ​​когда я переключаюсь на это, IE работает нормально и не входит навсегда.

До этого я пытался использовать аутентификацию без файлов cookie, но IE все еще не хотел подыгрывать.

Насколько я понял, проблема возникает из-за того, что приложения Facebook находятся внутри IFrame. Это якобы испортило что-то с помощью куки и доверия. Если кто-то знает, почему это так, я был бы рад услышать об этом.

Кроме того, если кто-то знает, как легко использовать и поддерживать роли с помощью [CanvasAuthorize], я был бы рад узнать.

0 голосов
/ 17 мая 2011

Я знаю, это кажется очевидным, но вы уверены, что куки не отключены в IE? В инструментах разработчика есть возможность отключить файлы cookie.

...