Wątek przeniesiony 2017-11-27 13:03 z Newbie przez somekind.

Uwierzytelnianie ePUAP na podstawie danych z Profilu Zaufanego

1

koperta wygląda następująco:

<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="[...]" Destination="https://pz.gov.pl/dt/SingleSignOnService" ID="ID_T1nyNodwuR47Nox43sGB617qjxVLw0Jl3RAm" IssueInstant="2020-03-06T09:43:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">[...]</saml2:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="">
                <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#">
                        <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml2 saml2p xenc wsu" />
                    </ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>[...]</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>[...]</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>[...]</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
</saml2p:AuthnRequest>

pamiętaj, że pomimo tego co mówi dokumentacja CanonicalizationMethod ma być http://www.w3.org/2001/10/xml-exc-c14n a od lutego SHA1 zmieniło się na SHA256

0

Panowie,
muszę ogarnąć temat integracji logowania przez PZ z naszym nowym systemem.
Powiedzcie mi proszę, co daje się do parametrów:
ds:DigestValue[...]</ds:DigestValue>
ds:SignatureValue[...]</ds:SignatureValue>
ds:X509Certificate[...]</ds:X509Certificate>

Ostatnie to pewnie przekonwertowany certyfikat, który wystawiło COI.. a co z resztą?
Z góry dziękuję :)

0
Bart Urbanczyk napisał(a):

Udało mi się zrobić skuteczną implementacje
AuthnRequest -> Artifactresolve -> getTpUserInfo w PHP
jeśli ktoś ma problemy mogę pomóc

Jestem chętny :)
Obecnie walczę z dokumentacją ale to jest powalone ... Obecnie wzoruję się na manualu ze strony http://www.extern.pl/artykuly/sso_epuap/ ale tamto to już nie jest raczej aktualne ...

0

Hej ale rozmawiamy o authnrequest czy artifactresolve?
w skrócie:
digest value to skrót SHA256 węzła koperty w base64 - w zależności czy mówimy o authnrequest czy artifactresolve czy gettpuserinfo inna część koperty jest podpisywana. Aby podpisać wiadomość najpierw trzeba stworzyć jej digest czyli hash
signature to podpisany digest
x509 to klucz publiczny, ktory dostalismy z COI, uwaga nalezy go przekonwertowac z p12 do x509v3

0

Jestem za samym początku więc dopiero authnRequest staram się zrobić. Kod mam taki (zapożyczony bo aż tak biegły w saml nie jestem żeby go wykombinować). Na razie próbuję się dostać do środowiska INT. URL-e zmieniłem na int.pz.gov.pl no i właśnie się zaciąłem na tych elementach o których pisałem ... Jako Issuser dałem identyfikator systemu w DRACO.

Idę w dobrą stronę czy błądzę? :)

<?php

   error_reporting(E_ALL);
   require 'common.php';

   if(!isset($_COOKIE['TGSID']) || true)
   {

   		$SAMLRequest = "<saml2p:AuthnRequest xmlns:saml2p=\"urn:oasis:names:tc:SAML:2.0:protocol\" AssertionConsumerServiceURL=\"https://prep.system[...].pl/consume.php\" Destination=\"https://int.pz.gov.pl/dt/SingleSignOnService\" ID=\"".getUniqueID(20)."\" IssueInstant=\"".getTimestamp()."\" ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact\" Version=\"2.0\">"
   		."<saml2:Issuer xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">lq896ify2p</saml2:Issuer>"
		."<ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\">"
		."<ds:SignedInfo>"
            ."<ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />"
            ."<ds:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\" />"
            ."<ds:Reference URI=\"\">"
                ."<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#\">"
                        ."<ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"ds saml2 saml2p xenc wsu\" />"
                    ."</ds:Transform>"
                ."</ds:Transforms>"
                ."<ds:DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\" />"
                ."<ds:DigestValue>[...]</ds:DigestValue>"
            ."</ds:Reference>"
        ."</ds:SignedInfo>"
        ."<ds:SignatureValue>[...]</ds:SignatureValue>"
        ."<ds:KeyInfo>"
            ."<ds:X509Data>"
                ."<ds:X509Certificate>MIIDsTCCApmgAwIBAgIIIe05o81LIzMwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UE[...]</ds:X509Certificate>"
            ."</ds:X509Data>"
        ."</ds:KeyInfo>"
    ."</ds:Signature>"
."</saml2p:AuthnRequest>";


		$url ="https://int.pz.gov.pl/dt/SingleSignOnService?SAMLRequest=".addslashes(rawurlencode(base64_encode(gzdeflate($SAMLRequest))));
		header("Location: $url");
	}
	else
	{
		echo "Sesja autoryzacyjna już istnieje i nie trzeba jej ustanawiać";
	}
