This is making me crazy... I'm trying to have a custom WCF auth token that derives from System.IdentityModel.Tokens.SecurityToken
for example:
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; }
}
I know I can write a custom serializer for it that extends WSSecurityTokenSerializer
, but I am trying to find a way to do that in a generic way, where I can make a serializer that can serialize any <T> where T : SecurityToken
Here is what I have tried, and failed:
Attempt 1: Make the SecurityToken a DataContract
[DataContract]
public class TestSecurityToken : SecurityToken
Fails because you cant have a DataContract that derives from a base class that isn't a DataContract, which SecurityToken is not.
Attempt 2: Serialize with an 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);
}
This fails with the error:
System.InvalidOperationException: There was an error reflecting type 'PartsSource.Services.Core.ServiceModel.SecurityTokenSerializerTest.TestSecurityToken'. ---> System.InvalidOperationException: To be XML serializable, types which inherit from ICollection must have an implementation of Add(System.IdentityModel.Tokens.SecurityKey) at all levels of their inheritance hierarchy. System.Collections.ObjectModel.ReadOnlyCollection`1[[System.IdentityModel.Tokens.SecurityKey, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] does not implement Add(System.IdentityModel.Tokens.SecurityKey).
Due to this property on my custom SecurityToken
:
public override ReadOnlyCollection<SecurityKey> SecurityKeys
{ get { return new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>(0)); } }
Attempt 3: Same as above, but try to tell the XmlSerializer to ignore that SecurityKeys property:
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);
}
This errors with the same message as the previous attempt. It does not ignore this property.
Does anyone have any other ideas on how to just serialize any SecurityToken to an XmlReader / XmlWriter? It seems like it should have been dead simple, but no...