Как принудительно обновить токен безопасности для службы WCF? - PullRequest
8 голосов
/ 09 ноября 2010

У меня есть служба WCF, для которой требуется токен безопасности, выданный отдельной службой STF WCF.Это все работает просто денди.В моем приложении я использую службу следующим образом:

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

Служба STS вызывается для получения токена, а токен используется для вызова метода службы DoStuff.

После инициализацииоднако рукопожатие закончено, объект myService кэширует токен и использует его до истечения срока действия.Это нормальное поведение и все такое, но как бы я заставил обновить его токен?

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

Так, что если бы я снова вызвал DoStuff (), он бы знал, что нужно перейти кснова STS, как это было в первый раз.

Я застрял, просто делая новый объект прокси-класса, то есть myService = new MyServiceClient();?Это работает, но похоже на решение ядерной бомбы.

Кроме того, есть ли способ просто вручную получить новый токен и заменить текущий, то есть myService.ClientCredentials.Renew();?

Если у меня естьчтобы сделать собственный класс ClientCredentials для этого, как бы я реализовал приведенные выше примеры методов?

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

В моей кодовой базе мы фактически кэшируем токен, поэтому мы гарантируем, что не будем повторять вызовы STS. Используя тот же метод, вы можете определенно изменить его вручную, запросив другой токен, когда захотите. Вот как подключиться к 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;
    }
}

Метод GetTokenCore () - это место, где вызывается STS. Когда вы вызываете GetToken (), STS будет предложено выпустить другой токен.

Исходя из вашего вопроса, я предполагаю, что вы знаете, как подключиться к своим ClientCredentials из app.config.

Возможно, есть способ установить свойство CacheIssuedTokens в файле App.config, но я просто не уверен, что мне это удастся.

1 голос
/ 12 ноября 2010

Не могли бы вы использовать свойство IssuedToken.MaxIssuedTokenCachingTime и установить его в 0?

...