Skip to content

Instantly share code, notes, and snippets.

@IntuitDeveloperRelations
Created August 11, 2014 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IntuitDeveloperRelations/3d90d1a9ae7e4f67559c to your computer and use it in GitHub Desktop.
Save IntuitDeveloperRelations/3d90d1a9ae7e4f67559c to your computer and use it in GitHub Desktop.
IPP CAD API / Component Space: Send SAML assertion to obtain OAuth tokens
// Copyright Intuit, Inc 2012
// SAML Sample Application
// This sample is for reference purposes only.
// Copyright (c) 2014 Intuit Inc. All rights reserved.
// Redistribution and use in source and binary forms, with or without modification, are permitted in conjunction
// with Intuit Partner Platform.
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, WHETHER OR NOT SUCH DAMAGES WERE FORESEEABLE AND EVEN IF THE AUTHOR IS ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGES.
//Uses http://www.componentspace.com/SAMLv20.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Xml;
using System.Security.Cryptography.X509Certificates;
using System.Net;
using System.IO;
using ComponentSpace.SAML2;
using ComponentSpace.SAML2.Assertions;
using ComponentSpace.SAML2.Protocols;
using ComponentSpace.SAML2.Bindings;
using ComponentSpace.SAML2.Profiles.SSOBrowser;
namespace GetAccessTokenBySAML_ComponentSpace
{
class Program
{
static void Main(string[] args)
{
try
{
confirmAppSettings();
Console.WriteLine("Getting OAuth Tokens by SAML using ComponentSpace");
string randomUserName = "customer1"; // GenerateRandomUsername();
string samlIdentityProviderID = System.Configuration.ConfigurationManager.AppSettings.Get("SAMLIdentityProviderID");
Console.WriteLine("Creating SAML Assertion for random user: " + randomUserName);
SAMLAssertion aggCatSAMLAssertion = CreateSAMLAssertion(samlIdentityProviderID, randomUserName);
string certificatePath = System.Configuration.ConfigurationManager.AppSettings.Get("PrivateKeyPath");
string certificatePassword = System.Configuration.ConfigurationManager.AppSettings.Get("PrivateKeyPassword");
Console.WriteLine("Signing SAML Assertion");
XmlElement signedSAMLAssertion = SignSAMLAssertion(aggCatSAMLAssertion, certificatePath, certificatePassword);
string consumerKey = System.Configuration.ConfigurationManager.AppSettings.Get("ConsumerKey");
string samlEndpoint = System.Configuration.ConfigurationManager.AppSettings.Get("SAMLEndpoint");
Console.WriteLine("Posting SAML Assertion");
string[] tokens = PostSAMLAssertion(signedSAMLAssertion, samlEndpoint, consumerKey);
Console.WriteLine("Successfully obtained OAuth Tokens");
Console.WriteLine(tokens[0] + ": " + tokens[1]);
Console.WriteLine(tokens[2] + ": " + tokens[3]);
}
catch (Exception ex)
{
Console.WriteLine("Exception thrown while obtaining OAuth tokens");
Console.WriteLine("Exception: " + ex.Message);
}
Console.WriteLine("Press any key to terminate application");
Console.Read();
}
static SAMLAssertion CreateSAMLAssertion(string samlIdentityProviderID, string userName)
{
SAMLAssertion samlAssertion = new SAMLAssertion();
samlAssertion.Issuer = new Issuer(samlIdentityProviderID);
Subject subject = new Subject(new NameID(userName, null, null, SAMLIdentifiers.NameIdentifierFormats.Unspecified, null));
SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer);
subject.SubjectConfirmations.Add(subjectConfirmation);
samlAssertion.Subject = subject;
Conditions conditions = new Conditions(new TimeSpan(1, 0, 0));
AudienceRestriction audienceRestriction = new AudienceRestriction();
audienceRestriction.Audiences.Add(new Audience(samlIdentityProviderID));
conditions.ConditionsList.Add(audienceRestriction);
samlAssertion.Conditions = conditions;
AuthnStatement authnStatement = new AuthnStatement();
authnStatement.AuthnContext = new AuthnContext();
authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Unspecified);
samlAssertion.Statements.Add(authnStatement);
return samlAssertion;
}
static XmlElement SignSAMLAssertion(SAMLAssertion samlAssertion, string certificateFilePath, string certificatePassword)
{
X509Certificate2 x509CertificateTest = new X509Certificate2(certificateFilePath, certificatePassword, X509KeyStorageFlags.MachineKeySet); ;
XmlElement samlAssertionXml = samlAssertion.ToXml();
SAMLAssertionSignature.Generate(samlAssertionXml, x509CertificateTest.PrivateKey, x509CertificateTest);
return samlAssertionXml;
}
static string[] PostSAMLAssertion(XmlElement signedSAMLAssertion, string samlEndpoint, string consumerKey)
{
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(samlEndpoint);
WebReq.Method = "POST";
WebReq.Host = "oauth.intuit.com";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.Headers.Set("Authorization", String.Concat("OAuth ", "oauth_consumer_key=\"", consumerKey, "\""));
byte[] postBody = Encoding.UTF8.GetBytes("saml_assertion=" + Base64EncodeWithURLandFilenameSafeAlphabet(signedSAMLAssertion));
Stream PostData = WebReq.GetRequestStream();
PostData.Write(postBody, 0, postBody.Length);
PostData.Close();
HttpWebResponse response = (HttpWebResponse)WebReq.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseStreamReader = new StreamReader(responseStream);
String readResponse = responseStreamReader.ReadToEnd();
char[] delimiters = { '&', '=' };
return readResponse.Split(delimiters);
}
static string Base64EncodeWithURLandFilenameSafeAlphabet(XmlElement signedSAMLAssertion)
{
byte[] buffer = Encoding.ASCII.GetBytes(signedSAMLAssertion.OuterXml);
string base64EncodedAssertion = Convert.ToBase64String(buffer);
base64EncodedAssertion = base64EncodedAssertion.Replace("+", "-");
base64EncodedAssertion = base64EncodedAssertion.Replace("/", "_");
return base64EncodedAssertion;
}
static void confirmAppSettings()
{
try
{
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("ConsumerKey"))) { throw new Exception(); };
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("ConsumerSecret"))) { throw new Exception(); };
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("SAMLIdentityProviderID"))) { throw new Exception(); };
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("PrivateKeyPath"))) { throw new Exception(); };
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("PrivateKeyPassword"))) { throw new Exception(); };
if (string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Get("SAMLEndpoint"))) { throw new Exception(); };
}
catch
{
throw new Exception("Please enter all values in app.config file");
}
}
public static string GenerateRandomUsername()
{
string rv = "";
char[] lowers = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
char[] uppers = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
char[] numbers = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int l = lowers.Length;
int u = uppers.Length;
int n = numbers.Length;
Random random = new Random();
rv += lowers[random.Next(0, l)].ToString();
rv += lowers[random.Next(0, l)].ToString();
rv += lowers[random.Next(0, l)].ToString();
rv += uppers[random.Next(0, u)].ToString();
rv += uppers[random.Next(0, u)].ToString();
rv += uppers[random.Next(0, u)].ToString();
rv += numbers[random.Next(0, n)].ToString();
rv += numbers[random.Next(0, n)].ToString();
rv += numbers[random.Next(0, n)].ToString();
return rv;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment