Как придумать обновление токена безопасности для службы WCF?

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

  •  30-09-2019
  •  | 
  •  

Вопрос

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

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 для этого, как бы я реализовал приведенные выше примеры методов?

Это было полезно?

Решение

В моей кодовой базе мы на самом деле кэшируем токен, поэтому мы гарантируем, что не делаем повторяющихся вызовов в STS. Используя тот же метод, вы определенно можете изменить его вручную запрашивать другой токен, когда пожелаете. Вот как зацепить клиентские кадры:

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 (), ST будет предложено выпустить другой токен.

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

В файле App.config может быть способ установить свойство CacheissuedTokens, я просто не уверен в пути от макула моей головы.

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top