1

我的网站使用 facebook 作为它的 oauth 提供者。用户将能够通过我的网站购买东西,所以我想强制他们进行身份验证,即使他们已经与 facebook 进行了活动会话。

我在讨论重新认证的 facebook 的 api 文档中找到了这个链接,但我无法让它与我的 mvc 应用程序一起使用。有谁知道这是否可能?

var extra = new Dictionary<string, object>();
extra.Add("auth_type", "reauthenticate");

OAuthWebSecurity.RegisterFacebookClient(
            appId: "**********",
            appSecret: "**********************",
            displayName: "",
            extraData: extra);  
4

3 回答 3

2

找到了解决方案。我必须创建自己的客户端,而不是使用提供的默认客户端OAuthWebSecurity.RegisterFacebookClient

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;

namespace Namespace.Helpers
{
    public class MyFacebookClient : DotNetOpenAuth.AspNet.Clients.OAuth2Client
    {
        private const string AuthorizationEP = "https://www.facebook.com/dialog/oauth";
        private const string TokenEP = "https://graph.facebook.com/oauth/access_token";
        private readonly string _appId;
        private readonly string _appSecret;

        public MyFacebookClient(string appId, string appSecret)
            : base("facebook")
        {
            this._appId = appId;
            this._appSecret = appSecret;
        }


        protected override Uri GetServiceLoginUrl(Uri returnUrl)
        {
            return new Uri(
                        AuthorizationEP
                        + "?client_id=" + this._appId
                        + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                        + "&scope=email,user_about_me"
                        + "&display=page"
                        + "&auth_type=reauthenticate"
                    );
        }

        protected override IDictionary<string, string> GetUserData(string accessToken)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                "https://graph.facebook.com/me?access_token=" + accessToken
            );
            dynamic data = Json.Decode(content);
            return new Dictionary<string, string> {
                {
                    "id",
                    data.id
                },
                {
                    "name",
                    data.name
                },
                {
                    "photo",
                    "https://graph.facebook.com/" + data.id + "/picture"
                },
                {
                    "email",
                    data.email
                }
            };
        }

        protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                TokenEP
                + "?client_id=" + this._appId
                + "&client_secret=" + this._appSecret
                + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                + "&code=" + authorizationCode
            );

            NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(content);
            if (nameValueCollection != null)
            {
                string result = nameValueCollection["access_token"];
                return result;
            }
            return null;
        }
    }
}

然后在 AuthConfig.cs...

 OAuthWebSecurity.RegisterClient(
                new MyFacebookClient(
                    appId: "xxxxxxxxxx", 
                    appSecret: "xxxxxxxxxxxxxxxx"),
                "facebook", null
            );
于 2013-09-28T13:14:58.767 回答
1

请注意,如果您的 Facebook 身份验证在 v2.3 成为您可以访问的最低版本时停止工作(非版本化调用获得应用程序可以访问的最低版本),则会发生这种情况。API 现在返回 JSON 而不是名称值对,因此您必须更新上面 @Ben Tidman 显示的 QueryAccessToken 方法

下面是更新的方法

protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                TokenEP
                + "?client_id=" + this._appId
                + "&client_secret=" + this._appSecret
                + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                + "&code=" + authorizationCode
            );

            dynamic json = System.Web.Helpers.Json.Decode(content);
            if (json != null)
            {
                string result = json.access_token;
                return result;
            }
            return null;
        }
于 2017-04-05T16:08:02.220 回答
0

使用 MyFacebookClient 实现存在一个问题。可能有人试图实现它遇到了错误:

字典中不存在给定的键

试图在 ActionController 中调用 ExternalLoginCallback 方法。

方法时引发错误

OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

叫做。

为了让它工作,必须重写方法 VerifyAuthentication。特别是

public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl);

抽象类 OAuth2Client 的重载。

如果您使用以下内容:

 public override AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl)
    {
        string code = context.Request.QueryString["code"];

        string rawUrl = context.Request.Url.OriginalString;
        //From this we need to remove code portion
        rawUrl = Regex.Replace(rawUrl, "&code=[^&]*", "");

        IDictionary<string, string> userData =    GetUserData(QueryAccessToken(returnPageUrl, code));

        if (userData == null)
            return new AuthenticationResult(false, ProviderName, null, null, null);


        AuthenticationResult result = new AuthenticationResult(true, ProviderName, userData["id"], userData["name"], userData);
        userData.Remove("id");
        userData.Remove("name");
        return result;
    }
}

最后,您以正确的方式调用了该方法,并且没有抛出异常。

于 2014-02-11T22:05:04.797 回答