Web APi 2 OAuth用户配置文件信息

时间:2017-01-09 06:29:40

标签: asp.net .net facebook-graph-api asp.net-web-api oauth

我正在使用WEB API 2Angularjs作为前端开发应用程序,两者都是单独托管的。应用程序需要外部登录,如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"),
            };
        }
    }

0 个答案:

没有答案