Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
543 views
in Technique[技术] by (71.8m points)

single sign on - Problems reading authenticating a SAML assertion in .Net using WSSecurityTokenSerializer

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

  1. Validate the signature on the entire response message.
  2. Extract the assertion part of the message.
  3. Read the token with Saml2SecurityTokenHandler.ReadToken().
  4. Validate the token with Saml2SecurityTokenHandler.DetectReplayedToken().
  5. Validate the token with Saml2SecurityTokenHandler.ValidateConditions()
  6. Use 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...