序列化任何自定义WCF SecurityToken的好方法
本文关键字:方法 SecurityToken WCF 任何 自定义 序列化 | 更新日期: 2023-09-27 18:11:42
这让我发疯了…我试图有一个自定义WCF认证令牌,从System.IdentityModel.Tokens.SecurityToken
派生,例如:
public class TestSecurityToken : SecurityToken
{
public override string Id
{ get { return "123"; } }
public override ReadOnlyCollection<SecurityKey> SecurityKeys
{ get { return new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>(0)); } }
public override DateTime ValidFrom
{ get { return DateTime.MinValue; } }
public override DateTime ValidTo
{get { return DateTime.MaxValue; } }
public string Property1 { get; set; }
}
我知道我可以为它写一个扩展WSSecurityTokenSerializer
的自定义序列化器,但我正试图找到一种通用的方式来做到这一点,在那里我可以制作一个序列化器,可以序列化任何<T> where T : SecurityToken
这是我尝试过的,失败了:
尝试1: Make SecurityToken a DataContract
[DataContract]
public class TestSecurityToken : SecurityToken
失败,因为你不能有一个派生自非DataContract基类的DataContract,而SecurityToken不是。
尝试2:使用XmlSerializer序列化
public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer where T : SecurityToken
{
private readonly XmlSerializer serializer;
public SecurityTokenSerializer()
{
serializer = new XmlSerializer(typeof (T));
}
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
serializer.Serialize(writer, token);
}
失败,报错:
系统。InvalidOperationException:有一个反映类型'PartsSource.Services.Core.ServiceModel.SecurityTokenSerializerTest.TestSecurityToken'的错误。——>系统。InvalidOperationException:要使XML可序列化,从ICollection继承的类型必须在其继承层次的所有级别上具有Add(System.IdentityModel.Tokens.SecurityKey)的实现。[[System.IdentityModel.Tokens System.Collections.ObjectModel.ReadOnlyCollection"1。SecurityKey、系统。IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]没有实现Add(System.IdentityModel.Tokens.SecurityKey).
由于这个属性在我的自定义SecurityToken
:
public override ReadOnlyCollection<SecurityKey> SecurityKeys
{ get { return new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>(0)); } }
尝试3:与上面相同,但尝试告诉XmlSerializer忽略SecurityKeys属性:
public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer where T : SecurityToken
{
private readonly XmlSerializer serializer;
public SecurityTokenSerializer()
{
var xOver = new XmlAttributeOverrides();
xOver.Add(typeof(T), "SecurityKeys", new XmlAttributes { XmlIgnore = true });
serializer = new XmlSerializer(typeof (T), xOver);
}
此错误显示与上次尝试相同的消息。它不会忽略此属性。
有没有人对如何将任何SecurityToken序列化到XmlReader/XmlWriter有任何其他想法?看起来应该非常简单,但是没有…
由于我发现没有其他好的方法来做到这一点,我最终做的是使我的自定义SecurityToken也实现IXmlSerializable
,然后将我的序列化器的定义更改为:
public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer
where T : SecurityToken, IXmlSerializable
我的自定义安全令牌定义为:
public class MySecurityToken : SecurityToken, IXmlSerializable
那么序列化器可以将序列化委托给自定义安全令牌。这可能不是最干净的解决方案(我想说它违反了单一责任原则),但它似乎确实有效,并且让我不必为每个自定义令牌编写序列化器。