?>
0

Koperta wygląda ok, pamiętaj, że SAMLRequest powinien być przekazywany POSTem

0

Coś mi się wydaje, że nie przeskoczę kwestii podpisywania o których pisałem... trzeba się chyba będzie rozejrzeć za kimś kto to mi zintegruje i wtedy pewnie zaczaję o co w tym chodzi... dzięki za poświęcony czas ;)

0

Hej, aktualnie również zmagamy się z integracją z Profilem Zaufanym i Dostawcą Tożsamości.
To co udało się uzyskać:

  • utworzyć konto testowe na: int.pz.gov.pl oraz int.epuap.gov.pl
  • utworzyć profil firmy
  • złożyć pozytywnie rozpatrzony wniosek o nadanie uprawnień podmiotu publicznego (wybrałem wszystkie uprawnienia)
  • wygenerować .csr i .key, złożyć wniosek o certyfikat do środowiska testowego gdzie podałem następujące parametry:
    ISSUER: https://naszadomena.pl
    SSO: https://naszadomena.pl/epuap
    SLO: https://naszadomena.pl/epuap
  • uzyskać testowy cert, a następnie stworzyłem .p12 z mojego .key i .crt w którym znajduje się odesłany przez ludzi od PZ cert główny i pośredni
  • z kodu w Internecie przygotować AuthnRequest, który korzysta z .jks (do niego został wrzucony .p12)
  • po wywołaniu https://naszadomena.pl/epuap/test tworzy się XML i następuje przekierowanie na https://int.pz.gov.pl/dt/SingleSignOnService , ale otrzymujemy komunikat:
    Błąd
    Dostęp zabroniony.

Tak wygląda przykładowy XML:

<?xml version="1.0" encoding="UTF-8"?><saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://naszadomena.pl/epuap" Destination="https://int.pz.gov.pl/dt/SingleSignOnService" ID="_f1a(...)" IssueInstant="2020-05-13T08:48:32.075Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://naszadomena.pl</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_f1a(...)">
<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#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>dn1e/F(...)</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>al03WGy/zJm(...)</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDZzCC(...)</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</saml2p:AuthnRequest>

tak wygląda przykładowy XML z dokumentacji DT:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://client.system.pl/index"
Destination="https://pz.gov.pl/dt/SingleSignOnService"
ID="ID_ac99bd70-2428-449a-92d0-47abdd84def9" IssueInstant="2014-06-30T08:03:21.789Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://klient01.pl</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="">
<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#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml2 saml2p xenc"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>NhBA2Hv/68W32w6OEsCMk51Hhl3neszpxlhwX3+jNeU=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>F6inIhf4dbX8RZgTWXoA3ZzmPLxccS6nu/guac(…)<ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIE3TCCA8WgAwIBAgIIKKqJnqOvcj4w(…)</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</saml2p:AuthnRequest>

Na pewno brakuje nam jeszcze InclusiveNamespaces.
Testowałem też CanonicalizationMethod jako http://www.w3.org/TR/2001/REC-xml-c14n# zamiast http://www.w3.org/TR/2001/REC-xml-c14n-20010315 tak jak ktoś wspomniał na forum, ale wtedy wywalało w ogóle błąd.

1

