我正在使用WEB API 2
和Angularjs
作为前端开发应用程序,两者都是单独托管的。应用程序需要外部登录,如Facebook,谷歌+,推特等。首先我正在使用Facebook身份验证,我已成功获得访问令牌。注册外部用户时,我需要用户的电子邮件,名字,姓氏,生日,性别。使用以下代码,我只能获得电子邮件和全名。名字,姓氏始终为空。
StartUp.Auth.cs:
public partial class Startup
{
//public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
//public static GoogleOAuth2AuthenticationOptions googleAuthOptions { get; private set; }
public static FacebookAuthenticationOptions facebookAuthOptions { get; private set; }
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the application for OAuth based flow
PublicClientId = "self";
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
facebookAuthOptions = new FacebookAuthenticationOptions()
{
AppId = "xxxxxxx",
AppSecret = "xxxxxxxx",
BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location",
Scope = { "email", "public_profile" }
};
//facebookAuthOptions.Scope.Add("email");
//facebookAuthOptions.Scope.Add("public_profile");
app.UseFacebookAuthentication(facebookAuthOptions);
}
}
RegisterExternal:
[AllowAnonymous]
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal()
{
//I am getting userInfo null always...
//var userInfo = await Authentication.GetExternalLoginInfoAsync();
//if (userInfo == null)
//{
// return InternalServerError();
//}
var externalIdentity = await Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalBearer);
var email = externalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email).Value; // Here I can get Email only
var lastNameClaim = externalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname); // Surname is null
var givenNameClaim = externalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName); // Given name is null
var firstName = externalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:first_name"); // first name is null
var lastName = externalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:last_name"); // last name is null
}
ExternalLoginData:
private class ExternalLoginData
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public IList<Claim> GetClaims()
{
IList<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
if (UserName != null)
{
claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
}
if (Email != null)
{
claims.Add(new Claim(ClaimTypes.Email, Email, null, LoginProvider));
}
if (FirstName != null)
{
claims.Add(new Claim(ClaimTypes.GivenName, FirstName, null, LoginProvider));
}
if (LastName != null)
{
claims.Add(new Claim(ClaimTypes.Surname, LastName, null, LoginProvider));
}
return claims;
}
public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
{
Claim providerKeyClaim = identity?.FindFirst(ClaimTypes.NameIdentifier);
if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer) || String.IsNullOrEmpty(providerKeyClaim.Value))
{
return null;
}
if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
{
return null;
}
return new ExternalLoginData
{
LoginProvider = providerKeyClaim.Issuer,
ProviderKey = providerKeyClaim.Value,
UserName = identity.FindFirstValue(ClaimTypes.Name),
Email = identity.FindFirstValue(ClaimTypes.Email),
FirstName = identity.FindFirstValue(ClaimTypes.GivenName),
LastName = identity.FindFirstValue(ClaimTypes.Surname)
//ExternalAccessToken = identity.FindFirstValue("ExternalAccessToken"),
};
}
}