Pergunta

No trabalho, temos um aplicativo da Web que precisamos interface com o aplicativo da Web de outra empresa usando o sinal único validado pela SAML. Nossos aplicativos da Web estão escritos no PHP e é obviamente irrelevante qual escolha de idiomas que a outra empresa está usando. No entanto, eu precisava escrever uma API simples para a qual essa outra empresa possa enviar solicitações de sabão com solicitações SAML e gerar uma resposta SAML. Eu tenho escrito do zero por três razões: 1) Realmente não parece haver muitas opções para interações SAML escritas no PHP, mesmo que eu quisesse uma, 2) Ele limita a sobrecarga que estaria envolvida na adição de outro componente de terceiros e 3) Criar coisas do zero geralmente me deixa com um entendimento significativamente melhor e me torna muito mais capaz de adaptar a coisa no futuro, se necessário.

De qualquer forma, eu sou bastante novo em padrões Saml, Soap e XML em geral, então eu meio que me ensinei à medida que vou. Eu tenho a API praticamente completa para nossos propósitos, com a exceção de que a outra empresa especificou que nossa resposta deverá ser assinada digitalmente com um certificado (e a solicitação que recebemos será assinada digitalmente). Então, eu tenho tentado descobrir como processar/gerar as assinaturas XML, mas honestamente é tudo um pouco confuso, pois as especificações do W3C não são exatamente a leitura leve.

Seção 5.4.8 do Asserções e protocolo para a linguagem de marcação de segurança do Oasis (SAML) v1.1 Documento (o documento que eu tenho saído, pois a outra empresa disse que usará v1.1) inclui um exemplo de uma resposta assinada contendo uma afirmação assinada, que vou incluir aqui para referência:

<Response IssueInstant="2003-04-17T00:46:02Z" MajorVersion="1" MinorVersion="1"
 Recipient="www.opensaml.org" ResponseID="_c7055387-af61-4fce-8b98-e2927324b306"
 xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
 xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
   <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
   <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
   <ds:Reference URI="#_c7055387-af61-4fce-8b98-e2927324b306">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
      <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
       xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
     </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <ds:DigestValue>TCDVSuG6grhyHbzhQFWFzGrxIPE=</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>x/GyPbzmFEe85pGD3c1aXG4Vspb9V9jGCjwcRCKrtwPS6vdVNCcY5rHaFPYWkf+5EIYcPzx+pX1h43SmwviCqXRjRtMANWbHLhWAptaK1ywS7gFgsD01qjyen3CP+m3Dw6vKhaq1ed10BYyrIzb4KkHO4ahNyBVXbJwqv5pUaE4=</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
   </ds:X509Data>
  </ds:KeyInfo>
 </ds:Signature>
 <Status><StatusCode Value="samlp:Success"/></Status>
 <Assertion AssertionID="_a75adf55-01d7-40cc-929f-dbd8372ebdfc"
  IssueInstant="2003-04-17T00:46:02Z" Issuer="www.opensaml.org"
  MajorVersion="1" MinorVersion="1" xmlns="urn:oasis:names:tc:SAML:1.0:assertion"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Conditions NotBefore="2003-04-17T00:46:02Z" NotOnOrAfter="2003-04-17T00:51:02Z">
   <AudienceRestrictionCondition>
    <Audience>http://www.opensaml.org</Audience>
   </AudienceRestrictionCondition>
  </Conditions>
  <AuthenticationStatement AuthenticationInstant="2003-04-17T00:46:00Z"
   AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
   <Subject>
    <NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">scott@example.org</NameIdentifier>
    <SubjectConfirmation>
     <ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod>
    </SubjectConfirmation>
   </Subject>
   <SubjectLocality IPAddress="127.0.0.1"/>
  </AuthenticationStatement>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
   <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    <ds:Reference URI="#_a75adf55-01d7-40cc-929f-dbd8372ebdfc">
     <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
       <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
        xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      </ds:Transform>
     </ds:Transforms>
     <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
     <ds:DigestValue>Kclet6XcaOgOWXM4gty6/UNdviI=</ds:DigestValue>
    </ds:Reference>
   </ds:SignedInfo>
   <ds:SignatureValue>hq4zk+ZknjggCQgZm7ea8fI79gJEsRy3E8LHDpYXWQIgZpkJN9CMLG8ENR4Nrw+n7iyzixBvKXX8P53BTCT4VghPBWhFTSt9tHWu/AtJfOTh6qaAsNdeCyG86jmtp3TDMWuL/cBUj2OtBZOQMFn7jQ9YB7k1Iz3RqVL+wNmeWI4=</ds:SignatureValue>
   <ds:KeyInfo>
    <ds:X509Data>
     <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
    </ds:X509Data>
   </ds:KeyInfo>
  </ds:Signature>
 </Assertion>
