net mvc example crear asp and c# asp.net-mvc facebook oauth

crear - mvc 5 login example in c#



Forzar la reautenticación con OAuthWebSecurity con Facebook (3)

Encontré la solución. Tuve que crear mi propio cliente en lugar de usar el predeterminado proporcionado por 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; } } }

y luego en AuthConfig.cs ...

OAuthWebSecurity.RegisterClient( new MyFacebookClient( appId: "xxxxxxxxxx", appSecret: "xxxxxxxxxxxxxxxx"), "facebook", null );

Mi sitio web usa Facebook ya que es un proveedor independiente. Los usuarios podrán comprar cosas a través de mi sitio, por lo que quiero obligarlos a autenticarse incluso si ya tienen una sesión activa con Facebook.

Encontré este enlace en la documentación de la API de Facebook que analiza la reautenticación, pero no puedo hacer que funcione con mi aplicación mvc. ¿Alguien sabe si esto es posible?

var extra = new Dictionary<string, object>(); extra.Add("auth_type", "reauthenticate"); OAuthWebSecurity.RegisterFacebookClient( appId: "**********", appSecret: "**********************", displayName: "", extraData: extra);


Hay un problema al usar la implementación MyFacebookClient. Probablemente alguien tratando de implementarlo se encontró con el error:

La clave dada no estaba presente en el diccionario

intentando llamar al método ExternalLoginCallback en ActionController.

El error aumenta cuando el método

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

se llama.

Para que funcione, el método VerifyAuthentication debe ser anulado. En particular, el

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

sobrecarga de la clase abstracta OAuth2Client.

Si usa lo siguiente:

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; } }

finalmente obtienes el método llamado de la manera correcta y no se produce excpetion.


Como nota para aquellos que pasan por esto si su Autenticación de Facebook dejó de funcionar cuando v2.3 se convirtió en la versión más baja a la que tiene acceso (las llamadas no versionadas obtienen la versión más baja a la que tiene acceso una aplicación). La API ahora devuelve JSON y no pares de nombre y nombre, por lo que debe actualizar el método QueryAccessToken mostrado anteriormente por @Ben Tidman.

A continuación está el método actualizado

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; }