Come faccio a forzare un aggiornamento del token di sicurezza per un servizio WCF?

StackOverflow https://stackoverflow.com/questions/4138525

  •  30-09-2019
  •  | 
  •  

Domanda

Ho un servizio WCF che richiede un token di sicurezza rilasciato da un WCF STS servizio separato. Tutto questo funziona da dandy. Nella mia domanda, io uso il servizio in questo modo:

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 che l'handshake iniziale è finita, però, l'oggetto myService ha la cache token e ri-usa fino alla scadenza. Questo è un comportamento fine e tutti, ma come faccio a forza che 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.

Am ho attaccato solo facendo un nuovo oggetto classe proxy, vale a dire myService = new MyServiceClient();? Questo funziona, ma sembra che la soluzione di bomba nucleare.

In 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 sopra esempio?

È stato utile?

Soluzione

Nel mio codice di base, abbiamo effettivamente memorizzare nella cache il token modo ci assicuriamo che non facciamo ripetuti appelli ai STS. Utilizzando lo stesso metodo, si potrebbe sicuramente alterarla richiedere manualmente un altro gettone ogni volta che lo si desidera. 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 si chiama GetToken (), lo STS sarà chiesto di emettere un altro token.

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

Ci potrebbe essere un modo di impostare la proprietà CacheIssuedTokens nel file App.config, solo che non sono sicuro di un modo fuori della parte superiore della mia testa.

Altri suggerimenti

Potresti non utilizzare la proprietà IssuedToken.MaxIssuedTokenCachingTime e impostarlo a 0?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top