net bearer asp c# asp.net asp.net-web-api oauth-2.0 google-oauth

c# - bearer - Registrarse API de inicio de sesión externo



oauth2 web api c# (1)

Este método no es realmente práctico, ya que está desarrollando una API, que probablemente se utilizará para aplicaciones, la mejor manera es manejar el inicio de sesión con Facebook por parte del consumidor API y dejar que le envíen un token de autenticación de Facebook.

Básicamente estaba tratando de hacer esto:

  1. Crear un enlace de inicio de sesión externo para Facebook.
  2. Envíe al usuario a ese enlace que los llevará a la página de inicio de sesión de Facebook.
  3. Después de iniciar sesión, Facebook se redireccionará a la API.
  4. El usuario estaría registrado, pero ¿cómo sabe la aplicación / sitio web que consume la API?

Lo que quieres hacer es esto:

  1. El consumidor API crea su propio método para iniciar sesión con Facebook (para aplicaciones a través de SDK)
  2. El consumidor API enviará un token de Facebook a la API para registrarse / iniciar sesión.
  3. API comprobará el token con el punto final del gráfico de Facebook.
  4. Cuando tenga éxito, API devolverá un token de portador para la API para realizar más solicitudes autenticadas.

Entonces, para usted como desarrollador de API, debería verificar el token de la siguiente manera:

var verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken);

Y luego obtener el userId

var client = new HttpClient(); var uri = new Uri(verifyTokenEndPoint); var response = await client.GetAsync(uri); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); dynamic jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(content); string user_id = jObj["data"]["user_id"]; string app_id = jObj["data"]["app_id"]; }

Eventualmente crearías o buscarías un usuario así:

IdentityUser user = await _userManager.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id));

Y luego depende de usted cómo crear un token de portador, si sigue el tutorial que se detalla a continuación, puede tener esto:

var tokenExpiration = TimeSpan.FromMinutes(30); ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, userName)); identity.AddClaim(new Claim("role", "user")); var props = new AuthenticationProperties() { IssuedUtc = DateTime.UtcNow, ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration), }; var ticket = new AuthenticationTicket(identity, props); var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);

Fuente, con tutorial completo aquí

También recibí el correo electrónico a través del SDK y lo envié junto con la solicitud POST, ya que administré la API y el consumidor. Advertencia: un usuario de Facebook podría no querer darle una dirección de correo electrónico.

Reciba un correo electrónico después del inicio de sesión de Facebook en Android y iOS

No entiendo por qué no es un tutorial claro o una guía sobre esto, así que espero que mi pregunta pueda ser respondida aquí.

Por lo tanto, tratando de registrar usuarios de Facebook o Google, a través de la API web.

El problema es, en el método RegisterExternal , en esta línea:

var info = await Authentication.GetExternalLoginInfoAsync();

Devuelve null y, por lo tanto, devuelve BadRequest()

Lo que obtuve hasta ahora:

En Startup.Auth.cs he tenido los id y los secretos, tenga en cuenta que también he intentado usar Microsoft.Owin.Security.Facebook

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions { AppId = "103596246642104", AppSecret = "1c9c8f696e47bbc661702821c5a8ae75", Provider = new FacebookAuthenticationProvider() { OnAuthenticated = (context) => { context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook")); return Task.FromResult(0); } }, }; facebookOptions.Scope.Add("email"); app.UseFacebookAuthentication(facebookOptions); app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "328779658984-t9d67rh2nr681bahfusan0m5vuqeck13.apps.googleusercontent.com", ClientSecret = "ZYcNHxBqH56Y0J2-tYowp9q0", CallbackPath = new PathString("/api/Account/ManageInfo") });

Fuente facebookOptions: esta publicación

Las facebookOptions adicionales no resolvieron el problema.

Puedo recuperar un access_token de Google y Facebook. También puedo autenticar con este access_token a api/Account/UserInfo

GET http://localhost:4856/api/Account/UserInfo in the header: Authorization: Bearer R9BTVhI0...

Que devuelve: {"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}

Un problema que noté es que devuelve mi nombre como Correo electrónico, no la dirección de correo electrónico real.

Ahora quiero registrar el inicio de sesión externo con un nuevo usuario para mi base de datos, que hago una llamada POST como esta:

POST http://localhost:4856/api/Account/RegisterExternal [header] authorization: bearer 6xcJoutY... Content-Type: application/json [body] {"Email":"[email protected]"}

fuente: esta publicación

Ahora esto devuelve una BadRequest en este snippit de código, dentro de RegisterExternal ():

public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (!ModelState.IsValid) { return BadRequest(ModelState); } //AuthenticationManger? var info = await Authentication.GetExternalLoginInfoAsync(); if (info == null) { return InternalServerError(); }

En la depuración, ExternalLoginConfirmationViewModel contiene mi dirección de correo electrónico.

¿Qué estoy haciendo mal? ¿Debo agregar algo a Startup.cs ? ¿Hay algo más que tengo que hacer en el Startup.Auth.cs ? ¿Llamo incorrectamente a RegisterExternal ? En MVC funciona sin problemas, ¿por qué no en la API web?

Aso miró esta respuesta desde esta pregunta , pero no entendí cómo implementar esto.