Pergunta

Estou tentando implementar uma solução SAML SSO em .Net, mas estou tendo problemas ao analisar a afirmação.

Eu tenho um exemplo de afirmação (parece byte[] dados como texto) e correspondente .p7b arquivo.

Quero carregar as chaves do .p7b e descriptografar a afirmação em um documento XML.

Até agora acho que estou lendo as chaves corretamente:

// 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;

Então tento analisar a afirmação e tenho um problema:

// 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;

Essa última instrução lança uma exceção, informando que não é possível analisar o conteúdo XML.

Acho que isso significa que estou perdendo uma etapa ao descriptografar a afirmação - obter o byte[] como texto convertido em um documento XML no formato SAML.

Alguém sabe como adicionar esta etapa?Estou sentindo falta de mais alguma coisa?

Foi útil?

Solução

Eu descobri isso - estava faltando parte da especificação SAML.

A afirmação é enviada (de forma bastante estranha, já que não é criptografada) como dados base64 e estava sendo codificada em URL duas vezes ao ser enviada.

Portanto, adicionar esta etapa nos dá uma afirmação válida:

// 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);

O a autenticação ainda não está funcionando, mas agora tenho XML válido, então é um problema diferente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top