2009-12-20 18 views
15

W pracy mamy aplikację internetową, która będzie musiała być połączona z aplikacją internetową innej firmy za pomocą funkcji logowania jednokrotnego zatwierdzonej przez SAML. Nasze aplikacje internetowe są napisane w PHP i oczywiście nie ma znaczenia, jakiego wyboru języka używa druga firma. Niemniej jednak, musiałem napisać prosty interfejs API, aby ta druga firma mogła wysyłać żądania SOAP do żądań SAML i wygenerować odpowiedź SAML. Pisałem to od zera z trzech powodów: 1) tak naprawdę nie wydaje się, że istnieje wiele opcji interakcji SAML napisanych w PHP, nawet gdybym chciał, 2) to ogranicza obciążenie, które mogłoby być zaangażowane z dodawaniem kolejnego komponentu strony trzeciej i 3) tworzenie rzeczy od zera zwykle daje mi znacznie lepsze zrozumienie i czyni mnie znacznie bardziej zdolnym do adaptowania tego w przyszłości, jeśli jest to konieczne.Co muszę wiedzieć o podpisach XML, aby uzyskać działanie SAML?

W każdym razie, jestem całkiem nowy w standardach SAML, SOAP i XML w ogóle, więc w pewnym sensie uczyłem się samego siebie. Interfejs API jest prawie kompletny dla naszych celów, z jednym wyjątkiem, że druga firma określiła, że ​​nasza odpowiedź będzie wymagać podpisu cyfrowego za pomocą certyfikatu (a otrzymane żądanie będzie również podpisane cyfrowo). Tak więc próbowałem dowiedzieć się, jak przetwarzać/generować podpisy XML, ale szczerze mówiąc, to wszystko jest trochę mylące, ponieważ specyfikacje W3C nie są dokładnie lekkim czytaniem.

W sekcji 5.4.8 dokumentu Assertions and Protocol for the OASIS Security Markup Language (SAML) V1.1 (dokument, który opisuję, jako że inne przedsiębiorstwo mówiło, że będzie używał wersji 1.1), znajduje się przykład podpisanej odpowiedzi zawierającej podpisany asercję, którą "tu zawrzeć:

<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">[email protected]</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> 

Jak mogę wygenerować coś takiego? A jeśli otrzymam coś takiego, jak mogę to sprawdzić? Czy każdy może zaoferować tylko podstawowy przegląd pojęć związanych z tagami <ds:Signature>? Wygląda na to, że istnieją dwa znaczniki <ds:Signature>, jeden w głównym <Response> i jeden w <Assertion>, z których każdy zawiera własny <ds:DigestValue>, <ds:SignatureValue> i <ds:X509Certificate> (i każdy inny). Jak są generowane? Każde światło, które można rzucić na ten temat, zostanie docenione. Ćwiczenia lub przykłady kodu byłyby jeszcze bardziej doceniane! Ale w tym momencie, jeśli możesz po prostu doprowadzić mnie na właściwą drogę, to wszystko, o co naprawdę proszę. Teraz wszystko wydaje mi się wielką czarną skrzynką.

Nawiasem mówiąc, jeśli to pomaga, w innym miejscu specyfikacji SAML 1.1 stwierdza się, że implementacje SAML powinny wykorzystywać tylko metodę "Ekskluzywnej kanonizacji" (Excl-C14N) i powinny używać tylko "transformacji kopertowej". Wciąż nie jestem do końca pewien, co to oznacza.

Odpowiedz

27

podpisy XML Processing nie jest to zbyt trudne, jeśli jesteś bardzo obeznany z XML, ale jest wiele szczegółów, które muszą być absolutnie poprawne lub rzeczy nie działają, więc prawdopodobnie nie spróbowałbym napisać mojej własnej implementacji w tej sytuacji (wprowadziłem ją częściowo raz, ale to było dla inny i specjalny cel, a zresztą nie było to kompletne wdrożenie).

