2010-11-09 15 views
8

Ho un servizio WCF che richiede un token di sicurezza emesso da un servizio STS WCF separato. Tutto questo funziona semplicemente dandy. Nella mia domanda, io uso il servizio in questo modo:Come impone un aggiornamento del token di sicurezza per un servizio WCF?

MyServiceClient myService = new MyServiceClient(); 
myService.Open(); 
myService.DoStuff(); 

Il servizio STS è chiamato ad ottenere un token e il token viene utilizzato per chiamare il metodo di servizio DoStuff.

Una volta terminato l'handshake iniziale, l'oggetto myService ha il token memorizzato nella cache e lo riutilizza fino alla scadenza. Questo è un buon comportamento e tutto, ma come potrei forzare per aggiornare il token?

myService.ClientCredentials.Invalidate(); // something like this? 

tale che se ho chiamato DoStuff() di nuovo sarebbe sapere che ha bisogno di andare alle STS ancora tanto come ha fatto la prima volta.

Sono bloccato solo a creare un nuovo oggetto di classe proxy, ad esempio myService = new MyServiceClient();? Funziona ma sembra la soluzione della bomba nucleare.

alternativa, c'è un modo per ottenere solo manualmente un nuovo token e sostituire quello attuale, cioè myService.ClientCredentials.Renew();?

Se devo fare una classe ClientCredentials personalizzati per fare questo, come faccio a implementare i metodi esempio di cui sopra?

risposta

4

Nel mio codice di base, abbiamo effettivamente memorizzare nella cache il token modo ci assicuriamo che non facciamo ripetuti appelli ai STS. Usando lo stesso metodo, puoi sicuramente modificarlo manualmente richiedendo un altro token ogni volta che lo desideri. Ecco come collegare in ClientCredentials:

public class CustomClientCredentials : ClientCredentials 
{ 
    public CustomClientCredentials() 
    { 
    } 

    protected CustomClientCredentials(ClientCredentials other) 
     : base(other) 
    { 
    } 

    protected override ClientCredentials CloneCore() 
    { 
     return new CustomClientCredentials(this); 
    } 

    /// <summary> 
    /// Returns a custom security token manager 
    /// </summary> 
    /// <returns></returns> 
    public override SecurityTokenManager CreateSecurityTokenManager() 
    { 
     return new CustomClientCredentialsSecurityTokenManager(this); 
    } 
} 


public class CustomClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager 
{ 
    public CustomClientCredentialsSecurityTokenManager(ClientCredentials credentials) 
     : base(credentials) 
    { 
    } 

    /// <summary> 
    /// Returns a custom token provider when a issued token is required 
    /// </summary> 
    public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) 
    { 
     if (IsIssuedSecurityTokenRequirement(tokenRequirement)) 
     { 
      // Adds the endpoint behaviors for calling the issuer 
      IssuedSecurityTokenProvider baseProvider = (IssuedSecurityTokenProvider)base.CreateSecurityTokenProvider(tokenRequirement); 

      CustomIssuedSecurityTokenProvider provider = new CustomIssuedSecurityTokenProvider(baseProvider); 
      return provider; 
     } 
     return base.CreateSecurityTokenProvider(tokenRequirement); 
    } 
} 


public class CustomIssuedSecurityTokenProvider : IssuedSecurityTokenProvider 
{ 
    private readonly IssuedSecurityTokenProvider _innerProvider; 

    public CustomIssuedSecurityTokenProvider(IssuedSecurityTokenProvider innerProvider) 
    { 
     _innerProvider = innerProvider; 
     CacheIssuedTokens = innerProvider.CacheIssuedTokens; 
     IdentityVerifier = innerProvider.IdentityVerifier; 
     IssuedTokenRenewalThresholdPercentage = innerProvider.IssuedTokenRenewalThresholdPercentage; 
     IssuerAddress = innerProvider.IssuerAddress; 
     IssuerBinding = innerProvider.IssuerBinding; 
     innerProvider.IssuerChannelBehaviors.ForEach(IssuerChannelBehaviors.Add); 
     KeyEntropyMode = innerProvider.KeyEntropyMode; 
     MaxIssuedTokenCachingTime = innerProvider.MaxIssuedTokenCachingTime; 
     MessageSecurityVersion = innerProvider.MessageSecurityVersion; 
     SecurityAlgorithmSuite = innerProvider.SecurityAlgorithmSuite; 
     SecurityTokenSerializer = innerProvider.SecurityTokenSerializer; 
     TargetAddress = innerProvider.TargetAddress; 
     innerProvider.TokenRequestParameters.ForEach(TokenRequestParameters.Add); 

     _innerProvider.Open(); 
    } 

    ~CustomIssuedSecurityTokenProvider() 
    { 
     _innerProvider.Close(); 
    } 

    protected override SecurityToken GetTokenCore(TimeSpan timeout) 
    { 
     // We're ignoring the CacheIssuedTokens property in order to force an STS call 
     var securityToken = _innerProvider.GetToken(timeout); 
     return securityToken; 
    } 
} 

Il metodo GetTokenCore() è dove i STS viene chiamato. Quando chiami GetToken(), verrà richiesto all'STS di emettere un altro token.

Dalla tua domanda, suppongo che voi sapete come collegare nella vostra ClientCredentials dal app.config.

Potrebbe esserci un modo per impostare la proprietà CacheIssuedTokens nel file App.config, non sono sicuro di un modo fuori di testa.

1

Non si può usare la proprietà IssuedToken.MaxIssuedTokenCachingTime e impostarla su 0?