Update2 这篇文章已经过时但仍然相关.. 下面是我解决它的方法。我标记了其他人的答案,因为我认为它更好地回答了这个问题。我在 accountcontroller 中调用了一个类似的方法(我即将重构:))。字符串应该是一个列表......我想你明白了。
/// <summary>
/// Use this method when an action fails due to lack of priviligies. It will redirect user to facebook with provided permission request.
/// Refactor to handle list of request.
/// </summary>
/// <param name="permission"></param>
private static void AddAdditionalPermissions(string permission)
{
System.Diagnostics.Trace.TraceInformation(permission + " not authorized for user.");
string facebook_urlAuthorize_base = "https://graph.facebook.com/oauth/authorize";
string scope = permission; //see: https://developers.facebook.com/docs/authentication/permissions/ for extended permissions
string urlAuthorize = facebook_urlAuthorize_base;
urlAuthorize += "?client_id=" + AppId;
urlAuthorize += "&redirect_uri=" + "https://fbd.anteckna.nu/";
urlAuthorize += "&scope=" + scope;
//redirect the users browser to Facebook to ask the user to authorize our Facebook application
HttpContext.Current.Response.Redirect(urlAuthorize, true); //this cannot be done using WebRequest since facebook may need to show dialogs in the users browser
}
然后,每个使用 facebook C# SDK 调用 facebook(如 /me/home)的方法都会捕获 FacebookOAuthException 并重定向到以下方法。这就是我们应用最佳实践的方式,即在需要时不事先向用户询问权限。此方法应该也有匹配的 aredirect url,但我们刚刚开始:)
希望能帮助到你!
/// <summary>
/// Check for what permissions to request or different ways to handle FacebookOAuthExceptions.
/// </summary>
/// <param name="foae">The exception object</param>
public static void HandleAuthorizationsExceptions(FacebookOAuthException foae)
{
if (foae.Message.Contains("publish_permissions"))
{
AddAdditionalPermissions("publish_permissions");
}
else if (foae.Message.Contains("read_stream"))
{
AddAdditionalPermissions("read_stream");
}
else
{
System.Diagnostics.Trace.TraceError("Unhandled error at:" + foae.StackTrace);
}
}
更新:此行为是由 .Net oauth 实现引起的,该实现将范围硬编码在密封类中。添加了图 4 以显示请求参数,其中除了“电子邮件”之外缺少其他范围(由 .net oauth 提供程序与所有请求一起发送)。将“,publish_stream”添加到查询字符串给了我想要的行为。任何人都知道如何实现这一目标?
请不要提交有关 facebook 最佳实践或替代解决方案的答案或评论。我有一个替代解决方案,但希望它与默认的 registerfacebookclient 参数一起使用。我已经根据指定我要求的权限的两个答案更新了应用程序以仅使用 publish_stream 。
图 4
原始问题: 我正在设置一个应用程序(C#.Net4.5 MVC4,剃刀视图),它几乎需要来自 facebook 的所有可用用户权限。您可以在下面看到我如何设置它的代码示例。
问题是当单击图 1 中的“确定”时,Facebook 将我发送回我的应用程序。据我了解,应该有一个额外的屏幕(图 2)要求“更重”的权限。截至目前,我只获得图一中所述的权限。那部分有效...
图1
图 2
所以,使用基本的 AuthConfig.cs
var facebooksocialData = new Dictionary<string, object>();
facebooksocialData.Add("scope", "email,publish_stream,read_stream,publish_actions,manage_pages,create_event,offline_access");
OAuthWebSecurity.RegisterFacebookClient(
appId: "165359673639901",
appSecret: "15091cb2094a1996ae6c7b324f0300e6",
displayName: "Facebook",
extraData: facebooksocialData);
这就是我处理响应的方式,但是这里 facebook 没有提示用户扩展权限,而只是提示电子邮件,
AccountController.cs
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
// Save the accesstoken into session
Session["accesstoken"] = result.ExtraData["accesstoken"];
Session["id"] = result.ExtraData["id"];
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return RedirectToLocal(returnUrl);
}
if (User.Identity.IsAuthenticated)
{
// If the current user is logged in add the new account
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
return RedirectToLocal(returnUrl);
}
else
{
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
}
}
我能找到的最接近答案的是一个 wp 插件,它有同样的问题。通过将域设置为 localhost 解决了他们的问题。这就是我的应用程序的设置方式。