كيف أجبر على تحديث رمز الأمان لخدمة WCF؟
-
30-09-2019 - |
سؤال
لدي خدمة WCF تتطلب رمزًا أمانًا صادرًا من خدمة WCF STS منفصلة. كل هذا يعمل فقط dandy. في طلبي ، أستخدم الخدمة مثل SO:
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. باستخدام نفس الطريقة ، يمكنك بالتأكيد تغييرها يدويًا مميزًا آخر كلما ترغب في ذلك. إليك كيفية ربط 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.
قد تكون هناك طريقة لتعيين خاصية CacheissuedTokens في ملف App.Config ، لست متأكدًا من إبعاد رأسي.
نصائح أخرى
ألا يمكنك استخدام IssuedToken.MaxIssuedTokenCachingTime
خاصية وتعيينها على 0؟