Хороший способ сериализации любого пользовательского WCF SecurityToken? - PullRequest
2 голосов
/ 19 октября 2011

Это сводит меня с ума ... Я пытаюсь получить собственный токен авторизации 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 : сделать взломанный объект безопасности 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 = нейтральный, PublicKeyToken = b77a5c561934e089]] не реализует метод Add (System.IdentitySl. ).

В связи с этим свойством на мой заказ 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? Кажется, это должно было быть очень просто, но нет ...

1 Ответ

0 голосов
/ 24 октября 2011

Так как я не нашел другого хорошего способа сделать это, в итоге я заставил свой Custom SecurityToken также реализовать IXmlSerializable, а затем изменил определение моего сериализатора на:

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

MyПользовательский токен безопасности затем определяется как:

public class MySecurityToken : SecurityToken, IXmlSerializable

Затем сериализатор может делегировать сериализацию на пользовательский токен безопасности.Возможно, это не самое чистое решение (я бы сказал, что оно нарушает принцип единоличной ответственности), но, похоже, оно работает, и мне не нужно писать сериализатор для каждого пользовательского токена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...