Cześć.
Moja działająca koperta na środowisku produkcyjnym:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" AssertionConsumerServiceURL="https://system(...).pl/callback" Destination="https://pz.gov.pl/dt/SingleSignOnService" ID="IS_05f2141bc5b50868_829a13eade1f2732" IssueInstant="2020-05-13T09:02:23.020Z" Version="2.0">
	<saml2:Issuer>https://system(...).pl</saml2:Issuer>
	<ds:Signature>
		<ds:SignedInfo>
			<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
			<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
			<ds:Reference URI="">
				<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#"/>
				</ds:Transforms>
				<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
				<ds:DigestValue>hv2qoBq8AzPgufL6AlrV2dxQf342grXJGbdepq6YGTU=</ds:DigestValue>
			</ds:Reference>
		</ds:SignedInfo>
		<ds:SignatureValue>WYLp(...)g==</ds:SignatureValue>
		<ds:KeyInfo>
			<ds:X509Data>
				<ds:X509Certificate>MIIE(...)kgM=</ds:X509Certificate>
			</ds:X509Data>
		</ds:KeyInfo>
	</ds:Signature>
</saml2p:AuthnRequest>
0

Jeżeli mogę coś doradzić to logowanie przez pz.gov.pl nie będzie już niedługo możliwe. Tj. źródłem logowania nie będzie sam Profil Zaufany tylko login.gov.pl tzw. węzeł krajowy, a pz będzie tylko jego dostarczycielem tożsamości. Dlatego tak przyszłościowo proponuję poczytać w tym temacie i może nie marnować niepotrzebnie zasobów :)

0

Ciekawa sprawa trzeba zgłębić temat pewnie implementacja nie będzie się mocno różniła. Nie wydaje mi się żeby przestali wspierać PZ i DT pewnie będą to wygaszali latami skoro przeszli na SHA256 w lutym 2020 więc może nie ma powodu do paniki ze starszymi implementacjami.

edit: na pierwszy rzut oka zmienia się tylko adres na login.gov.pl

0

Integracja jest bardzo podobna ale wprowadzona jest dodatkowa metoda szyfrowania odpowiedzi i oddzielne certyfikaty do tego na krzywych eliptycznych (nie wiadomo po co). Certyfikaty trzeba sobie zakupić oddzielnie na produkcję (około 2kzł na 3 lata). Sama integracja jest bardzo przyjemna tj. dokumentacja zgadza się z rzeczywistością 1:1 i można liczyć na szybą odpowiedź na zadawane pytania w pomocy technicznej.

0
Dymb napisał(a):

Sama integracja jest bardzo przyjemna tj. dokumentacja zgadza się z rzeczywistością 1:1 i można liczyć na szybą odpowiedź na zadawane pytania w pomocy technicznej.

żartujesz czy Ty tak na poważnie?
mówimy o tym? https://mc.bip.gov.pl/interoperacyjnosc-mc/wezel-krajowy-dokumentacja-dotyczaca-integracji-z-wezlem-krajowym.html

0

Jakkolwiek nieprawdopodobnie to brzmi to wg. tak jest. Integrowałem się już z pierwszym ePuap-em, który powstał przy pomocy pewnej skończonej liczby studentów i działał jak działał, a włosy z głowy które wtedy rwałem już nie odrosną :), więc wydaje mi się że jestem w stanie to porównać. Tutaj wygląda na to że COI poszło po rozum do głowy i zleciło to jakiejś firmie zewnętrznej i wygląda to naprawdę dobrze. Dostajemy nawet w pełni działającą gotową aplikację w Spring Boot, tak by mieć się na czym wzorować.

0

Czy ktoś mógłby się podzielić kopertą do getTpUserInfo?

1

Mogę się wreszcie pochwalić, no i pokonałem ePUAP w C#.
Zrobiłem uwierzytelnianie, podpisanie dokumentu i wreszcie działające poprawnie wylogowani.

0

Poszukujących wzorcowej implementacji w C# interacji z ePUAP (logowanie, podpisywanie, ESP) zapraszam do repo na github.
(proszę tylko zwrócić uwagę na typ licencji).

W niedługim czasie będę mierzył się z logowaniem przez WK, aczkolwiek z uwagi na różnice technologiczne (certyfikaty eliptyczne ktore nie są obsługiwane przez bibliotekę standardową .NET Framework*) może to chwilę zająć.

  • certyfikaty jako takie są obsługiwane ale SignedXml wyrzuca wyjątek przy próbie ich użycia do wygenerowania sygnatury
0

@torq314: Świetna robota.

