【问题标题】:Good way to serialize any custom WCF SecurityToken?序列化任何自定义 WCF SecurityToken 的好方法?
【发布时间】:2011-10-18 20:41:44
【问题描述】:

这让我发疯了...我正在尝试使用源自 System.IdentityModel.Tokens.SecurityToken 的自定义 WCF 身份验证令牌,例如:

    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 的自定义序列化程序,但我正在尝试找到一种以通用方式执行此操作的方法,我可以制作一个可以序列化任何 &lt;T&gt; where T : SecurityToken 的序列化程序

这是我尝试过的,但失败了:


尝试 1:将 SecurityToken 设为 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);
    }

这失败并出现错误:

System.InvalidOperationException:出现反映类型“PartsSource.Services.Core.ServiceModel.SecurityTokenSerializerTest.TestSecurityToken”的错误。 ---> System.InvalidOperationException:要成为 XML 可序列化的,从 ICollection 继承的类型必须在其继承层次结构的所有级别上都有 Add(System.IdentityModel.Tokens.SecurityKey) 的实现。 System.Collections.ObjectModel.ReadOnlyCollection`1[[System.IdentityModel.Tokens.SecurityKey, System.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 有任何其他想法?看起来应该很简单,但没有......

【问题讨论】:

    标签: c# .net wcf xml-serialization wcf-security


    【解决方案1】:

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

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

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

    public class MySecurityToken : SecurityToken, IXmlSerializable
    

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

    【讨论】:

    • 请您举一个可序列化如何在 MySecurityToken 上工作的代码示例? @CodingWithSpike
    • @Zinov。您可以在任何地方找到它们……该问题并非特定于 SecurityTokens。 codeproject.com/Articles/43237/…stackoverflow.com/questions/279534/…
    • 你能显示你的序列化代码吗?我模仿了你,但得到了同样的错误(令牌序列化程序无法序列化'TestSecurityToken'。如果这是一个自定义类型,你必须提供一个自定义序列化程序。)..(在此之后启动代码)XmlWriterSettings xws = new XmlWriterSettings(); /**/ xws.Indent = false; /**/ xws.NewLineHandling = NewLineHandling.None; /**/ /**/ SecurityTokenSerializer ser = new SecurityTokenSerializer();/**/ using (XmlWriter xw = XmlWriter.Create(@"C:\temp\myfile.xml", xws)) /**/ { ser.WriteToken(xw, myToken);/**/ }
    猜你喜欢
    • 1970-01-01
    • 2010-11-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    相关资源
    最近更新 更多