using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Federation;
using System.ServiceModel.Security;
using System.Threading.Tasks;
using System.IO.Compression;
public static async Task Main()
var endpoint = "https://si-idp.vfltest.dk/adfs/services/trust/13/usernamemixed";
var audience = "https://si-obapi.vfltest.dk/";
var token = await Issue(endpoint, audience, user, pass);
var tokenXml = token.TokenXml;
Console.WriteLine(tokenXml);
var encodedToken = new DeflatedSamlEncoder().Encode(tokenXml);
Console.WriteLine(encodedToken);
static async Task<(GenericXmlSecurityToken TypedToken, string TokenXml)> Issue(string endpoint, string audience, string user, string pass)
var issueEndpoint = new EndpointAddress(endpoint);
var binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
var tokenParameters = WSTrustTokenParameters.CreateWS2007FederationTokenParameters(binding, issueEndpoint);
tokenParameters.KeyType = SecurityKeyType.BearerKey;
var clientCredentials = new ClientCredentials();
clientCredentials.UserName.UserName = user;
clientCredentials.UserName.Password = pass;
var channelCredentials = new WSTrustChannelClientCredentials(clientCredentials);
var tokenManager = channelCredentials.CreateSecurityTokenManager();
var tokenRequirement = new SecurityTokenRequirement();
EndpointAddress appliesTo = new EndpointAddress(audience);
tokenRequirement.Properties["http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/IssuedSecurityTokenParameters"] = tokenParameters;
tokenRequirement.Properties["http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/TargetAddress"] = appliesTo;
tokenRequirement.Properties.Add("http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/SecurityAlgorithmSuite", SecurityAlgorithmSuite.TripleDes);
var tokenProvider = tokenManager.CreateSecurityTokenProvider(tokenRequirement);
((ICommunicationObject)tokenProvider).Open();
var token = await tokenProvider.GetTokenAsync(Timeout.InfiniteTimeSpan);
var tokenXmlProp = typeof(GenericXmlSecurityToken).GetProperties(BindingFlags.Public | BindingFlags.Instance).Single(p => p.Name == "TokenXml");
var xml = (XmlElement)tokenXmlProp.GetValue(token);
return ((GenericXmlSecurityToken)token, xml.OuterXml);
public class DeflatedSamlEncoder
private readonly Encoding _encoding = Encoding.UTF8;
private readonly DeflateCookieTransform _deflateCookieTransform = new DeflateCookieTransform();
public virtual string Encode(string token)
var bytes = _encoding.GetBytes(token);
var deflatedBytes = _deflateCookieTransform.Encode(bytes);
var base64String = Convert.ToBase64String(deflatedBytes);
var encodedToken = System.Net.WebUtility.UrlEncode(base64String);
public virtual string Decode(string encodedToken)
var base64String = System.Net.WebUtility.UrlDecode(encodedToken);
var deflatedBytes = Convert.FromBase64String(base64String);
var bytes = _deflateCookieTransform.Decode(deflatedBytes);
var token = _encoding.GetString(bytes);
private sealed class DeflateCookieTransform
public int MaxDecompressedSize
public byte[] Decode(byte[] encoded)
throw new ArgumentNullException(nameof(encoded));
throw new ArgumentException(nameof(encoded), "ID6045");
using (var deflateStream = new DeflateStream(new MemoryStream(encoded), CompressionMode.Decompress, false))
using (var memoryStream = new MemoryStream())
var buffer = new byte[1024];
count = deflateStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
if (memoryStream.Length > MaxDecompressedSize)
throw new SecurityException($"ID1068: {MaxDecompressedSize}");
return memoryStream.ToArray();
public byte[] Encode(byte[] value)
throw new ArgumentNullException(nameof(value));
throw new ArgumentException(nameof(value), "ID6044");
using (var memoryStream = new MemoryStream())
using (var deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, true))
deflateStream.Write(value, 0, value.Length);
var array = memoryStream.ToArray();