2015-01-26 23 views
6

Sto provando a seguire la semplice guida mvcGettingStarted. Ora, ho implementato entrambi i provider GoogleAuthentication e FacebookAuthentication e tutto funziona come previsto, posso effettivamente effettuare l'accesso e, se accedo con il mio server di identità, ho ricevuto anche le richieste di ruolo per utente. Mi stavo chiedendo, e se volessi mantenere tutte le richieste avanzate dai fornitori esterni? Semplice esempio. Ecco come il mio Facebook configurazione fornitore assomiglia:Thinktecture Identity Server v3 Come mantenere crediti da fornitori esterni?

var facebookOptions = new FacebookAuthenticationOptions() { 
      AuthenticationType = "Facebook", 
      Caption = "Sign in with Facebook", 
      AppId = "*****", 
      AppSecret = "****", 
      SignInAsAuthenticationType = signInAsType, 
      Provider = new FacebookAuthenticationProvider() { 
       OnAuthenticated = (context) => { 

        foreach (var x in context.User) { 
         context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString())); 
        } 

        return Task.FromResult(context); 
       } 
      }, 
     }; 

     facebookOptions.Scope.Add("email"); 
     facebookOptions.Scope.Add("public_profile"); 
     facebookOptions.Scope.Add("user_friends"); 

     app.UseFacebookAuthentication(facebookOptions); 

In per ogni loop sto cercando di memorizzare tutti i Facebook sostiene in Identity, ma quando torno nel SecurityTokenValidated richiamata, la mia identità hasn sono loro.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() { 
      Authority = "https://localhost:44302/identity/", 
      ClientId = "my_client", 
      Scope = "openid profile roles email", 
      RedirectUri = "https://localhost:44302/", 
      ResponseType = "id_token token", 
      SignInAsAuthenticationType = "Cookies", 
      UseTokenLifetime = false, 
      Notifications = new OpenIdConnectAuthenticationNotifications() { 

       SecurityTokenValidated = async context => { 
        //let's clean up this identity 

        //context.AuthenticationTicket.Identity doesn't have the claims added in the facebook callback 
        var nid = new ClaimsIdentity(
         context.AuthenticationTicket.Identity.AuthenticationType, 
         Constants.ClaimTypes.GivenName, 
         Constants.ClaimTypes.Role); 
        ........ 

È perché sto manipolando due identità diverse? C'è un modo giusto per ottenere ciò che sto cercando di fare? Grazie.

risposta

4

Lo si farebbe nell'implementazione del servizio utente personalizzato. Quello predefinito rende disponibili le attestazioni dal fornitore esterno. Documenti su un servizio utente personalizzato: https://identityserver.github.io/Documentation/docsv2/advanced/userService.html

+0

il collegamento risulta in 404 https://identityserver.github.io/Documentation/docs/advanced/userService.html – Rahatur

+0

collegamento corretto ................... –

6

Come ha detto @brock-allen, il servizio utente è la strada giusta da seguire. Così sono andato avanti e implementato un semplice UserService

public class UserService { 
    private static InMemoryUserService _service = null; 
    public static InMemoryUserService Get() { 
     if(_service == null) 
      _service = new InMemoryUserService(Users.Get()); 

     return _service; 
    } 
} 

registrato il mio userservice nella mia fabbrica come questo

public void Configuration(IAppBuilder app) { 
     AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; 
     JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

     var factory = InMemoryFactory.Create(
      users: Users.Get(), 
      clients: Clients.Get(), 
      scopes: Scopes.Get()); 
     factory.UserService = new Registration<IUserService>(resolver => UserService.Get()); 

..... 

(Naturalmente questo è il metodo di configurazione all'interno della mia classe di avvio)

Così ora Posso autenticare l'utente esterno all'interno della callback di autenticazione del provider esterno (in questo caso Facebook), specificando tutti i reclami di cui ho bisogno:

var facebookOptions = new FacebookAuthenticationOptions() { 
      AuthenticationType = "Facebook", 
      Caption = "Sign in with Facebook", 
      AppId = "******", 
      AppSecret = "*******", 
      SignInAsAuthenticationType = signInAsType, 
      Provider = new FacebookAuthenticationProvider() { 
       OnAuthenticated = (context) => { 

        foreach (var x in context.User) { 
         context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString())); 
        } 

        ExternalIdentity identity = new ExternalIdentity() { 
         Claims = context.Identity.Claims, 
         Provider = "Facebook", 
         ProviderId = "Facebook" 
        }; 
        SignInMessage signInMessage = new SignInMessage(); 

        UserService.Get().AuthenticateExternalAsync(identity, signInMessage); 


        return Task.FromResult(context); 
       } 
      }, 
     } 

Ora, posso fare

List<Claim> claims = await UserService.Get().GetProfileDataAsync(User as ClaimsPrincipal) as List<Claim>; 

E vedere che il mio utente ha tutte le pretese facebook forniti durante l'autenticazione. Ovviamente questo codice è solo a scopo di test, può essere migliorato molto.

+0

Sto attraversando alcune lotte che comprendono anche rivendicazioni locali o esterne. Vedi http://stackoverflow.com/questions/28748000/confusion-over-local-authority-claims-and-external-provider-claims. Sei in grado di far luce su questo? – Raj

+2

@Daniele puoi pubblicare un intero codice? Sono molto interessato. Thx – mbrc

+1

AuthenticateExternalAsync è un metodo di estensione? Non sono riuscito a trovarne uno che accetti quegli arg. Quello che ho qui accetta solo un ExternalAuthenticationContext come argomento e non ha sovraccarico. –