【问题标题】:How do I force a refresh of the security token for a WCF service?如何强制刷新 WCF 服务的安全令牌?
【发布时间】:2011-05-07 12:21:25
【问题描述】:

我有一个 WCF 服务,它需要由单独的 WCF STS 服务颁发的安全令牌。这一切都只是花花公子。在我的应用程序中,我使用这样的服务:

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

调用STS Service获取token,token用于调用服务方法DoStuff。

不过,一旦初始握手结束,myService 对象就会缓存令牌并重新使用它,直到它过期。这是很好的行为,但我将如何强制刷新令牌?

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

这样,如果我再次调用 DoStuff(),它就会知道它需要再次访问 STS,就像第一次一样。

我只是在创建一个新的代理类对象,即myService = new MyServiceClient(); 吗?这可行,但它似乎是核弹解决方案。

或者,有没有办法手动获取新令牌并替换当前令牌,即myService.ClientCredentials.Renew();

如果我必须创建一个自定义 ClientCredentials 类来执行此操作,我将如何实现上述示例方法?

【问题讨论】:

    标签: wcf credentials wif


    【解决方案1】:

    您不能使用IssuedToken.MaxIssuedTokenCachingTime 属性并将其设置为0 吗?

    【讨论】:

      【解决方案2】:

      在我的代码库中,我们实际上缓存了令牌,因此我们确保不会重复调用 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 将被要求发布另一个令牌。

      根据您的问题,我假设您知道如何从 app.config 连接到您的 ClientCredentials。

      可能有一种方法可以在 App.config 文件中设置 CacheIssuedTokens 属性,我只是不确定有什么办法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-29
        • 1970-01-01
        • 2022-01-19
        • 2016-06-12
        • 2020-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多