Mam pytanie odnośnie tego modelu: https://github.com/wzychla/OldMusicBox.ePUAP.Client/blob/master/OldMusicBox.ePUAP.Client/Model/GetTpUserInfo/GetTpUserInfoResponse.cs#L141
To są wszystkie dane (tzn. imię, nazwisko, pesel, id) jakie można wyciągnąć o użytkowniku z ePUAP?

EDIT:
Znalazłem odpowiedź, gdyby kogoś interesowało to ostatnia strona: https://pz.gov.pl/Instrukcja_dla_Integratora_PZ_logowanie.pdf

Do poprania danych użytkownika sesji służy metoda getTpUserInfo wystawiana przez usługę PZ:
https://pz.gov.pl/pz-services/tpUserInfo
Metoda zwraca następujące informacje dla danych osoby fizycznej:

  • Adres e-mail
  • Nazwisko
  • Imię
  • PESEL
  • Identyfikator Profilu Zaufanego
  • Identyfikator konta użytkownika
0
ttfnty napisał(a):

@torq314: Świetna robota.

Mam pytanie odnośnie tego modelu: https://github.com/wzychla/OldMusicBox.ePUAP.Client/blob/master/OldMusicBox.ePUAP.Client/Model/GetTpUserInfo/GetTpUserInfoResponse.cs#L141
To są wszystkie dane (tzn. imię, nazwisko, pesel, id) jakie można wyciągnąć o użytkowniku z ePUAP?

EDIT:
Znalazłem odpowiedź, gdyby kogoś interesowało to ostatnia strona: https://pz.gov.pl/Instrukcja_dla_Integratora_PZ_logowanie.pdf

Do poprania danych użytkownika sesji służy metoda getTpUserInfo wystawiana przez usługę PZ:
https://pz.gov.pl/pz-services/tpUserInfo
Metoda zwraca następujące informacje dla danych osoby fizycznej:

  • Adres e-mail
  • Nazwisko
  • Imię
  • PESEL
  • Identyfikator Profilu Zaufanego
  • Identyfikator konta użytkownika

Wyżej, w GetTpUserInfoReturn, jest AccountEmailAddress.

0

Dzień dobry. Proszę o pomoc. Poszukuję jakiejś wzorcowej implementacji obecnie działającej aplikacji obsługującej epuap -logowanie, podpisywanie, skrzynka podawcza w Javie.

0

Cześć,

Czy ktoś komu już udało się ogarnąć integracje z PZ mógłby podrzucić przykładową envelope do tpUserInfo (juz po podpisie)? Ja, pomimo wielu prob dostaje caly czas zwrotke:

 <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>These policy alternatives can not be satisfied: 
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}AsymmetricBinding: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}X509Token: The received token does not match the token inclusion requirement
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedParts: Soap Body is not SIGNED</faultstring></soap:Fault></soap:Body></soap:Envelope>

Przy projektowaniu envelope korzystalem z wsdl-a:
https://int.pz.gov.pl/pz-services/tpUserInfo?wsdl

ktory generuje nastepujaca strukture:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="http://userinfo.zp.epuap.gov.pl">
   <soapenv:Header/>
   <soapenv:Body>
      <user:getTpUserInfo>
         <tgsid>?</tgsid>
         <systemOrganisationId>?</systemOrganisationId>
      </user:getTpUserInfo>
   </soapenv:Body>
</soapenv:Envelope>
0

@Łukasz Kęska: poprawna struktura jest opisana w dokumentacji i stamtąd można wyciągnąć przykładowy. Ten XML wygląda jak wygenerowany przez domyślny serializator, zakładający że usługa nie wymaga szczególnej składni zgodnej z WS-Security. Tymczasem w dokumentacji jest wyraźnie zaznaczone, że wymaga się dokładnie takiego a nie innego formatu.

Tu jakiś wyjęty z logów i trochę przeformatowany. W szczególności, dopóki Header nie zawiera poprawnego węzła BST to nie ma co dalej próbować.

