Created
April 4, 2011 19:08
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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