Skip to content

Instantly share code, notes, and snippets.

@bsrini
Created April 4, 2011 19:08
Show Gist options
  • Save bsrini/902209 to your computer and use it in GitHub Desktop.
Save bsrini/902209 to your computer and use it in GitHub Desktop.
Federating authentication from ADFS to ACS to get to a WCF REST Service
void Main()
{
// Get the SAML token from ADFS server
var adfsAddress = "https://server/adfs/services/trust/13/kerberosmixed";
var samlFormat = "SAML1.1";
var appliesTo = "https://namespace.accesscontrol.appfabriclabs.com";
string samlToken = GetSamlClaim(adfsAddress, samlFormat, appliesTo);
// Get the SWT token from ACS using the SAML token obtained above.
var wrapToken = SendSAMLTokenToACS(
samlToken,
"https://namespace.accesscontrol.appfabriclabs.com/WRAPv0.9",
"https://relyingparty/endpoint");
"--------".Dump();
// Call the service, with the SWT token.
var client = new System.Net.WebClient();
client.Headers.Add("X-Authorization", wrapToken);
try
{
var response = client.DownloadString("https://relyingparty/endpoint");
response.Dump();
}
catch (WebException wex)
{
wex.Response.Headers[System.Net.HttpResponseHeader.Warning].Dump();
wex.Dump();
}
}
// Define other methods and classes here
public static string GetSamlClaim(string endpointAddress, string samlVersion, string tokenRequestUri)
{
WSTrustChannelFactory trustChannelFactory =
new WSTrustChannelFactory(new KerberosWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(endpointAddress)));
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
try
{
RequestSecurityToken rst =
new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue, WSTrust13Constants.KeyTypes.Bearer);
Uri appliesTo = new Uri(tokenRequestUri);
UriBuilder builder = new UriBuilder(appliesTo);
builder.Port = -1;
rst.AppliesTo = new EndpointAddress(builder.Uri);
switch (samlVersion)
{
case "SAML1.1":
rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml11TokenProfile11;
break;
case "SAML1.0":
rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml2TokenProfile11;
break;
default:
throw new ArgumentException("Passed unsupported value", "samlVersion");
}
WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
Console.WriteLine("Attempting to retrieve SAML assertion");
GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken;
Console.WriteLine("Successfully retrieved SAML assertion");
string tokenString = token.TokenXml.OuterXml;
return tokenString;
}
finally
{
trustChannelFactory.Close();
}
}
public string SendSAMLTokenToACS(string samlToken, string acsUrl, string appliesTo)
{
try
{
WebClient client = new WebClient();
client.BaseAddress = acsUrl;
NameValueCollection parameters = new NameValueCollection();
// ensure the applies_to URI is created in your ACS
// service namespace
parameters.Add("wrap_assertion_format", "SAML");
parameters.Add("wrap_assertion", samlToken);
parameters.Add("wrap_scope", appliesTo);
Console.WriteLine("Attempting to retrieve SWT token");
byte[] responseBytes = client.UploadValues("", parameters);
Console.WriteLine("Successfully retrieved a SWT token");
string response = Encoding.UTF8.GetString(responseBytes);
return response;
}
catch (WebException wex)
{
string acsError = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
("Error from ACS - " + acsError).Dump();
return string.Empty;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment