I struggled hard to figure this out so I am putting it out there in hopes of saving someone else time. Writing a WCF C# Proxy service to the ACS API, I tried several of the .NET libraries suggested and finally arrived at a solution using System.IdentityModel.Tokens.Jwt from Microsoft. The real hangup was with the metascopes claim. It needs to be true as an object and not "true" as a string. The documentation on MSDN says that all claim values are strings but you can suggest a serialization by using an XMLSchema type. There are no examples so I tried xs:boolean to no avail and it fails silently, continuing to pass a string. The correct format for the argument is shown below.
Certificate storage is on your own, for now I am loading from a local .pfx file.
using System.Security.Cryptography.X509Certificates;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
private string GenerateToken() {
var tokenHandler = new JwtSecurityTokenHandler();
string path = AppDomain.CurrentDomain.BaseDirectory;
string certpath = path + "\\etc\\adobecert.pfx";
X509Certificate2 certificate = new X509Certificate2(certpath);
X509SecurityKey securityKey = new X509SecurityKey(certificate);
string audience = "https://ims-na1.adobelogin.com/c/" + APIKey;
List<Claim> claimslist = new List<Claim>();
claimslist.Add(new Claim("sub",TechnicalAccountID));
// WRONG! claimslist.Add(new Claim("https://ims-na1.adobelogin.com/s/ent_campaign_sdk", "true", "xs:boolean"));
//RIGHT!
claimslist.Add(new Claim("https://ims-na1.adobelogin.com/s/ent_campaign_sdk","true","http://www.w3.org/2001/XMLSchema#boolean"));
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor {
Subject = new ClaimsIdentity(claimslist),
Issuer = OrganizationID,
IssuedAt = DateTime.Now,
Audience = audience,
Expires = DateTime.Now.AddSeconds(86400),
SigningCredentials = new SigningCredentials(
securityKey,
SecurityAlgorithms.RsaSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
Message was edited by: Thom Williams edited to remove a couple extraneous lines of code from a previous attempt.