7

पहचान सर्वर लागू किया गया है और अच्छी तरह से काम कर रहा है। Google लॉगिन काम कर रहा है और ईमेल सहित कई दावों को वापस कर रहा है।पहचान सर्वर 3 फेसबुक लॉगिन ईमेल प्राप्त करें

फेसबुक लॉगिन काम कर रहा है, और मेरे एप्लिकेशन के लाइव होने और ईमेल अनुमतियों का अनुरोध करता है जब में।

एक नया उपयोगकर्ता के लॉग समस्या यह है कि मैं नहीं OAuth समाप्ति बिंदु से वापस ईमेल प्राप्त कर सकते हैं और मैं नहीं कर सकता है उपयोगकर्ता जानकारी मैन्युअल रूप से अनुरोध करने के लिए access_token को प्रतीत होता है। मेरे पास फेसबुक लॉगिन एंडपॉइंट से वापस "कोड" है।

यहां पहचान सर्वर सेटअप है।

var fb = new FacebookAuthenticationOptions 
      { 
       AuthenticationType = "Facebook", 
       SignInAsAuthenticationType = signInAsType, 
       AppId = ConfigurationManager.AppSettings["Facebook:AppId"], 
       AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"] 
      }; 

      fb.Scope.Add("email"); 

      app.UseFacebookAuthentication(fb); 

तो निश्चित रूप से मैं AuthenticateLocalAsync विधि अनुकूलित किया है, लेकिन दावों मैं केवल प्राप्त कर रहा हूँ नाम शामिल हैं। कोई ईमेल दावा नहीं।

पहचान सर्वर के लिए स्रोत कोड के माध्यम से खोदने के बाद, मुझे एहसास हुआ कि फेसबुक दावों को बदलने के लिए कुछ दावों की घटनाएं हो रही हैं, इसलिए मैंने उस कक्षा को डीबग करने के लिए बढ़ाया और देखा कि क्या यह किसी भी दावों को अलग कर रहा है, जो यह नहीं है।

मैंने फिडलर के साथ http कॉल भी देखे, और मुझे केवल निम्नलिखित दिखाई देता है (क्षमा करें क्योंकि कोड स्वरूपण यूआरएल पर बहुत अच्छा काम नहीं करता है। मैंने क्वेरीस्ट्रिंग पैराम्स को अपनी लाइनों को प्रारूपित करने की कोशिश की लेकिन यह नहीं लिया)

  1. (facebook.com)

    /संवाद/OAuth ? response_type = कोड & client_id = xxx & redirect_uri = https% 3A% 2F% 2Fidentity। [साइट] .com% 2Fid % 2Fsignin-facebook & गुंजाइश = ईमेल & राज्य = xxx

  2. (facebook.com)

    /login.php ? Skip_api_login = 1 & api_key = xxx & signed_next = 1 & अगले = https% 3A% 2F% 2Fwww.facebook.com% 2Fv2.7% 2Fdialog% 2Foauth% 3Fredirect_uri% 3Dhttps% 253A% 252F% 252Fidentity। [साइट] .com% 252Fid% 252Fsignin-फेसबुक% 26state% 3Dxxx% 26scope% 3Demail% 26response_type% 3Dcode% 26client_id% 3Dxxx% 26ret% 3Dlogin% 26logger_id% 3Dxxx & cancel_url = https% 3A% 2F% 2 पहचान। [साइट]। कॉम% 2Fid% 2Fsignin-फेसबुक% 3Ferror% 3Daccess_denied% 26error_code% 3D200% 26error_description% 3DPermissions% 2Berror% 26error_reason% 3Duser_denied% 26state% 3Dxxx% 23_% 3D_ & प्रदर्शन = पेज & स्थान = hi & logger_id = xxx

  3. (facebook.com)

    पोस्ट/कुकी/सहमति /? पीवी = 1 & डीपीआर = 1 HTTP/1,1

  4. (facebook.com)

    /login.php ? Login_attempt = 1 & अगला = https% 3 ए% 2 एफ% 2Fwww.facebook.com% 2Fv2.7% 2Fdialog% 2Foauth% 3Fredirect_uri% 3Dhttps% 253A% 252F% 252Fidentity। [साइट]।कॉम% 252Fid% 252Fsignin-फेसबुक% 26state% 3Dxxx% 26scope% 3Demail% 26response_type% 3Dcode% 26client_id% 3Dxxx% 26ret% 3Dlogin% 26logger_id% 3Dxxx & lwv = 100

  5. (facebook.com)

    /v2.7/dialog/oauth ? redirect_uri = https% 3A% 2F% 2Fidentity। [साइट] .com% 2Fid% 2Fsignin-फेसबुक & राज्य = xxx & गुंजाइश = ईमेल & response_type = कोड & client_id = xxx & ret = लॉगिन & logger_id = xxx & हैश = xxx

  6. (पहचान सर्वर)

    /आईडी/साइन-इन-फेसबुक ? कोड = xxx & राज्य = xxx