<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Header xmlns:obi="http://wsdl.epuap.gov.pl/obiekty/">
        <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <BinarySecurityToken d4p1:Id="X509-d197a1fc-ceab-469c-a438-633288b2b619" 
                    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
                    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" 
                    xmlns:d4p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">MII...tu...certyfikat...</BinarySecurityToken>
            <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/2001/04/xmldsig-more#rsa-sha256" />
                    <Reference URI="#id-144254239">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                        <DigestValue>TbdwlqbPiGlni7E0lMgGLVr458wFid/3ZTBHF7ocWhM=</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>My...tu...sygnatura...</SignatureValue>
                <KeyInfo Id="KI-1975959953">
                    <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="1069223476">
                        <wsse:Reference URI="#X509-d197a1fc-ceab-469c-a438-633288b2b619" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
                    </wsse:SecurityTokenReference>
                </KeyInfo>
            </Signature>
        </Security>
    </Header>
    <Body d2p1:Id="id-144254239" xmlns:d2p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <getTpUserInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://userinfo.zp.epuap.gov.pl">
            <tgsid xmlns="">_ID-a4...</tgsid>
            <systemOrganisationId xmlns="">0</systemOrganisationId>
        </getTpUserInfo>
    </Body>
</Envelope>
2

Informuję że klient dla .NET/C# do integracji z Węzłem Krajowym jest już na github, licencja MIT. Jest też opublikowany na nuget.
Działa z witryną symulatora, po nowym roku będzie testowany z produkcyjnym WK.

https://github.com/wzychla/OldMusicBox.EIH.Client
https://www.nuget.org/packages/OldMusicBox.EIH.Client/

Można zgłaszać ewentualne problemy, sugestie i uwagi.

0

Hej,

Trochę już załamuje ręce i nie wiem co robi źle...

Wszystko wygląda tak, jakbym miał zły podpis i taki też komunikat dostaje z serwera testowego.
Co robię:

  1. Mam taką kopertę (wzięte z dokumentacji):
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:eidas="http://eidas.europa.eu/saml-extensions" xmlns:naturalperson="http://eidas.europa.eu/attributes/naturalperson" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" AssertionConsumerServiceURL="https://www.medicaldata.pl/test.php" Destination="https://login.gov.pl/login/SingleSignOnService" ForceAuthn="true" ID="ID-ae56a741-0667-8f56-509c-07149b72e02b" IssueInstant="2021-02-04T09:04:40Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" ProviderName="NAZWA_FIRMY" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">NAZWA_FIRMY</saml2:Issuer>
    <saml2p:Extensions>
        <eidas:SPType xmlns:eidas="http://eidas.europa.eu/saml-extensions">public</eidas:SPType>
        <eidas:RequestedAttributes xmlns:eidas="http://eidas.europa.eu/saml-extensions">
            <eidas:RequestedAttribute FriendlyName="FamilyName" Name="http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="FirstName" Name="http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="DateOfBirth" Name="http://eidas.europa.eu/attributes/naturalperson/DateOfBirth" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="PersonIdentifier" Name="http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
        </eidas:RequestedAttributes>
    </saml2p:Extensions>
    <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"></saml2p:NameIDPolicy>
    <saml2p:RequestedAuthnContext Comparison="minimum">
        <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://eidas.europa.eu/LoA/substantial</saml2:AuthnContextClassRef>
    </saml2p:RequestedAuthnContext>
</saml2p:AuthnRequest>
  1. Robię z tej koperty hash z sha256 i z tego robie base64, to będzie moje późniejsze DigestValue
  2. Podpisuje sobie tego xml za pomocą openssl
