How to deserialize a SecurityToken of type GenericXmlSecurityToken that has been serialized using WSSecurityTokenSerializer

32 Views Asked by At

I have 2 web services communicating together, both of them are .Net Framework 4.7.2. Service 1 (let's call it TokenFetcher) retrieves a System.IdentityModel.Tokens.SecurityToken of the type System.IdentityModel.Tokens.GenericXmlSecurityToken. I have validated that the token being fetched contains the private key. This was found in the GenericXmlSecurityToken.ProofToken.Certificate.PrivateKey attribute on the object. It is a boolean and returned true.

After the token has been fetched it is serialized and base64 encoded and sent to service 2 (let's call service 2 TokenUser). The TokenUser service decodes the base64 string and deserializes it into an object of a new GenericXmlSecurityToken. When validating if the new deserialized object contains the private key the boolean returns false.

I would expect the private key to be a part of the token after it has been deserialized since it was before the object was serialized.

This is how I serialize the token:

private string Serialize(SecurityToken token)
{
    try
    {
        using (var memoryStream = new MemoryStream())
        {
            var serializer = new WSSecurityTokenSerializer();
            var writer = new XmlTextWriter(memoryStream, Encoding.Default);
            serializer.WriteToken(writer, token);
            writer.Close();

            var bytes = memoryStream.ToArray();

            var base64Token = Base64Encode(bytes);

            return base64Token;
        }
    }
    catch (Exception ex)
    {
        throw new SerializingException(ex.Message);
    }
}

private string Base64Encode(byte[] bytes)
{
    var result = Convert.ToBase64String(bytes).Trim();
    return result;
}

And this is how the token is being deserialized:

private SecurityToken Deserialize(string encodedToken, string encodedProofToken, BaseGenericXmlSecurityToken baseToken)
{
    var serviceConfig = new SecurityTokenServiceConfiguration();
    var proofToken =
        serviceConfig.SecurityTokenHandlers.ReadToken(
            new XmlTextReader(new MemoryStream(Convert.FromBase64String(encodedProofToken))));

    var xml = Convert.FromBase64String(encodedToken);
    var doc = new XmlDocument();
    doc.LoadXml(Encoding.UTF8.GetString(xml));
    var xmlToken = new GenericXmlSecurityToken(
        doc.DocumentElement,
        proofToken,
        baseToken.ValidFrom,
        baseToken.ValidTo,
        baseToken.InternalTokenReference,
        baseToken.ExternalTokenReference,
        baseToken.AuthorizationPolicies
    );

    return xmlToken;
}

The baseToken is not relevant for this question and can be skipped. What is relevant is the proofToken attribute of the xmlToken object. This contains a certificate but not the private key part.

I would expect the private key part to be part of the Certificate in the ProofToken, but it is not. How can I fix it?

0

There are 0 best solutions below