मैं कोड देखा उस अंतिम कॉल पर पैरामीटर और सोचा कि शायद मैं फेसबुक एपीआई https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow

से access_token प्राप्त करने के लिए कोड का उपयोग कर सकता हूं

हालांकि जब मैंने कोशिश की कि मुझे एपीआई से एक संदेश मिलता है तो मुझे बता रहा है कि कोड पहले ही इस्तेमाल हो चुका है।

मैंने UserInformationEndpoint को फेसबुक प्रमाणीकरण विकल्प में बदलने की कोशिश की ताकि इसे ईमेल के लिए पूछने के लिए मजबूर किया जा सके? फ़ील्ड = ईमेल डिफ़ॉल्ट एंडपॉइंट स्थान के अंत में ईमेल करें, लेकिन इससे पहचान सर्वर त्रुटि को थूकने का कारण बनता है "वहां था बाहरी प्रदाता में लॉग इन करने में त्रुटि। त्रुटि संदेश है: access_denied "।

यदि मैं respond_type = id_token के साथ अनुरोध भेजने के लिए मिडलवेयर बदल सकता हूं तो मैं इसे ठीक करने में सक्षम हो सकता हूं, लेकिन मैं यह नहीं समझ सकता कि यह कैसे करना है या उस टोकन को निकालने के तरीके को कैसे निकालना है फेसबुक सी # एसडीके का उपयोग करने में सक्षम होने के लिए पहली जगह।

तो मुझे लगता है कि कोई भी मदद या दिशा बिल्कुल शानदार होगी। मैंने अनगिनत घंटे शोध किए और समस्या को हल करने की कोशिश की है। मुझे बस इतना करना है कि लॉग इन-इन उपयोगकर्ता का ईमेल पता IdentityServer3 के माध्यम से प्राप्त करें। इतना कठिन नहीं लगता है और फिर भी मैं अटक गया हूँ।

+0

क्या आप प्राधिकरण कोड के साथ "प्रोफ़ाइल" दायरा प्राप्त करने का प्रयास कर सकते हैं। इससे आपको उपयोगकर्ता और उसके गुणों के बारे में कुछ जानकारी मिल सकती है। आपके द्वारा अनुरोध किए जा रहे स्कोप क्या हैं? और यदि यह प्राधिकरण कोड प्रवाह है तो उन क्षेत्रों को वह हिस्सा होना चाहिए जहां हम प्राधिकरण कोड का अनुरोध कर रहे हैं। –

+0

हाय मित्र, आपके सुझाव के लिए धन्यवाद। मैं वास्तव में पहले से ही किसी भी सफलता के साथ कोशिश की थी। जब मैं "प्रोफ़ाइल" दायरा जोड़ने की कोशिश करता हूं तो मुझे यह संदेश वापस मिल रहा है। बाहरी प्रदाता में लॉग इन करने में त्रुटि हुई थी। त्रुटि संदेश है: access_denied। कोई सुझाव? – Ryan

+1

आईडी_Token से जानकारी निकालने का एक और तरीका है, शायद आप उस id_token को उस HTTP प्रतिक्रिया से प्राप्त करने में सक्षम होना चाहिए जिसे आप auth_code के साथ टोकन का अनुरोध करते समय प्राप्त करते हैं। –

उत्तर

3

मुझे अंत में यह पता चला। जवाब में मित्रा की टिप्पणियों के साथ कुछ करना है, हालांकि उन उत्तरों में से कोई भी बिल बिलकुल फिट नहीं लग रहा था, इसलिए मैं यहां एक और डाल रहा हूं। सबसे पहले, आपको access_token, फेसबुक के प्रमाणीकरण एंडपॉइंट से कोड (प्रमाणीकरण कोड) का अनुरोध करने की आवश्यकता नहीं है। ऐसा करने के लिए, इसे सेट अप इस

 var fb = new FacebookAuthenticationOptions 
     { 
      AuthenticationType = "Facebook", 
      SignInAsAuthenticationType = signInAsType, 
      AppId = ConfigurationManager.AppSettings["Facebook:AppId"], 
      AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"], 
      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); 
       } 
      } 

     }; 

     fb.Scope.Add("email"); 

     app.UseFacebookAuthentication(fb); 