openssl dgst -sha256 -sign private.key < ./authn_request.xml > ./signature.bin
  1. Jak sobie wygeneruje klucz publiczny
    openssl x509 -pubkey -noout -in private.key > pubkey.pem
    i zrobie weryfikacje:
    openssl dgst -verify pubkey.pem -signature signature.bin authn_request.xml
    to mam komunikat ze jest ok.
  2. Następnie biorę zawartość signature.bin i koduje to w base64 i to będzie moje SignatureValue
  3. Ostatecznie doklejam do xml cały segment Signature i mój xml wyglda tak
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:eidas="http://eidas.europa.eu/saml-extensions" xmlns:naturalperson="http://eidas.europa.eu/attributes/naturalperson" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" AssertionConsumerServiceURL="https://www.medicaldata.pl/test.php" Destination="https://login.gov.pl/login/SingleSignOnService" ForceAuthn="true" ID="ID-ae56a741-0667-8f56-509c-07149b72e02b" IssueInstant="2021-02-04T09:04:40Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" ProviderName="NAZWA_FIRMY" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">NAZWA_FIRMY</saml2:Issuer>
    <ds:Signature>
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
            <ds:Reference URI="ID-ae56a741-0667-8f56-509c-07149b72e02b">
                <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 xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml2 saml2p xenc"/>
                    </ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <ds:DigestValue>QnQDd4UDx...</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>MEUCIG....</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>MIICljCCA....</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
    <saml2p:Extensions>
        <eidas:SPType xmlns:eidas="http://eidas.europa.eu/saml-extensions">public</eidas:SPType>
        <eidas:RequestedAttributes xmlns:eidas="http://eidas.europa.eu/saml-extensions">
            <eidas:RequestedAttribute FriendlyName="FamilyName" Name="http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="FirstName" Name="http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="DateOfBirth" Name="http://eidas.europa.eu/attributes/naturalperson/DateOfBirth" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
            <eidas:RequestedAttribute FriendlyName="PersonIdentifier" Name="http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"></eidas:RequestedAttribute>
        </eidas:RequestedAttributes>
    </saml2p:Extensions>
    <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"></saml2p:NameIDPolicy>
    <saml2p:RequestedAuthnContext Comparison="minimum">
        <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://eidas.europa.eu/LoA/substantial</saml2:AuthnContextClassRef>
    </saml2p:RequestedAuthnContext>
</saml2p:AuthnRequest>
  1. Pakuje to w base64 i wysyłam postem do serwera.
    Pytanie co robie źle, bo cały czas mam taki komunikat:
    Błąd podczas weryfikacji podpisu lub certyfikatu w żądaniu AuthnRequest wysłanym przez system kliencki o nazwie Issuer 'NAZWA_FIRMY': Niepoprawny podpis.
0

@Paweł Maj: dla zbudowania sygnatury zgodnej z XMLDsig trzeba jednak zrobić coś więcej. Nie wystarczy policzyć hasha z dokumentu i wstawić do SignatureValue.
To jest tak:

  1. najpierw używa się wskazanego w Reference/Transforms normalizatora (tu: c14n) żeby wyjściowy XML znormalizować
  2. ze znormalizowanego dokumentu wylicza się hash, wyliczony hash wstawia się do DigestValue
  3. sekcję ds:SignedInfo (zawierającą digest) traktuje się jako nowy XML
  4. do tego małego XMLa znów stosuje się transformatę, wskazaną tym razem w SignedInfo/CanonicalizationMethod
  5. ze znormalizowanego małego dokumentu liczy się znów hash, ale nigdzie się go nie wstawia
  6. ten nowy wyliczony hash szyfruje się kluczem certyfikatu i wstawia wartość do SignatureValue

Tego lepiej nie robić samemu, tylko zrzucić na jakąś bibliotekę, która rozumie te kroki.
Walidacja przez openssl może dać fałszywy obraz sytuacji jeśli pomija to jak sygnatura jest zbudowana.

0

