Errori vari con l'uso di italia/spid-testenv2

Salve,
inizio con il ringraziarvi dell’eventuale supporto che saprete darmi.

Gli step che ho compiuto sono i seguenti:

  1. Ho scaricato ed avviato correttamente la SDK-Spring, italia/spid-testenv2 (avviato direttamente dall’immagine presa da docker-hub) e SPID Validator (Build & start con docker).

  2. Ho installato i certificati della mia organizzazione all’interno del KeyStore.jks contenuto nell’SDK (usando il keytool jdk8)

  3. Ho firmato il metadata-sp.xml attraverso xmlsectool.sh con il comando

./xmlsectool.sh --sign --inFile metadata/metadata-sp.xml --outFile out.xml --certificate crt/mycert.cer --keyFile crt/mycert.key

  1. ho posto alla validazione dello SPID-Validator sino a che non ho ottenuto tutti i segnali verdi (NB, ho rimosso il tag <?xml version=“1.0” encoding=“UTF-8” > come trovato in una issue sul forum per il problema “Parsing utf-8”

  2. Ho inserito nella configurazione dello italia/spid-testenv2 il mio metadata e riavviato il container, verificato poi che sull’interfaccia grafica fosse disponibile il mio endpoint

  3. Ho eseguito in locale da postman la chiamata all’SDK per ottenare la SAML Request.
    PRIMO ERRORE: La SDK restituisce un formato che l’ambiente di test liquida con

Impossibile decodificare l’elemento ‘SAMLRequest’

  1. Sono andato in debug, ho quindi preso la SAML Request ed l’ho codificata in base64 inviandola all’ambiente di test sempre con una post in cui ho compilato i campi:

SAMLRequest e RelayState su tipo post FORM-DATA.

ottengo quindi:

AuthnRequest - attribute: IsPassive item not allowed
AuthnRequest/Issuer - attribute: Format Il valore dell’elemento è diverso dal valore atteso (urn:oasis:names:tc:SAML:2.0:nameid-format:entity):
urn:oasis:names:tc:SAML:2.0:nameid-format:transient

Allego la mia SAMLRequest:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceIndex="0" AssertionConsumerServiceURL="https://PRIVATE/spid/signin.html" AttributeConsumingServiceIndex="1" Destination="http://localhost:8088/sso" ID="_abdd8d0-370e-4f76-b281-8eebb276faef" IsPassive="false" IssueInstant="2021-04-09T08:58:39.939Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
	<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="PRIVATE">PRIVATE</saml2:Issuer>
	<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/2001/04/xmldsig-more#rsa-sha256"/>
			<ds:Reference URI="#_abdd8d0-370e-4f76-b281-8eebb276faef">
				<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/2000/09/xmldsig#sha1"/>
				<ds:DigestValue/>
			</ds:Reference>
		</ds:SignedInfo>
		<ds:SignatureValue/>
		<ds:KeyInfo>
			<ds:KeyValue>
				<ds:RSAKeyValue>
					<ds:Modulus>............</ds:Modulus>
					<ds:Exponent>AQAB</ds:Exponent>
				</ds:RSAKeyValue>
			</ds:KeyValue>
			<ds:X509Data>
				<ds:X509Certificate>MIIG..............6tVggXjY</ds:X509Certificate>
			</ds:X509Data>
		</ds:KeyInfo>
	</ds:Signature>
	<saml2p:NameIDPolicy xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
	<saml2p:RequestedAuthnContext xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="exact">
		<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://www.spid.gov.it/SpidL2</saml:AuthnContextClassRef>
	</saml2p:RequestedAuthnContext>
</samlp:AuthnRequest>

ed anche il mio metadata

<?xml version="1.0" encoding="UTF-8" standalone="no"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:spid="https://spid.gov.it/saml-extensions" ID="_abdd8d0-370e-4f76-b281-8eebb276faef" entityID="https://PRIVATE"><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/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>Tb3......oc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
........
</ds:SignatureValue>
<ds:KeyInfo>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>
.........
</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
<ds:X509Data>
<ds:X509Certificate>
MIIGJ....XjY
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>

	<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

		<md:KeyDescriptor use="signing">
			<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
				<ds:X509Data>
					<ds:X509Certificate>MIIGJjCCB...ggXjY</ds:X509Certificate>
				</ds:X509Data>
			</ds:KeyInfo>
		</md:KeyDescriptor>

		<md:KeyDescriptor use="encryption">
			<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
				<ds:X509Data>
					<ds:X509Certificate>MIIGJ.....VggXjY</ds:X509Certificate>
				</ds:X509Data>
			</ds:KeyInfo>
		</md:KeyDescriptor>

		<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://PRIVATE/logout"/>
		<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
		
		<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://PRIVATE/spid/signin.html" index="0" isDefault="true"/>
		<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://PRIVATE/spid/login.html" index="1" isDefault="false"/>
		
		<md:AttributeConsumingService index="2">
			<md:ServiceName xml:lang="it">Login</md:ServiceName>
			<md:ServiceDescription xml:lang="it">Login</md:ServiceDescription>
			<md:RequestedAttribute Name="name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="familyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="fiscalNumber" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
		</md:AttributeConsumingService>
		<md:AttributeConsumingService index="1">
			<md:ServiceName xml:lang="it">Iscrizione</md:ServiceName>
			<md:ServiceDescription xml:lang="it">Iscrizione</md:ServiceDescription>
			<md:RequestedAttribute Name="spidCode" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="gender" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="placeOfBirth" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="ivaCode" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="companyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="mobilePhone" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="address" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="expirationDate" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="familyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="fiscalNumber" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="dateOfBirth" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="countyOfBirth" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="idCard" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="registeredOffice" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
			<md:RequestedAttribute Name="digitalAddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
		</md:AttributeConsumingService>		
	</md:SPSSODescriptor>

	<md:Organization>
		<md:OrganizationName xml:lang="it">PRIVATE</md:OrganizationName>
		<md:OrganizationDisplayName xml:lang="it">PRIVATE</md:OrganizationDisplayName>
		<md:OrganizationURL xml:lang="it">https://PRIVATE/</md:OrganizationURL>
	</md:Organization>
	<md:ContactPerson contactType="other">
		<md:Extensions>
			<spid:VATNumber>IT12345678901</spid:VATNumber>
			<spid:FiscalCode>XYZABCAAMGGJ000W</spid:FiscalCode>
			<spid:Private/>
		</md:Extensions>
		<md:EmailAddress>tech-info@example.org</md:EmailAddress>
		<md:TelephoneNumber>+39 8472345634785</md:TelephoneNumber>
	</md:ContactPerson>
</md:EntityDescriptor>

secondo voi dove sto sbagliando?

Sbagli a non leggere le regole tecniche:

  • Nell’elemento <AuthnRequest> non deve essere presente l’attributo IsPassive

  • Deve essere presente l’elemento <Issuer> [omissis]. L’elemento deve riportare gli attributi:

    • Format fissato al valore urn:oasis:names:tc:SAML:2.0:nameid-format:entity

E ti anticipo anche un altro errore che ho notato nella tua AuthnRequest. Stai usando come digest lo sha1, mentre le regole dicono:

  • nel caso del binding HTTP POST deve essere presente l’elemento <Signature> contenente la firma sulla richiesta apposta dal Service Provider. La firma deve essere prodotta secondo il profilo specificato per SAML (SAML-Core, cap. 5) utilizzando chiavi RSA almeno a 2048 bit e algoritmo di digest SHA-256 o superiore.

Grazie. Tuttavia il dubbio che mi viene è questo:

La parte che ho scritto personalmente ossia il metadata-sp, ha la digest a 256

<ds:DigestMethod Algorithm=“http://www.w3.org/2001/04/xmlenc#sha256”/>

La Request invece viene generata dalla SDK-Spring presente su developer italia… quindi mi stai dicendo che, la SDK che trovo sul sito non è aggiornata/non è valida per l’utilizzo ed è meglio accantonarla e scriversi qualcosa di proprio conto?

O c’è qualche altra SDK in altro linguaggio in grado di generare una SAMLRequest che non presenta le anomalie che mi hai segnalato!?

Grazie!

EDIT:

Ho provato anche a cambiare l’element

inserendo

  • Format fissato al valore urn:oasis:names:tc:SAML:2.0:nameid-format:entity

Chiede transient e viceversa

Personalmente ho dato un’occhiata veloce a quella libreria e mi sembra un abbozzo dall’utilità limitata. Fa riferimento a “Spring” perché utilizza l’estensione per SAML 2 di Spring Security (https://spring.io/projects/spring-security-saml), che peraltro oggigiorno è anche in fase di dismissione in favore dell’integrazione del support SAML dentro il core di Spring Security a partire dalla versione 5.2.0. Potrebbe far pensare che serva per integrare SPID nella propria applicazione che fa uso di Spring Security, ma è fuorviante: l’integrazione in questo caso dovrebbe adottare un approccio ben diverso e cioè dovrebbe consistere nella configurazione delle classi di supporto di Spring Security affinché possano guidare correttamente l’autenticazione tramite SAML, ma in realtà quello che vedo è del codice che potrebbe servire come inizio per studiare come implementare un Service Provider SAML, che è ben diverso, o meglio: un’applicazione che usa Spring Security e vuole aggiungere il supporto a SAML svolge il ruolo di Service Provider, ma non dovrebbe entrare nel processo di gestione delle richieste SAML: dovrebbe solo consumare il risultato finale dell’autenticazione (principal ed attributi ad esso riferiti) ed orchestrare il processo di creazione della sessione locale e di mappatura degli utenti.
Dipende da cosa devi fare tu, ma poiché implementare SPID ha delle complicanze rispetto ad una semplice implementazione di un login mediante SAML 2.0 (vedasi requisiti fuori standard, necessità di gestire una moltitudine di Identity Provider diversi, ecc. ecc.), una semplice aggiunta del modulo di Spring Security potrebbe starti stretto.
Io stesso ho provato ad approfondire l’argomento ed alla fine ho cambiato strada.

A seconda dunque di quello che devi fare, un approccio volto ad implementare più a basso livello un Service Provider SAML potrebbe essere quello che ti serve, ma la libreria in questione, facendo uso dell’estensione di Spring Security, che è nata con il solo scopo di fornire gli elementi necessari al fine di integrare l’autenticazione SAML all’interno di un’applicazione che fa uso del framework Spring Security e che a sua volta usa la libreria OpenSAML, potrebbe essere un po’ troppo limitata. Personalmente a suo tempo ho abbandonato anche questa strada, a favore dell’uso di una libreria più “a tutto tondo” seppure a più basso livello, tipo (volendo rimanere in ambito Java) la stessa OpenSAML (https://wiki.shibboleth.net/confluence/display/OS30/Home), probabilmente la soluzione più completa, oppure java-saml (https://github.com/onelogin/java-saml), che sto usando io ma che richiede dei piccoli miglioramenti per poter soddisfare appieno i requisiti di SPID.

Implementare (bene) SPID non è semplice, poi dipende chiaramente da scopi e tempi.

Venendo al tuo problema specifico: il discorso dell’isPassive è una delle storture di SPID, dato che l’assenza dell’attributo da specifiche SAML è equivalente a specificare isPassive="false" come nella tua richiesta, per cui la tua richiesta è formalmente corretta dal punto di vista SAML, ma il validatore che stai usando prende alla lettera i requisiti imprecisi di SPID e quindi ti rigetta la richiesta perché trova un valore di isPassive specificato (fregandosene che è posto a false, che serebbe lo scopo ultimo del requisito).
Ecco, questo è il tipico esempio di quando dico che l’implementazione fornita dall’estensione Spring per SAML può essere limitata: qui per risolvere il problema dovresti estendere l’estensione in questione in modo che non aggiunga isPassive="false" nel caso in cui questo attributo sia false, ma per farlo bisogna capire se si riesce (dipende da com’è strutturato il codice) e potrebbe diventare più complicato rispetto appunto all’adozione diretta di una libreria più a basso livello (che però ti richiede più lavoro di orchestrazione dei vari “pezzi” che compongono il processo di autenticazione SAML).

Per quanto riguarda il discorso dell’Issuer: innanzi tutto fai attenzione, perché quando mi dici che hai provato a mettere entity e dice che vuole transient, probabilmente stai modificando l’elemento sbagliato. Per l’Issuer il formato dev’essere urn:oasis:names:tc:SAML:2.0:nameid-format:entity, invece sul NameIDPolicy il formato dev’essere urn:oasis:names:tc:SAML:2.0:nameid-format:transient.
Anche qui, il requisito di SPID che l’Issuer specifichi il Format è ridondante; non solo, le specifiche SPID richiedono anche si specificare il NameQualifier e qui arriviamo persino a violare le specifiche SAML (vedasi https://github.com/italia/spid-regole-tecniche/issues/15), per cui è un altro punto in cui potresti avere difficoltà con le librerie standard che trovi in giro.

Il consiglio che personalmente posso darti, se vuoi capire bene l’argomento e gestirlo in piena consapevolezza, è: studia bene SAML 2.0, poi guardati tutte le specifiche SPID e poi parti da una delle librerie che ti ho indicato sopra, a seconda di cosa vuoi fare. Lo so, è parecchio lavoro.

Se, invece, vuoi una soluzione già pronta per SPID, onestamente non saprei bene cosa suggerirti, almeno in ambito Java. Ho visto che l’INPS recentemente ha rilasciato qualcosa ma credo sia utilizzabile solo in ambito mobile, per cui anche in questo caso dipende da cosa devi fare.

Grazie mille Mauro, in effetti quello che mi hai detto è proprio quello che ho notato.

In particolare ho iniziato ad avere difficoltà quando nella SAMLRequest, la stessa documentazione tecnica di SPID va in contraddizione, infatti succede che indica i campi

AssertionConsumerServiceURL; ProtocolBinding e AttributeConsumingServiceIndex nell’esempio, ma poi se lo segui, l’ambiente di test comunica che devi scegliere solo uno di questi… e va bhé… tanto per aumentare il caos.

A questo punto mi sono armato di pazienza e visto che la Base64 che tira fuori la SDK, non so che cosa sia ma sicuramente non è Base64, ho estrapolato la SAMLRequest e l’ho corretta facendo una cosa molto grezza… passandola all’ambiente via POSTMAN.

Ad ogni modo, conscio di quanto mi hai detto che probabilmente, mi farà investire il tempo in maniera più profiqua di quanto abbia fatto sino ad ora, il target è permettere ad una delle nostre webapplication (Java Spring) di introdurre l’SSO con SPID, andando quindi a gestire login e registrazione. Il classico insomma.

Morale della favola sono arrivato adesso a creare questo file:

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                  	ID="_abdd8d0-370e-4f76-b281-8eebb276faef"
                  	Version="2.0"
                  	IssueInstant="2021-04-12T10:20:53.108Z"
                  	Destination="http://localhost:8088/sso"
                  	AssertionConsumerServiceIndex="1"
                  	>
	<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
            		Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
            		NameQualifier="https://PRIVATO.it">https://PRIVATO.it</saml2:Issuer>
	<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/2001/04/xmldsig-more#rsa-sha256"/>
			<ds:Reference URI="#_abdd8d0-370e-4f76-b281-8eebb276faef">
				<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/>
			</ds:Reference>
		</ds:SignedInfo>
		<ds:SignatureValue/>
		<ds:KeyInfo>
			<ds:KeyValue>
				<ds:RSAKeyValue>
					<ds:Modulus>lN...Q==</ds:Modulus>
					<ds:Exponent>AQAB</ds:Exponent>
				</ds:RSAKeyValue>
			</ds:KeyValue>
			<ds:X509Data>
				<ds:X509Certificate>MIIG...ggXjY</ds:X509Certificate>
			</ds:X509Data>
		</ds:KeyInfo>
	</ds:Signature>
	<saml2p:NameIDPolicy xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                   		Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
	<saml2p:RequestedAuthnContext xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                            		Comparison="exact">
		<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://www.spid.gov.it/SpidL2</saml:AuthnContextClassRef>
	</saml2p:RequestedAuthnContext>
</samlp:AuthnRequest>

Dove, inviandolo così com’è ottengo:

  File "/usr/local/lib/python3.7/base64.py", line 43, in _bytes_from_decode_data
    return memoryview(s).tobytes()
TypeError: memoryview: a bytes-like object is required, not 'NoneType'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/app/testenv/server.py", line 306, in single_sign_on_service
    spid_request = self._parse_message(action='login')
  File "/app/testenv/server.py", line 243, in _parse_message
    return self._handle_http_post(action)
  File "/app/testenv/server.py", line 282, in _handle_http_post
    HTTPPostSignatureVerifier(cert, request_data).verify()
  File "/app/testenv/crypto.py", line 244, in verify
    self._verify_signature()
  File "/app/testenv/crypto.py", line 293, in _verify_signature
    self._request.saml_request, x509_cert=self._cert)
  File "/usr/local/lib/python3.7/site-packages/signxml/__init__.py", line 815, in verify
    raw_signature = b64decode(signature_value.text)
  File "/usr/local/lib/python3.7/base64.py", line 80, in b64decode
    s = _bytes_from_decode_data(s)
  File "/usr/local/lib/python3.7/base64.py", line 46, in _bytes_from_decode_data
    "string, not %r" % s.__class__.__name__) from None
TypeError: argument should be a bytes-like object or ASCII string, not 'NoneType'

Che suppongo proprio sia il DIGEST che l’SDK in origine mi tronca cos’ì come appare.

Quindi ho deciso di valorizzarlo andando ad ottenere

Digest non valido

E li probabilmente sto ancora sbagliando qualcosa.

SPIEGO il perché di queste cose. Prima di mettermi a buttare giù codice, avendo un pò capito l’andazzo di una documentazione che non è che sia proprio proprio aggiornata o fedele al funzionamento o compliant al 100% con SAML, mi piacerebbe avere dei modelli di partenza da cui almeno partire e capire il giro funzionalmente, da li fare codice perché venga prodotta esattamente la SAML Request sperata!

Qualora dovesse servire a qualcuno, partendo dai passaggi precedenti, per firmare la SAMLRequest basta usare questo tool online:

Anche qui attenzione perché temo ci sia un fraintendimento: non confondere Assertion Consumer Service con Attribute Consuming Service. I campi che sono alternativi tra loro sono AssertionConsumerServiceIndex rispetto alla coppia AssertionConsumerServiceURL/ProtocolBinding (questo da specifica SAML), usati per indicare dove la risposta SAML dev’essere inviata (alternativamente mediante l’uso di un indice o di una coppia URL/binding). Invece l’AttributeConsumingServiceIndex è un’altra cosa e serve per richiedere gli attributi: non è alternativo agli altri, puoi certamente usarlo assieme.

Per avere una visione ad alto livello su come funziona SAML, ti consiglio questo documento:


con particolare riferimento al profilo Web Browser SSO.

La codifica base 64 è utilizzata in genere o per indicare in metadati e richieste i certificati, o per le firme, o per codificare l’intera richiesta ad esempio quando la invii tramite binding HTTP-Redirect o HTTP-Post. Anche il modo in cui firmi la richiesta può variare a seconda del binding.

Ti ringrazio di tutto. Leggerò questo manuale, inizierò a leggermelo e quindi a valutare lo sviluppo di un plugin per la mia applicazione!