序列化任何自定义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有任何其他想法?看起来应该非常简单,但是没有…

序列化任何自定义WCF SecurityToken的好方法

由于我发现没有其他好的方法来做到这一点,我最终做的是使我的自定义SecurityToken也实现IXmlSerializable,然后将我的序列化器的定义更改为:

public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer
    where T : SecurityToken, IXmlSerializable

我的自定义安全令牌定义为:

public class MySecurityToken : SecurityToken, IXmlSerializable

那么序列化器可以将序列化委托给自定义安全令牌。这可能不是最干净的解决方案(我想说它违反了单一责任原则),但它似乎确实有效,并且让我不必为每个自定义令牌编写序列化器。