W każdym razie nie wiem zbyt wiele o SAML, ale wiem o sygnaturach XML i XML, więc być może uda mi się trochę rozwiązać, próbując odpowiedzieć na twoje pytania.

Element Signature odnosi się do konkretnego fragmentu dokumentu XML, który został podpisany cyfrowo, w elemencie podrzędnym SignedInfo. Ten element potomny tego (myślę, że może być wiele elementów Reference, które łączą się podczas tworzenia bajtów do podpisu, ale nie pamiętam już na pewno) wskazuje na treść za pomocą atrybutu URI. Elementy Transform opisują transformacje wykonywane na określonej zawartości przed jej skróceniem; będziesz musiał spojrzeć na specyfikacje, aby dowiedzieć się, jak zdefiniowane są algorytmy transformacji. Element DigestMethod podaje algorytm mieszający do zastosowania do bajtów, które są wynikiem tych algorytmów transformacji (zauważ, że jednym z nich jest zawsze kanonizacja, która konwertuje XML na bajty), a DigestValue podaje wynik tego algorytmu skrótu.

Rzeczywista podpis jest w elemencie SignatureValue i produkowany jest przez zastosowanie žkonwertowaniem kanonicznymâ w CanonicalizationMethod elementu produkować bajtów, a następnie podpisanie te bajty z SignatureMethod. Element KeyInfo informuje, jak znaleźć klucz do użycia.

Kanonizacja, która pojawia się kilka razy powyżej, jest po prostu sposobem na konwersję dokumentu XML na bajty, aby "równoważne" dokumenty XML tworzyły tę samą sekwencję bajtów. Jest to wymagane w podpisie cyfrowym, ponieważ algorytmy działają na bajtach, a kod XML może przejść przez szereg pośredników, które prawdopodobnie zakłócą oryginalne bajty, ale zachowają równoważność. A różne metody kanonizacji są potrzebne w różnych sytuacjach: jeśli elementy są wydobywane z dokumentów i umieszczane w innych, potrzebujesz wyłącznej kanonalizacji, która usuwa niepotrzebne definicje przestrzeni nazw, ale w innych przypadkach, które mogą nie działać poprawnie, więc potrzebujesz zamiast tego inkluzywnej kanonizacji, która zachowuje wszystkie przestrzenie nazw w zakresie.

To tylko podstawy. Istnieje wiele różnych opcji tworzenia podpisu XML, a jeśli chcesz wdrożyć działający weryfikator, musisz wziąć pod uwagę wszystkie. Ponieważ jesteś początkującym użytkownikiem XML, po prostu powtórzę moją radę użycia czegoś, co już istnieje. To ciekawe doświadczenie edukacyjne w implementacji specyfikacji, ale często jest to strata czasu, jeśli implementacje są już dostępne.

+0

Po określeniu ca Algorytm nonikalizacji w elemencie metody kanonizacji podpisanego elementu informacyjnego, dlaczego powinieneś go ponownie podać w elemencie transforms? – Ashwin

+1

@Ashwin: 'CanonicalizationMethod' w' SignedInfo' jest tym, co jest stosowane do elementu 'SignedInfo', jakakolwiek kanonizacja w transformacjach jest stosowana do odnośnej treści, więc mają one zastosowanie do różnych rzeczy, i dlatego potrzebujesz obu. Podpisana treść nie musi też być XML, więc kanonizacja niekoniecznie ma zastosowanie. – JaakkoK

+0

dzięki za to :) Jest jeszcze jeden obszar, w którym utknąłem. Wymagane jest użycie xslt w elemencie transforms. Nie ma przykładu, jak go używać w Javie. Jeśli to możliwe, możesz podać przykładowy kod lub wskazać łącze, które używa xslt w podpisach xml z java. – Ashwin

2

Istnieje przykład w xmlseclibs.php w SimpleSAML. Opiera się na module openssl, aby wykonać kryptografię.

Chciałbym szczerze używać tego lib lub most Java/Tomcat, tylko dlatego, że problemy międzyoperacyjne może wymyślić, że musiałby być potencjalnie błędów,