我正在使用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版本相关(或至少没有标记)的分支或标签。
答案 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/