支持Facebook的应用程序的两用iFrame +外部身份验证的最佳实践

时间:2010-12-27 06:45:27

标签: facebook oauth facebook-c#-sdk

好的,如果cookie是禁忌,那么我需要一些指导来实现我正在创建的应用程序的最佳方式。

场景是我正在尝试创建一个可以对用户进行身份验证的Asp.Net MVC应用程序,无论用户是直接访问网站还是通过Facebook中的iFrame访问。根据用户是否通过Facebook进入,有单独的操作(实际上是在单独的控制器中)以获取INTO应用程序,但Facebook应用程序中还有一些地方我打开了一个新的“扩展”功能窗口在应用程序的其他方面,在iFrame中无法正常工作。它应该无缝过渡。它目前使用cookie工作得很好,但我从多个来源得知这对iFrame应用程序来说不是一件好事。但是,我不确定这意味着什么。

如果没有cookie,你还能以某种方式获得服务器端访问身份验证令牌吗?如果没有,那么处理这个问题的“正确”方法是什么。我是否需要使用JS API手动解析令牌并向服务器发送AJAX通知,告知用户已经过身份验证并创建表单身份验证令牌? CanvasAuthorize属性是否可以在没有cookie的情况下工作?现在我已将代码添加到Global.asax中的FormsAuthentication_OnAuthenticate事件,以便在用户通过Facebook登录(并与外部应用程序中的有效用户正确关联)时创建表单身份验证令牌,如下所示:

protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs args)
{
    if (FormsAuthentication.CookiesSupported)
    {
        if (Request.Cookies[FormsAuthentication.FormsCookieName] == null)
        {
            // Attempt to authenticate using Facebook
            try
            {
                FacebookApp fbApp = new FacebookApp();
                if (fbApp.Session != null)
                {
                    dynamic me = fbApp.Get("me");
                    String fbID = "" + me.id;
                    MembershipUser mUser = AppMembershipProvider.GetUserByFacebookID(fbID);
                    if (mUser != null)
                    {
                        FormsAuthentication.SetAuthCookie(mUser.UserName, false);
                        AppMembershipProvider.UpdateLastLogin(mUser.UserName);
                        Session["FacebookLogin"] = true;
                    }
                }
            }
            catch (Exception e)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(e);
            }
        }
    }
    else
    {
        throw new HttpException("Cookieless Forms Authentication is not " +
                                "supported for this application.");
    }
}

我需要更改吗?

很抱歉,如果这是基本知识,但我对如何最好地实现这一点感到困惑。谢谢!

2 个答案:

答案 0 :(得分:3)

首先,让我解决一下cookies的问题。所以,当我说不在iFrames中使用cookies时,我说这有几个原因。首先在IE中,存在一些安全问题。您需要将以下标题添加到您的应用中,以使Cookie在iframe中正常运行:

P3P: CP="CAO PSA OUR"

iframe应用程序中cookie的第二大问题是Safari。由于Safari中的安全设置,iframe无法创建Cookie。因此,您将无法在iframe内部依赖Cookie进行身份验证。

如果您在iframe内外使用该应用,则应启用Cookie支持。但是,您的应用必须以解决iframe问题的方式进行设计。这将是困难的部分。

iframe应用程序中最可靠的身份验证是签名请求方法。当网址在iframe中呈现时,Facebook会将查询参数附加到您的网址。此查询参数包含用户的会话。 Facebook C#SDK处理为您阅读此内容,因此您不需要解析它等等。但您需要知道它就在那里。如果您在Facebook中查看iframe应用的传入请求网址,您会看到类似http://www.mysite.com/page/?signed_request= {blahblahblah}的内容。

所以关键是你需要确保如果你在iframe中你保留了这个?在网址上的signed_request值。

你可以通过以下几种方式做到这一点。首先,您可以使用CanvasRedirect方法。这些是Facebook.Web.Mvc命名空间中System.Web.Mvc.Controller的扩展方法。画布重定向使用javascript在顶部网址中重定向您的页面。这样Facebook实际上处理重定向,并始终将signed_request添加到您的iframe网址。问题在于,这种重定向方法只能在iframe中使用,而不能在外部使用。

第二种方法是在重定向时手动将?signed_request添加到url。你可以这样做:

public ActionResult Something(){  return RedirectToAction(“something”,new {signed_request = Request.Querystring [“signed_requets”]); }

还有其他方法,比如在会话中存储数据或其他方式,但我不建议沿着这条路走下去。

你所做的绝对是一种先进的服装,但希望上述内容能帮助你朝着正确的方向前进。如果您有任何疑问,请随时直接与我联系。 nathan@ntotten.com或@ntotten在twitter上。

答案 1 :(得分:1)