2016-09-15 4 views
0

Я пытаюсь заменить обычную библиотеку SAML 2, для которой у меня нет исходного кода, с WIF, для которого у меня нет опыта. Мне не повезло найти пример кода, поэтому я работаю над пробным и ошибочным стилем. Код, похоже, почти работает, но я получаю очень краткое сообщение The signature verification failed. и ничего больше.Ошибка подтверждения утверждения SAML 2 с использованием Windows Identity Foundation

Для ввода этого процесса у меня есть сертификат X509 и утверждение SAML 2 с базовым кодом 64.

Мой код:

// Load X509 certificate 
string rootPath = System.AppDomain.CurrentDomain.BaseDirectory; 
string certFilePath = ConfigurationManager.AppSettings["SAMLCertLocation"]; 
certFilePath = Path.Combine(rootPath, certFilePath); 
msg = string.Format("SAMLCertLocation: [{0}]", certFilePath); 
Trace.TraceInformation(msg); 
X509Certificate2 cert = new X509Certificate2(certFilePath, String.Empty); 

// build token handler configuration 
List<System.IdentityModel.Tokens.SecurityToken> serviceTokens = new List<System.IdentityModel.Tokens.SecurityToken>(); 
serviceTokens.Add(new System.IdentityModel.Tokens.X509SecurityToken(cert)); 

ConfigurationBasedIssuerNameRegistry issuers = new ConfigurationBasedIssuerNameRegistry(); 
issuers.AddTrustedIssuer(cert.Thumbprint, cert.Issuer); 

SecurityTokenHandlerConfiguration config = new SecurityTokenHandlerConfiguration() 
{ 
    AudienceRestriction = { AudienceMode = AudienceUriMode.Never }, 
    CertificateValidator = X509CertificateValidator.None,    
    // RevocationMode = X509RevocationMode.NoCheck,    // no such property 
    IssuerNameRegistry = issuers, 
    MaxClockSkew = TimeSpan.FromMinutes(5), 
    ServiceTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(serviceTokens.AsReadOnly(), false) 
}; 

// extract the assertion from the request 
byte[] data = Convert.FromBase64String(reqstr); 
string assertion = Encoding.UTF8.GetString(data); 
Trace.TraceInformation(assertion); 

// read and validate the assertion 
Saml2SecurityTokenHandler handler = new Saml2SecurityTokenHandler(); 
handler.Configuration = config; 
bool canReadToken = handler.CanReadToken(XmlReader.Create(new StringReader(assertion))); 
msg = string.Format("CanReadToken [{0}]", canReadToken); 
Trace.TraceInformation(msg); 
if (canReadToken) 
{ 
    try 
    { 
     System.IdentityModel.Tokens.SecurityToken token = handler.ReadToken(XmlReader.Create(new StringReader(assertion))); 
     ClaimsIdentityCollection claims = handler.ValidateToken(token); 
     msg = string.Format("SAML Claims [{0}]", claims.ToString()); 
     Trace.TraceInformation(msg); 
    } 
    catch (Exception e) 
    { 
     msg = string.Format("Validation Exception [{0}]", e.Message); 
     Trace.TraceInformation(msg); 
    } 
} 

Ошибка, из которой я выхожу;

2016-09-15T19:34:39 PID[6504] Information CanReadToken [True] 
2016-09-15T19:34:39 PID[6504] Information Validation Exception [ID6013: The signature verification failed.] 
2016-09-19T13:13:13 PID[11912] Information Validation Exception [System.Security.Cryptography.CryptographicException: ID6013: The signature verification failed. 
    at Microsoft.IdentityModel.Protocols.XmlSignature.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter, String signatureMethod) 
    at Microsoft.IdentityModel.Protocols.XmlSignature.SignedXml.StartSignatureVerification(SecurityKey verificationKey) 
    at Microsoft.IdentityModel.Protocols.XmlSignature.EnvelopedSignatureReader.OnEndOfRootElement() 
    at Microsoft.IdentityModel.Protocols.XmlSignature.EnvelopedSignatureReader.Read() 
    at System.Xml.XmlReader.ReadEndElement() 
    at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadAssertion(XmlReader reader) 
    at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadToken(XmlReader reader) 
    at AXAWeb.Code.Saml20Login.Saml20Login.SamlLogon(String samlString, String absoluteUrl) in Saml20Login.cs:line 189] 

Подпись состоит из утверждения:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
    <SignedInfo> 
    <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> 
    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> 
    <Reference URI="#SAML-a964f232-77ab-40d1-a74a-f85dfe10f57d"> 
     <Transforms> 
     <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> 
     <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> 
     </Transforms> 
     <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> 
     <DigestValue>B9q+BrqH+Fq74R8eCqd+Vd+vKkw=</DigestValue> 
    </Reference> 
    </SignedInfo> 
    <SignatureValue>...snip for brevity...</SignatureValue> 
    <KeyInfo> 
    <X509Data> 
     <X509Certificate>...snip for brevity...</X509Certificate> 
    </X509Data> 
    <X509Data> 
     <X509IssuerSerial> 
     <X509IssuerName>CN=Entrust Certification Authority - L1K, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US</X509IssuerName> 
     <X509SerialNumber>1356031830</X509SerialNumber> 
     </X509IssuerSerial> 
    </X509Data> 
    </KeyInfo> 
</Signature> 

Я ожидаю, что я что-то в конфигурации отсутствует, поэтому я вставил изменения на основе информации, содержащейся в this question. Однако это не изменило моих результатов.

Кто-нибудь с опытом знает, что мне нужно добавить, чтобы сделать эту работу?

+0

Не печатать исключая.Message только. Пожалуйста, распечатайте все exception.ToString(), чтобы получить более подробную информацию. Исходя из этого, кто-то может оказать вам дополнительную помощь :) – Thuan

+0

@Thuan - спасибо за предложение. Добавлена ​​новая информация выше. – CAB

+0

Вам действительно нужно заменить этот модуль или вы хотите аутентифицировать приложение IIS или что-то подобное? – TGlatzer

ответ

3

Очень раздражающая проблема проверки подписи WIF заключается в том, что она использует внутреннюю реализацию SignedXml, которая не поддерживает трассировку. Для записи общедоступный System.Security.Cryptography.Xml.SignedXml поддерживает отслеживание, и, таким образом, легче узнать, что пошло не так. В любом случае, по моему опыту, я предлагаю вам проверить, содержат ли ваше утверждение xml пробелы. Если да, вам нужно использовать параметр PreserveWhiteSpaces при чтении его в XmlReader.

Отредактировано: Две другие вещи, чтобы проверить, если вы телеграфировать правильный сертификат для проверки подписи, и если вы можете проверить подпись для утверждения с помощью System.Security.Cryptography.Xml.SignedXml: https://msdn.microsoft.com/en-us/library/ms229950(v=vs.110).aspx

+0

Ничего себе. Так просто. Я следовал примеру SignedXml. 5 строк кода и сделано. Спасибо! – CAB

+0

+1 для указания, что ** пробел является существенным ** для проверки подписи. 'XmlReader' по умолчанию отключает пробелы, поэтому убедитесь, что вы устанавливаете' IgnoreWhitespace = true' в 'XmlReaderSettings'. – Nick

0

Посмотрите на active-directory-dotnet-webapp-wsfederation.

По существу вырвать материал SAMl и использовать пакет OWIN Nuget Ws-Fed.

Конечно, это предполагает, что ваш IDP поддерживает WS-FEd?

+0

Это «нет» на WS-Fed. Кроме того, я стараюсь не нарушать интерфейс, который передает мне утверждение для проверки. – CAB

Смежные вопросы