</Response>

Então, como eu gero algo assim? E se eu receber algo assim, como a validar? Além disso, alguém pode oferecer apenas uma visão conceitual básica do que o <ds:Signature> Tags estão aqui? Parece que existem dois <ds:Signature> tags, uma no principal <Response> e um no <Assertion>, cada um contendo o seu próprio <ds:DigestValue>, <ds:SignatureValue>, e <ds:X509Certificate> (e cada distinto). Como isso é gerado? Qualquer luz que você possa lançar sobre isso será muito apreciada. Tutoriais ou exemplos de código seriam ainda mais apreciados! Mas, neste momento, se você pode me colocar no caminho certo, é tudo o que estou realmente pedindo. No momento, tudo ainda parece uma grande caixa preta para mim.

A propósito, se isso ajudar, diz em outras partes da especificação SAML 1.1 que as implementações da SAML devem usar apenas o método "canonicalização exclusiva" (excl-C14N) e usar apenas a "transformação envolvida". Ainda não tenho certeza do que isso significa.

Foi útil?

Solução

Processar assinaturas XML não é realmente muito difícil, se você estiver muito familiarizado com o XML, mas há muitos detalhes que precisam estar absolutamente certos ou as coisas não funcionam, então eu provavelmente não tentaria escrever minha própria implementação nisso Situação (eu a implementei parcialmente uma vez, mas isso foi para um propósito diferente e especial e, de qualquer forma, não foi uma implementação completa).

De qualquer forma, não sei muito sobre Saml, mas sei sobre assinaturas XML e XML, então talvez eu possa buscá -lo um pouco tentando responder às suas perguntas.

UMA Signature elemento refere -se a uma parte específica de um documento XML que foi assinado digitalmente, em seu SignedInfo elemento filho. o Reference elemento infantil disso (acho que pode haver muitos Reference Elementos que são concatenados ao formar os bytes a serem assinados, mas não me lembro mais com certeza) aponta para o conteúdo através do URI atributo. o Transform Os elementos descrevem transformações realizadas no conteúdo referido antes da hash; Você precisará examinar as especificações para descobrir como os algoritmos de transformação são definidos. o DigestMethod O elemento fornece o algoritmo de hash para se aplicar aos bytes que são o resultado desses algoritmos de transformação (observe que um deles é sempre canonicalização que converte XML em bytes) e o DigestValue fornece o resultado desse algoritmo de digestão.

A assinatura real está no SignatureValue elemento, e é produzido aplicando o CanonicalizationMethod a canonalização do elemento para produzir os bytes e depois assinar esses bytes com o SignatureMethod. o KeyInfo O elemento informa como encontrar a chave a ser usada.

A canonicalização, que aparece algumas vezes acima, é simplesmente uma maneira de converter um documento XML em bytes, para que os documentos XML "equivalentes" produzam a mesma sequência de bytes. Isso é necessário em uma assinatura digital, porque os algoritmos funcionam em bytes e XML pode passar por vários intermediários que provavelmente interromperão os bytes originais, mas manterão a equivalência. E diferentes métodos de canonicalização são necessários para diferentes situações: se os elementos forem extraídos de documentos e colocados em outros, você precisará de canonicalização exclusiva que retire as definições de nomes desnecessárias, mas em outros casos que podem não funcionar corretamente, para que você precise de canonalidade inclusiva, que, em vez disso, que, em vez disso preserva todos os namespaces no escopo.

Este é apenas o básico. Existem várias opções diferentes em como produzir uma assinatura XML e, se você deseja implementar um verificador de trabalho, precisa considerar todos eles. Como você é novo no XML em geral, repetirei meu conselho de usar algo que já existe. É uma experiência de aprendizado interessante para implementar uma especificação, mas muitas vezes é uma perda de tempo se as implementações já estiverem disponíveis.

Aí está o W3C documentação sobre assinaturas.

Outras dicas

Há um exemplo em xmlseclibs.php em SimpleSaml. Ele depende do módulo OpenSSL para fazer a criptografia.

Sinceramente, eu usaria essa lib ou ponte para Java/Tomcat, apenas porque os problemas de interopamento podem surgir que precisariam ser potencialmente depurados,

  1. Você pode dar uma olhada neste Java Lib para assinar o exemplo de solicitação SAML https://github.com/jrowny/java-saml

  2. Para validar a assinatura, você precisa instalar o Saml Tracer Addon https://addons.mozilla.org/en-us/firefox/addon/saml-tracer/

  3. Você pode usar a ferramenta https://www.samltool.com/validate_logout_req.php Para vaalidar ou assinar o pedido https://www.samltool.com/sign_logout_req.php

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