Dla zainteresowanych - informuję, że implementacja klienta .NET do Węzła Krajowego, którą anonsowałem kilka wpisów wyżej, otrzymała w repo aktualizację dodającą zastępnik serwera WK. Aktualnie biblioteka zawiera zarówno część kliencką jak i serwerową, a częścią repozytorium są przykładowe implementacje klienta i serwera (obie można lokalnie uruchomić w VS2019

W szczególności

  • klient poprawnie działa z rzeczywistym Symulatorem Węzła Krajowego (i w związku z tym należy się wzorować na nim we własnych aplikacjach dla .NET)
  • klient poprawnie działa z załączonym przykładowym serwerem
  • załączonego przykładowego serwera można więc użyć jako zastępnika Symulatora Węzła Krajowego - nadaje się do lokalnych testów integracyjnych

Mówiąc inaczej, mając własnego klienta napisanego jakkolwiek (w Javie, node.js, PHP czy w .NET) można debugować przepływ SSO używając mojego przykładowego serwera - bo można go uruchomić lokalnie i w pełni debugować. Rzeczywisty Symulator Węzła Krajowego nie ułatwia zadania o tyle że nie ma możliwości debugowania go (bo jest udostępniony tylko zdalnie).

Oczywiście nie daję 100% gwarancji że przejście testu integracyjnego z zastępnikiem serwera implikuje przejście testu do Symulatora WK (a potem do produkcyjnego WK), natomiast jestem przekonany że jeśli się nie przechodzi testu do zastępnika to nie przejdzie się testu na symulatorze. Zastępnik serwera stara się bowiem szczegółowo powtarzać cały przepływ SSO SAML2, w tym podpisuje zwracane odpowiedzi, a dodatkowo ostatnią odpowiedź (ArtifactResponse) szyfruje tak samo jak szyfruje ją Węzeł Krajowy.

0

Czy komuś udało się zrobić integrację z login.gov.pl (węzeł krajowy) w Javie? Jeśli tak to jakiej biblioteki najlepiej do tego użyć? W przypadku użycia liba onelogin do artifactResolve dodaje się podpis ale bezpośrednio w znaczniku soap:Envelope, a powinno być w soap:Body. Byłbym wdzięczny za wszelkie sugestie.

0

@matid: Jam Ci tego dokonał, ale do rozwiązywania artefaktu nie używałem żadnej biblioteki. Koperty buduję ręcznie a potem podpisuję i to wysyłam zwykłym HttpClient

0

@Dymb: Miło słyszeć żę się udało :) Co rozumiesz pod pojęciem ręcznie? Wczytujesz xmla, tego który jest w dokumentacji COI czy w jakiś inny sposób?

2

@matid: To może wrzucę po prostu tę funkcję i będziesz miał z głowy :)

public static Document getSignedEcdSamlResolve(String keystoreFile,
    		String privateKeyPass, 
    		String issuerText, 
    		String artifactText) throws Exception {
    	
    	ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, "ds");
    	
    	String certificateAlias = "";
		
		KeyStore ks = getKeystore(keystoreFile, privateKeyPass);
		PrivateKey privateKey = getPrivateKey(privateKeyPass, ks);
		
    	javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory
				.newInstance();
		
		dbf.setNamespaceAware(true);
		javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
		org.w3c.dom.Document doc = db.newDocument();
	 
		//Koperta SOAP-owa
		Element root = doc.createElementNS("http://schemas.xmlsoap.org/soap/envelope/", "soap:Envelope");
		root.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:soap", "http://schemas.xmlsoap.org/soap/envelope/");
		root.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
		
		
		//Naglowek koperty
		Element header = doc.createElement("SOAP-ENV:Header");
		root.appendChild(header);
		
		//BOdy koperty
		Element body = doc.createElement("SOAP-ENV:Body");
		root.appendChild(body);
		
		
		String id = "ID-" + UUID.randomUUID().toString();
		SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
		String date = DATE_FORMAT.format(new Date());
		String time = TIME_FORMAT.format(new Date());
		
		//Rozwiazanie artefaktu wstawiane do koperty
		Element artifactResolve = doc.createElement("saml2p:ArtifactResolve");
		body.appendChild(artifactResolve);
		
		artifactResolve.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
		artifactResolve.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:saml2", "urn:oasis:names:tc:SAML:2.0:assertion");
		artifactResolve.setAttributeNS(null, "ID", id);
		artifactResolve.setAttributeNS(null, "IssueInstant", date + "T" + time + "Z");
		artifactResolve.setAttributeNS(null, "Version", "2.0");
		
		
		//Issuer
		Element issuer = doc.createElement("saml2:Issuer");
		issuer.appendChild(doc.createTextNode(issuerText));
		artifactResolve.appendChild(issuer);
		
		//Sygnatura
		
		XMLSignature sig = new XMLSignature(doc, "", XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); //, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS
		
		artifactResolve.appendChild(sig.getElement());
		
		//Artefakt
		Element artifact = doc.createElement("saml2p:Artifact");
		artifact.appendChild(doc.createTextNode(artifactText));
		artifactResolve.appendChild(artifact);

		doc.appendChild(root);
		
		//Transformacje
		Transforms transforms = new Transforms(doc);
		transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
		transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
		
		sig.addDocument("", transforms, DigestMethod.SHA256);
				  
		X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias);
		sig.addKeyInfo(cert);
		sig.sign(privateKey);
		
		return doc;
    }

0 użytkowników online, w tym zalogowanych: 0, gości: 0