0

Facebookから自分の電子メールアドレスを使用しているユーザーにサインします。私はまた、電子メールアドレスを返すためにFacebookのプロバイダーをオーバーライドしているWebApi電子メールアドレスを使用したFacebook認証

var facebookAuthenticationOptions = new FacebookAuthenticationOptions 
{ 
    AppId = facebookId, 
    AppSecret = facebookSecret, 
    Provider = new FacebookProvider() 
}; 
app.UseFacebookAuthentication(facebookAuthenticationOptions); 

::私は私のFacebookの認証を設定している

public class FacebookProvider : FacebookAuthenticationProvider 
{ 
    public override Task Authenticated(FacebookAuthenticatedContext context) 
    { 
     var accessTokenClaim = new Claim("ExternalAccessToken", context.AccessToken, "urn:facebook:access_token"); 
     context.Identity.AddClaim(accessTokenClaim); 
     var extraClaims = GetAdditionalFacebookClaims(accessTokenClaim); 
     context.Identity.AddClaim(new Claim(ClaimTypes.Email, extraClaims.First(k => k.Key == "email").Value.ToString())); 
     context.Identity.AddClaim(new Claim("Provider", context.Identity.AuthenticationType)); 
     context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name))); 

     var userDetail = context.User; 
     var link = userDetail.Value<string>("link") ?? string.Empty; 
     context.Identity.AddClaim(new Claim("link", link)); 
     context.Identity.AddClaim(new Claim("FacebookId", userDetail.Value<string>("id"))); 
     return Task.FromResult(0); 
    } 

    private static JsonObject GetAdditionalFacebookClaims(Claim accessToken) 
    { 
     var fb = new FacebookClient(accessToken.Value); 
     return fb.Get("me", new { fields = new[] { "email" } }) as JsonObject; 
    } 

すべてがMVCで正常に動作します - LoginOwinCallback機能では、私が取得できていますFacebookから返されたユーザーのメールアドレス私は外部クッキーの代わりにトークン認証を使用してWebApiで同じことを達成しようとしています。しかし、プロバイダに電子メールの要求を応答に追加することはできますが、次のルーチンでAuthenticateAsyncメソッドを呼び出すと、電子メールの要求は含まれません。

private async Task<ExternalLoginInfo> GetExternalLoginInfoAsync() 
{ 
    var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer); 

    if (result == null || result.Identity == null) return null; 

    var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier); 
    if (idClaim != null) 
    { 
     return new ExternalLoginInfo() 
     { 
      DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""), 
      ExternalIdentity = result.Identity, 
      Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value) 
     }; 
    } 

    return null; 
} 

私が間違っていることは何ですか?

答えて

0

同じ問題に直面している他の人にとっては、電子メールの申し立てが可能です。

まず、正常のFacebookからユーザーの電子メールアドレスを取得するために、Startup.Auth.csのConfigureAuth方法で認証をセットアップする必要があります:MVC AccountControllerクラスのLoginOwinCallback方法で

app.UseFacebookAuthentication(new FacebookAuthenticationOptions 
{ 
    AppId = facebookId, 
    AppSecret = facebookSecret, 
    Scope= {"email"}, 
    UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=email" 
}); 

電子メールアドレスは、var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();によって返されたExternalLoginInfoオブジェクトのEmailプロパティにあります。

WebAPI AccountControllerクラスの電子メールアドレスを取得するには、User.IdentityオブジェクトをClaimsIdentity型にキャストする必要があります。

[OverrideAuthentication] 
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] 
[AllowAnonymous] 
[Route("ExternalLogin", Name = "ExternalLogin")] 
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null) 
{ 
    if (error != null) 
    { 
     return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error)); 
    } 

    if (!User.Identity.IsAuthenticated) 
    { 
     return new ChallengeResult(provider, this); 
    } 

    // get all of the claims 
    var claimsIdentity = User.Identity as ClaimsIdentity; // this cast exposes all of the claims returned by Facebook 

    // get the external login details 
    var externalLogin = ExternalLoginData.FromIdentity(claimsIdentity); 

    if (externalLogin == null) 
    { 
     return InternalServerError(); 
    } 

    if (externalLogin.LoginProvider != provider) 
    { 
      AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
     return new ChallengeResult(provider, this); 
    } 

    var user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, 
      externalLogin.ProviderKey)); 

    var hasRegistered = user != null; 

    if (hasRegistered) 
    { 
     AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 

     var oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, 
      OAuthDefaults.AuthenticationType); 
     var cookieIdentity = await user.GenerateUserIdentityAsync(UserManager, 
      CookieAuthenticationDefaults.AuthenticationType); 

     var properties = ApplicationOAuthProvider.CreateProperties(user.UserName); 
     AuthenticationManager.SignIn(properties, oAuthIdentity, cookieIdentity); 
    } 
    else 
    { 
     var claims = claimsIdentity?.Claims ?? externalLogin.GetClaims(); 
     var identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType); 
     AuthenticationManager.SignIn(identity); 
    } 

    return Ok(); 
} 

これは、あなたがFacebookから返された電子メールの請求を見つけるために、アイデンティティにFindFirst方法を使用できることを意味します。

関連する問題