2015-09-18 14 views
7

संदर्भ: मैं ओविन स्वयं होस्ट के साथ एएसपी.नेट एमवीसी का उपयोग कर रहा हूं। नीचे बाकी कॉन्फ़िगरेशन/सेटअप हैं।पहचान सर्वर 3: कुछ दावा पहचान सर्वर से वापस नहीं लौटाए जा रहे हैं

पहचान सर्वर में मेरी ग्राहक रों में (AllowedScopes सेट दिखाई):

public static class InMemoryClientSource 
{ 
    public static List<Client> GetClientList() 
    { 
     return new List<Client>() 
     { 
      new Client() 
      { 
       ClientName = "Admin website", 
       ClientId = "admin", 
       Enabled = true, 
       Flow = Flows.Hybrid, 
       ClientSecrets = new List<Secret>() 
       { 
        new Secret("admin".Sha256()) 
       }, 
       RedirectUris = new List<string>() 
       { 
        "https://admin.localhost.com/" 
       }, 
       PostLogoutRedirectUris = new List<string>() 
       { 
        "https://admin.localhost.com/" 
       }, 
       AllowedScopes = new List<string> { 
        Constants.StandardScopes.OpenId, 
        Constants.StandardScopes.Profile, 
        Constants.StandardScopes.Email, 
        Constants.StandardScopes.Roles 
       } 
      } 
     }; 
    } 
} 

यहाँ कार्यक्षेत्र हैं:

public static class InMemoryScopeSource 
{ 
    public static List<Scope> GetScopeList() 
    { 
     var scopes = new List<Scope>(); 

     scopes.Add(StandardScopes.OpenId); 
     scopes.Add(StandardScopes.Profile); 
     scopes.Add(StandardScopes.Email); 
     scopes.Add(StandardScopes.Roles); 

     return scopes.ToList(); 
    } 
} 

पहचान सर्वर में, यहां बताया गया है कि सर्वर कैसे कॉन्फ़िगर किया गया है। (ध्यान दें ग्राहकों और कार्यक्षेत्र लोगों ऊपर प्रदान की जाती हैं):

var userService = new UsersService(.... repository passed here ....); 

     var factory = new IdentityServerServiceFactory() 
      .UseInMemoryClients(InMemoryClientSource.GetClientList()) 
      .UseInMemoryScopes(InMemoryScopeSource.GetScopeList()); 

     factory.UserService = new Registration<IUserService>(resolver => userService); 

     var options = new IdentityServerOptions() 
     { 
      Factory = factory, 
      SigningCertificate = Certificates.Load(), // certificates blah blah 
      SiteName = "Identity" 
     }; 

     app.UseIdentityServer(options); 

अंत में, ग्राहक वेब अनुप्रयोग तरफ, यह कैसे प्रमाणन सेट किया गया है:

app.UseCookieAuthentication(new CookieAuthenticationOptions() 
     { 
      AuthenticationType = "Cookies" 
     }); 

     app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() 
     { 
      Authority = "https://id.localhost.com", 
      ClientId = "admin", 
      RedirectUri = "https://admin.localhost.com/", 
      PostLogoutRedirectUri = "https://admin.localhost.com/", 
      ResponseType = "code id_token token", 
      Scope = "openid profile email roles", 
      ClientSecret = "admin", 
      SignInAsAuthenticationType = "Cookies" 
     }); 

मेरे पास है

public class UsersService : UserServiceBase 
{ 
    public UsersService(.... repository passed here ....) 
    { 
     //.... ctor stuff 
    } 

    public override Task AuthenticateLocalAsync(LocalAuthenticationContext context) 
    { 
     // var user = .... retrieved from database ..... 
     // ... auth logic ... 

     if (isAuthenticated) 
     { 
      var claims = new List<Claim>(); 
      claims.Add(new Claim(Constants.ClaimTypes.GivenName, user.FirstName)); 
      claims.Add(new Claim(Constants.ClaimTypes.FamilyName, user.LastName)); 
      claims.Add(new Claim(Constants.ClaimTypes.Email, user.EmailAddress)); 
      context.AuthenticateResult = new AuthenticateResult(user.Id.ToString(), user.EmailAddress, claims); 
     } 

     return Task.FromResult(0); 
    } 
} 

जैसा कि आप देख, का दावा है इस पंक्ति में पारित कर रहे हैं: IUserService के लिए एक कस्टम वर्ग कार्यान्वित:

context.AuthenticateResult = new AuthenticateResult(user.Id.ToString(), user.EmailAddress, claims); 

जब मैं पहचान सर्वर 3 में लॉग इन करने का प्रयास करता हूं, तो मैं क्लाइंट वेब एप्लिकेशन में सफलतापूर्वक लॉग इन कर सकता हूं। हाउवर, जब मुझे उपयोगकर्ता का दावा मिलता है, तो मुझे कोई पहचान दावा नहीं दिखता है। नहीं दिया_name, family_name, और ईमेल दावे। नीचे स्क्रीनशॉट:

As you can see, there are no given_name, family_name and email claims included.

कुछ भी मैं याद किया हो सकता है? अग्रिम में धन्यवाद!

+0

आपका विन्यास ठीक लग रहा है:

एक में स्मृति ग्राहक सब मैंने किया था के लिए कुछ इस तरह था। मूर्खतापूर्ण मुझे पता है, लेकिन क्या आप निश्चित हैं कि प्रमाणीकृत उपयोगकर्ता के पास ये दावा हैं? –

+0