की तरह फिर, एक बार यह लॉग ऑन है आप प्रतिक्रिया को पकड़ने के लिए की जरूरत है। मैं IdentityServer3 Samples Repository, जो ओवरराइड करता है से निम्नलिखित file उपयोग कर रहा हूँ (पढ़ें, कार्यक्षमता प्रदान करता है) के लिए बाहरी साइटों से उपयोगकर्ता को लॉग इन करने के लिए आवश्यक विधियां। इस प्रतिक्रिया से, मैं C# Facebook SDK का उपयोग कर रहा हूं जो बाहरी प्रमाणीकरण कॉन्टेक्स्ट में नए लौटाए गए एक्सेस_टोकन दावे के साथ मुझे आवश्यक फ़ील्ड का अनुरोध करने और दावों की सूची में जोड़ने के लिए उपयोग कर रहा है। फिर मैं उपयोगकर्ता को बनाने/लॉग इन करने के लिए उस जानकारी का उपयोग कर सकता हूं।

public override async Task AuthenticateExternalAsync(ExternalAuthenticationContext ctx) 
    { 
     var externalUser = ctx.ExternalIdentity; 
     var claimsList = ctx.ExternalIdentity.Claims.ToList(); 
     if (externalUser.Provider == "Facebook") 
     { 
      var extraClaims = GetAdditionalFacebookClaims(externalUser.Claims.First(claim => claim.Type == "urn:facebook:access_token")); 
      claimsList.Add(new Claim("email", extraClaims.First(k => k.Key == "email").Value.ToString())); 
      claimsList.Add(new Claim("given_name", extraClaims.First(k => k.Key == "first_name").Value.ToString())); 
      claimsList.Add(new Claim("family_name", extraClaims.First(k => k.Key == "last_name").Value.ToString())); 
     } 

     if (externalUser == null) 
     { 
      throw new ArgumentNullException("externalUser"); 
     } 

     var user = await userManager.FindAsync(new Microsoft.AspNet.Identity.UserLoginInfo(externalUser.Provider, externalUser.ProviderId)); 
     if (user == null) 
     { 
      ctx.AuthenticateResult = await ProcessNewExternalAccountAsync(externalUser.Provider, externalUser.ProviderId, claimsList); 
     } 
     else 
     { 
      ctx.AuthenticateResult = await ProcessExistingExternalAccountAsync(user.Id, externalUser.Provider, externalUser.ProviderId, claimsList); 
     } 
    } 

और यही वह है! यदि इस प्रक्रिया को सरल बनाने के लिए आपके पास कोई सुझाव है, तो कृपया मुझे बताएं।मैं फेसबुक कोड प्रमाणीकरण विकल्प से एपीआई को कॉल करने के लिए इस कोड को संशोधित करने जा रहा था, लेकिन घटनाक्रम संपत्ति अब स्पष्ट रूप से मौजूद नहीं है।

संपादित करें: GetAdditionalFacebookClaims विधि केवल एक विधि है जो एक नया फेसबुक क्लाइंट बनाता है जो एक्सेस टोकन दिया जाता है और अन्य उपयोगकर्ता दावों के लिए फेसबुक एपीआई से पूछताछ करता है। उदाहरण के लिए, मेरी विधि इस तरह दिखती है:

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

निश्चित रूप से मुझे सही दिशा में ले जा रहा है। हालांकि मैं नहीं देख रहा हूं कि GetAdditionalFacebookClaims विधि मौजूद है। –

+0

@Chris_ मैंने जिस विधि को आप खो रहे थे उसे प्रदान करने के लिए उत्तर अपडेट किया है। – Ryan

+3

यदि आप 'फेसबुक प्रमाणीकरणप्रदाता.ऑन प्रमाणीकृत' के अंदर फेसबुक से ईमेल प्राप्त करने का तर्क डालते हैं, तो आपको 'प्रमाणीकरणExternalAsync() 'के अंदर विशेष केस तर्क की आवश्यकता नहीं है। –

संबंधित मुद्दे