来自Facebook的DotNetOpenAuth声称标识符从不相同

时间:2011-09-23 12:40:39

标签: facebook asp.net-mvc-3 dotnetopenauth

我正在使用DotNetOpenAuth v3.5.0.10357,每次用户对Facebook进行身份验证时,我都会获得不同的声称标识符。令牌看起来是加密的,因此我假设DNOA以某种方式加密令牌以及到期。谁能证实这一点?或者我使用它错了:

    public ActionResult FacebookLogOn(string returnUrl)
    {
        IAuthorizationState authorization = m_FacebookClient.ProcessUserAuthorization();
        if (authorization == null)
        {
            // Kick off authorization request
            return new FacebookAuthenticationResult(m_FacebookClient, returnUrl);
        }
        else
        {
            // TODO: can we check response status codes to see if request was successful?
            var baseTokenUrl = "https://graph.facebook.com/me?access_token=";
            var requestUrl = String.Format("{0}{1}", baseTokenUrl, Uri.EscapeDataString(authorization.AccessToken));
            var claimedIdentifier = String.Format("{0}{1}", baseTokenUrl, authorization.AccessToken.Split('|')[0]);

            var request = WebRequest.Create(requestUrl);
            using (var response = request.GetResponse())
            {
                using (var responseStream = response.GetResponseStream())
                {
                    var graph = FacebookGraph.Deserialize(responseStream);
                    var token = RelyingPartyLogic.User.ProcessUserLogin(graph, claimedIdentifier);
                    this.FormsAuth.SignIn(token.ClaimedIdentifier, false);
                }
            }

            return RedirectAfterLogin(returnUrl);
        }
    }

这是FacebookAuthenticationResult的代码:

    public class FacebookAuthenticationResult : ActionResult
{
    private FacebookClient m_Client;
    private OutgoingWebResponse m_Response;

    public FacebookAuthenticationResult(FacebookClient client, string returnUrl)
    {
        m_Client = client;

        var authorizationState = new AuthorizationState(new String[] { "email" });
        if (!String.IsNullOrEmpty(returnUrl))
        {
            var currentUri = HttpContext.Current.Request.Url;
            var path = HttpUtility.UrlDecode(returnUrl);

            authorizationState.Callback = new Uri(String.Format("{0}?returnUrl={1}", currentUri.AbsoluteUri, path));

        }
        m_Response = m_Client.PrepareRequestUserAuthorization(authorizationState);
    }

    public FacebookAuthenticationResult(FacebookClient client) : this(client, null) { }

    public override void ExecuteResult(ControllerContext context)
    {
        m_Response.Send();
    }
}

此外,我正在使用DNOA示例中包含的RelyingPartyLogic项目,但我为ProcessUserLogin添加了一个特定于facebook的重载:

    public static AuthenticationToken ProcessUserLogin(FacebookGraph claim, string claimedIdentifier)
    {
        string name = claim.Name;
        string email = claim.Email;
        if (String.IsNullOrEmpty(name))
            name = String.Format("{0} {1}", claim.FirstName, claim.LastName).TrimEnd();
        return ProcessUserLogin(claimedIdentifier, "http://facebook.com", email, name, claim.Verified);
    }

看起来FacebookClient继承自WebServerClient,但我在GitHub上查找了源代码,并且我没有看到与相应的v3.5版本相关(或至少没有标记)的分支或标签。

2 个答案:

答案 0 :(得分:5)

Facebook不支持OpenID。声明的标识符是OpenID术语。 Facebook使用OAuth 2.0,因此您将混合使用OpenID和OAuth。

Facebook每次都会发送一个不同的访问令牌,这对于OAuth协议来说是正常的。您必须使用访问令牌来查询Facebook以获取每次访问时一致的用户ID。

答案 1 :(得分:0)

我认为您还需要在令牌请求中添加offline_access权限,请参阅https://developers.facebook.com/docs/reference/api/permissions/