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?