Reputation: 155692
I have a SAML assertion that I wish to authenticate in .Net using WSSecurityTokenSerializer
.
I've got the key-chain and SAML XML, despite a few issues.
First I get the SAML assertion from the HTTPS POST:
// spec says "SAMLResponse="
string rawSamlData = Request["SAMLResponse"];
// read the base64 encoded bytes
byte[] samlData = Convert.FromBase64String(rawSamlData);
// read back into a UTF string
string samlAssertion = Encoding.UTF8.GetString(samlData);
// get the SAML data in an XML reader
var assertionPostStream = new StringReader(samlAssertion);
var reader = XmlReader.Create(assertionPostStream);
Then I get the keys provided by my IdP:
// get the key data
byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b");
// decode the keys
var cms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber);
cms.Decode(certificateData);
// we have a keychain of X509Certificate2s, we need a collection of tokens
var certificatesAsTokens =
from X509Certificate2 cert in cms.Certificates
select new X509SecurityToken(cert) as SecurityToken;
// get a token resolver
var tokens = new ReadOnlyCollection<SecurityToken>(
certificatesAsTokens.ToList());
var resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
tokens, true);
Finally I get an error thrown here:
// use the WS Security stuff to parse the reader
var securityToken = WSSecurityTokenSerializer.
DefaultInstance.ReadToken(reader, resolver) as SamlSecurityToken;
When calling that ReadToken
I get the following error:
Cannot read the token from the 'Response' element with the 'urn:oasis:names:tc:SAML:2.0:protocol' namespace for BinarySecretSecurityToken, with a '' ValueType. If this element is expected to be valid, ensure that security is configured to consume tokens with the name, namespace and value type specified.
My SAML XML starts with:
<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ...
So clearly I have a Response
element in the urn:oasis:names:tc:SAML:2.0:protocol
namespace.
Any idea what's wrong/missing here?
Upvotes: 3
Views: 8205
Reputation: 69260
It looks like you are receiving a SAML2 response. Although there is support for SAML2 in .NET 4.5, there is unfortunately only support for the assertions - not the protocol itself (including the Response message).
To process the SAML2 response in .NET you have to:
Saml2SecurityTokenHandler.ReadToken()
.Saml2SecurityTokenHandler.DetectReplayedToken()
.Saml2SecurityTokenHandler.ValidateConditions()
Saml2SecurityTokenHandler.CreateClaims()
to create a claims identity.Unfortunately most of those methods are protected, but you can subclass Saml2SecurityTokenHandler
and get access to them.
A complete working example can be found in the Saml2Response class in the Sustainsys.Saml2 project.
Upvotes: 5