अरे @ स्कॉटब्राडी, मुझे लगता है कि वे पहले से ही हैं क्योंकि मैंने संदर्भ में उन दावों को जोड़ा है। प्रमाणीकरण रीसेट (जैसा कि आप कस्टम उपयोगकर्ता सेवा कार्यान्वयन के लिए उपरोक्त नमूना कोड पर देखते हैं)। – jerbersoft

उत्तर

5

अंत में इस समस्या के लिए समाधान मिल गया।

सबसे पहले, मैंने अधिग्रहण GetProfileDataAsync (मेरे उपयोगकर्ता सेवा वर्ग में) के दावों के निर्माण को स्थानांतरित कर दिया।

public override Task GetProfileDataAsync(ProfileDataRequestContext context) 
     { 
      var identity = new ClaimsIdentity(); 

      UserInfo user = null; 
      if (!string.IsNullOrEmpty(context.Subject.Identity.Name)) 
       user = _facade.Get(context.Subject.Identity.Name); 
      else 
      { 
       // get the sub claim 
       var claim = context.Subject.FindFirst(item => item.Type == "sub"); 
       if (claim != null) 
       { 
        Guid userId = new Guid(claim.Value); 
        user = _facade.Get(userId); 
       } 
      } 

      if (user != null) 
      { 
       identity.AddClaims(new[] 
       { 
        new Claim(Constants.ClaimTypes.PreferredUserName, user.Username), 
        new Claim(Constants.ClaimTypes.Email, user.EmailAddress) 
        // .. other claims 
       }); 
      } 

context.IssuedClaims = identity.Claims; //<- MAKE SURE you add the claims here 
      return Task.FromResult(identity.Claims); 
     } 

सुनिश्चित करें कि हम GetProfileDataAsync अंदर "context.IssueClaims"() कार्य लौटने से पहले के दावों को पारित करें: यहाँ यह की मेरी कार्यान्वयन है।

और कैसे मेरी AuthenticateLocalAsync() की तरह दिखता है पर रुचि रखने वालों के लिए:

var user = _facade.Get(context.UserName); 
      if (user == null) 
       return Task.FromResult(0); 

      var isPasswordCorrect = BCrypt.Net.BCrypt.Verify(context.Password, user.Password); 
      if (isPasswordCorrect) 
      { 
       context.AuthenticateResult = new AuthenticateResult(user.Id.ToString(), user.Username); 
      } 

      return Task.FromResult(0); 

मैं IdentityServer3 GitHub परियोजना पृष्ठ में एक समान मुद्दा यह है कि क्यों मैं अपने मुद्दे का सामना करना पड़ा पर स्पष्टीकरण शामिल उठाया। यहां लिंक है: https://github.com/IdentityServer/IdentityServer3/issues/1938

+0

विधि "GetProfileDataAsync" में कोड का यह हिस्सा क्या है: var claim = context.Subject.FindFirst (item => item.Type == "sub"); अगर (दावा! = शून्य) { मार्गदर्शिका उपयोगकर्ता आईडी = नया ग्रिड (दावा। वैल्यू); उपयोगकर्ता = _facade.Get (userId); } – Jenan

+0

विधि "" GetProfileDataAsync "को दो बार बुलाया जाता है और पहले कॉल के बाद संदर्भ होता है। विषय। Identity.Name शून्य, शून्य क्यों है - क्या आप जानते हैं? – Jenan

+0

@ जेनान, अपने पहले प्रश्न का उत्तर देने के लिए," उप "(विषय के लिए छोटा) दावा उपयोगकर्ता नाम प्राप्त कर रहा है। _facade भाग को कभी भी न मानें क्योंकि यह उपयोगकर्ता को डेटाबेस से प्राप्त करने के लिए मेरा कोड है। आपके दूसरे प्रश्न के लिए, मुझे नहीं पता कि इसे दो बार क्यों कहा जाता है। शायद आप चाहें IdentityServer3 github चर्चा पर जाएं, कोई भी मदद करने में सक्षम हो सकता है। :) – jerbersoft

-1

मैं पहचान सर्वर का उपयोग नहीं कर रहा हूं, हालांकि मैं विंडोज आइडेंटिटी फाउंडेशन का उपयोग कर रहा हूं, जो मुझे विश्वास है कि पहचानकर्ता सर्वर क्या उपयोग करता है। दावों का उपयोग मैं उपयोग करने के लिए:

((ClaimsIdentity)User.Identity).Claims

+0

हाय @ आरएल, मैंने कोशिश की है लेकिन दावे अभी भी प्रश्न में स्क्रीनशॉट में देख सकते हैं। फिर भी धन्यवाद। :) – jerbersoft

4

मेरा समाधान उन दावों को वापस करने के लिए मेरे दायरे विन्यास के दावों की एक सूची जोड़ना था। विकी के दस्तावेज़ here ने इसका वर्णन किया।

public class Scopes 
{ 
    public static IEnumerable<Scope> Get() 
    { 
     return new Scope[] 
     { 
      StandardScopes.OpenId, 
      StandardScopes.Profile, 
      StandardScopes.Email, 
      StandardScopes.Roles, 
      StandardScopes.OfflineAccess, 
      new Scope 
      { 
       Name = "yourScopeNameHere", 
       DisplayName = "A Nice Display Name", 
       Type = ScopeType.Identity, 
       Emphasize = false, 
       Claims = new List<ScopeClaim> 
       { 
        new ScopeClaim("yourClaimNameHere", true), 
        new ScopeClaim("anotherClaimNameHere", true) 
       } 
      } 
     }; 
    } 
} 
संबंधित मुद्दे