Как разобрать запрос подтверждения SAML в .Net - PullRequest
5 голосов
/ 23 мая 2011

Я пытаюсь реализовать решение SAML SSO в .Net, но у меня проблема с анализом утверждения.

У меня есть пример утверждения (выглядит как byte[] данные в виде текста) исоответствующий .p7b файл.

Я хочу загрузить ключи из .p7b и расшифровать утверждение в XML-документ.

Пока я думаю, что правильно читаю ключи:

// get the key data
byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b");

// decode the keys
var cms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber);
cms.Decode(certificateData);

var samlCertificates = cms.Certificates;

Затем я пытаюсь разобрать утверждение, у меня возникает проблема:

// we have a keychain of X509Certificate2s, we need a collection of tokens
var certificatesAsTokens =
    from X509Certificate2 cert in samlCertificates
    select new X509SecurityToken(cert) as SecurityToken;

// get a token resolver
var tokens = new ReadOnlyCollection<SecurityToken>(
    certificatesAsTokens.ToList());
var resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
    tokens, true);

// get the SAML data in an XML reader
var reader = XmlReader.Create(assertionPostStream);

// use the WS Security stuff to parse the reader
var securityToken = WSSecurityTokenSerializer.
    DefaultInstance.ReadToken(reader, resolver) as SamlSecurityToken;

Последнее предложение выдает исключение, заявляя, что не может проанализировать содержимое XML.

Я думаю, это означает, что я пропускаю шаг, расшифровывающий утверждение - получение byte[] в виде текста, преобразованного в XML-документ формата SAML.

Кто-нибудь знает, как добавить этот шаг?Я что-то упускаю?

1 Ответ

13 голосов
/ 24 мая 2011

Я понял это - мне не хватало части спецификации SAML.

Утверждение отправляется (довольно странно, поскольку оно не зашифровано) как данные base64, и оно кодировалось по URLдважды, как было отправлено.

Таким образом, добавление этого шага дает нам правильное утверждение:

// spec says "SAMLResponse=" 
string rawSamlData = Request["SAMLResponse"];

// the sample data sent us may be already encoded, 
// which results in double encoding
if (rawSamlData.Contains('%'))
{
    rawSamlData = HttpUtility.UrlDecode(rawSamlData);
}

// read the base64 encoded bytes
byte[] samlData = Convert.FromBase64String(rawSamlData);

// read back into a UTF string
string samlAssertion = Encoding.UTF8.GetString(samlData);

Аутентификация все еще не работает , но теперь у меня есть действительныйXML, так что это другая проблема.

...