不保证以下代码不会过时,但适用于当前使用的 Dynamics CRM 版本(2011、2013 和 2015)。从 2015 年开始,支持 OAuth,这似乎是通过网络传递令牌的更好方式。
将SecurityTokenResponse 转换为Base64 编码字符串:
public static string Serialize(SecurityTokenResponse securityTokenResponse)
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Encoding = Encoding.UTF8;
using (MemoryStream memoryStream = new MemoryStream())
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
WSTrust13ResponseSerializer serializer = new WSTrust13ResponseSerializer();
WSTrustSerializationContext context = new WSTrustSerializationContext();
serializer.WriteXml(securityTokenResponse.Response, xmlWriter, context);
xmlWriter.Flush();
return Convert.ToBase64String(memoryStream.ToArray());
}
}
将 Base64 编码的字符串转换回SecurityTokenResponse:
public static SecurityTokenResponse ParseToken(string serializedToken)
{
RequestSecurityTokenResponse response;
using (MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(serializedToken)))
using (XmlReader xmlReader = XmlReader.Create(memoryStream))
{
WSTrust13ResponseSerializer serializer = new WSTrust13ResponseSerializer();
WSTrustSerializationContext serializationContext = new WSTrustSerializationContext();
response = serializer.ReadXml(xmlReader, serializationContext);
}
SecurityToken proofKey = new BinarySecretSecurityToken(response.RequestedProofToken.ProtectedKey.GetKeyBytes());
DateTime? created = null;
DateTime? expires = null;
if (response.Lifetime != null)
{
created = response.Lifetime.Created;
expires = response.Lifetime.Expires;
}
if (!created.HasValue)
{
throw new Exception("Created unspecified");
}
if (!expires.HasValue)
{
throw new Exception("Expires unspecified");
}
SecurityToken securityToken = new GenericXmlSecurityToken(
response.RequestedSecurityToken.SecurityTokenXml,
proofKey,
created.Value,
expires.Value,
response.RequestedAttachedReference,
response.RequestedUnattachedReference,
new ReadOnlyCollection<IAuthorizationPolicy>(new List<IAuthorizationPolicy>())
);
return new SecurityTokenResponse()
{
Response = response,
Token = securityToken
};
}
选择 Base64 作为编码的原因是因为我通过 XML Web 服务发送令牌。这消除了对 XML 字符串进行 XML 转义的需要。这可能会导致大量转义:&gt;、&lt;、&amp; 等。如果您没有通过 XML Web 服务发送序列化令牌,您可能希望使用更易读的编码,例如 @ 987654328@.