Obtenha o ExtraData do provedor de identidade OAuth / OWin do framework MVC5 com o provedor de autenticação externo

Estou tentando usar o novo framework MVC5 na visualização do VS 2013.

A estrutura de autenticação de associação foi revisada e substituída pelo OWin .

Em particular, liguei o provedor de autenticação externo Google auth.

Foi muito simples de fazer.

Simplesmente descomente esta linha: app.UseGoogleAuthentication(); no arquivo Startup.Auth.cs no diretório App_Start do novo projeto MVC padrão.

Então, eu quero acessar o “Extra Data” que vem do provedor de autenticação, como uma URL para o avatar do usuário para exibir no meu aplicativo.

Sob a implementação OAuth mais antiga contra o provedor de associação asp.net, havia uma maneira de capturar isso usando este dictionary ExtraData encontrado aqui: ProviderDetail.ExtraData Property .

Não consigo encontrar muita documentação sobre como o OAuth e o OWin trabalham juntos e como acessar esses dados extras.

Alguém pode me esclarecer?

Recentemente eu tive que ter access à foto do perfil do Google e aqui está como eu resolvo isso …

Se você acabou de ativar o código app.UseGoogleAuthentication(); no arquivo Startup.Auth.cs não é suficiente porque neste caso o Google não retorna nenhuma informação sobre a foto do perfil (ou eu não descobri como obtê-lo).

O que você realmente precisa é usar a integração do OAuth2 em vez do Open ID que é ativado por padrão. E aqui está como eu fiz isso …

Primeiro de tudo você tem que registrar seu aplicativo no lado do Google e obter “Client ID” e “Client secret”. Assim que isso for feito, você pode ir mais longe (você precisará dele mais tarde). Informações detalhadas sobre como fazer isso aqui .

Substituir app.UseGoogleAuthentication(); com

  var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions { ClientId = "<>", ClientSecret = "<>", CallbackPath = new PathString("/Account/ExternalGoogleLoginCallback"), Provider = new GoogleOAuth2AuthenticationProvider() { OnAuthenticated = async context => { context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString())); context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString())); } } }; googleOAuth2AuthenticationOptions.Scope.Add("email"); app.UseGoogleAuthentication(googleOAuth2AuthenticationOptions); 

Depois disso, você pode usar o código para obter access ao URL da imagem do perfil da mesma maneira que para qualquer outra propriedade

 var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); var pictureClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type.Equals("picture")); var pictureUrl = pictureClaim.Value; 

Com a versão RTW da identidade asp.net, o código a seguir em ExternalLoginCallback faz isso para mim.

 var externalIdentity = await HttpContext.GetOwinContext().Authentication .GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); var displayName = externalIdentity.Name; var email = externalIdentity.FindFirstValue(ClaimTypes.Email); 

Usando a resposta de Alex Wheat, eu criei uma solução para recuperar o perfil, o gênero e o e-mail do google + usando o Google Authentication.

Startup.Auth.cs:

 var googleOptions = new GoogleOAuth2AuthenticationOptions() { ClientId = "<>", ClientSecret = "<>", Provider = new GoogleOAuth2AuthenticationProvider() { OnAuthenticated = context => { var userDetail = context.User; context.Identity.AddClaim(new Claim(ClaimTypes.Name,context.Identity.FindFirstValue(ClaimTypes.Name))); context.Identity.AddClaim(new Claim(ClaimTypes.Email,context.Identity.FindFirstValue(ClaimTypes.Email))); var gender = userDetail.Value("gender"); context.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender)); var picture = userDetail.Value("picture"); context.Identity.AddClaim(new Claim("picture", picture)); return Task.FromResult(0); }, }, }; googleOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); googleOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); app.UseGoogleAuthentication(googleOptions); 

Para obter access a dados de perfil estendidos, você deve adicionar dois escopos à solicitação – plus.login e userinfo.email. Se você adicionar apenas o escopo plus.login, não poderá ver o email do usuário. Se você usar o modelo padrão da ASP.NET MVC5 para autenticar, ele mostrará apenas o endereço de e-mail, Nome, Sobrenome e endereço de perfil do google + do usuário. Usando o caminho mostrado aqui, você terá access também ao link da foto do usuário.

A propriedade context.User carrega uma serialização JSON dos dados do usuário enviados pela rede e possui methods úteis para permitir que o usuário localize uma propriedade por sua chave.

Para saber mais sobre o conceito de escopos de login, consulte: https://developers.google.com/+/api/oauth#login-scopes

Os seguintes detalhes sobre como você pode obter dados extras dos provedores sociais http://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used -em-o-vs-2013-project-templates.aspx

Os seguintes trabalhos para mim no facebook:

StartupAuth.cs:

 var facebookAuthenticationOptions = new FacebookAuthenticationOptions() { AppId = "x", AppSecret = "y" }; facebookAuthenticationOptions.Scope.Add("email"); app.UseFacebookAuthentication(facebookAuthenticationOptions); 

Método ExternalLoginCallback:

 var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email); var email = emailClaim.Value; 

E para o Google:

StartupAuth.cs

 app.UseGoogleAuthentication(); 

Método ExternalLoginCallback (o mesmo que para o facebook):

 var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email); var email = emailClaim.Value; 

Se eu definir um ponto de interrupção aqui:

 var email = emailClaim.Value; 

Eu vejo o endereço de e-mail do facebook e do Google no depurador.

Update : Veja este post em vez de solução adequada e completa; Obtendo o email de provedores externos Google e Facebook durante a associação de conta passo em um aplicativo MVC5 padrão

Então, infelizmente, isso não é super simples, uma maneira de fazer isso é ligar o evento Autenticado do GoogleProvider e adicionar uma reivindicação personalizada à Identidade de Reivindicações com o avatar:

 public class MyGoogleProvider : GoogleAuthenticationProvider { public override Task Authenticated(GoogleAuthenticatedContext context) { context.Identity.AddClaim(new Claim("avatarClaim", "")); return base.Authenticated(context); } } app.UseGoogleAuthentication(new GoogleAuthenticationOptions() { Provider = new MyGoogleProvider() }); 

Em seguida, dentro do seu AccountController, quando a identidade externa é extraída, você pode pegar essa declaração de avatar e armazená-la em seu object de usuário para uso posterior.

Aqui está uma boa resposta do AndrewPolland. Trabalhe para mim. Ele usa o novo token de access oauth para recuperar as informações do usuário após o login. A partir daqui Deepak Goswami explica como usar esta chamada de API.