- This repository is no longer maintained
- The software stack included within the project does not fully implement the SPID specifications
- The use in production is strongly discouraged.
SPID Auth Docker is a service provider based on shibboleth that takes care of the SPID authentication process with the Identity Provider and redirects the attributes of the final response to the set address so that they can be used by the application.
SPID Auth Docker has been developed and is maintained by AgID - Agenzia per l'Italia Digitale.
It's highly recommended to use the latest release of the image. The versioning follows the SemVer rules.
-
Create a directory to store SAML certificates and another to store log files
$ mkdir -vp /tmp/certs /tmp/log/{httpd,shibboleth,shibboleth-www} -
Create a docker compose file (
docker-compose.yml) with the following content. Note: setSERVER_NAMEto a publicly reachable IP or FQDN.version: '3' services: authproxy: image: spid-auth-proxy build: context: . dockerfile: Dockerfile ports: - '80:80' - '443:443' volumes: - '/tmp/certs:/opt/shibboleth-sp/certs' - '/tmp/log:/var/log' environment: ORGANIZATION: 'My eGov Service' SERVER_NAME: 'my.auth.proxy.com' ENTITY_ID: 'https://my.auth.proxy.com' TARGET_BACKEND: 'https://mytargetapp.my.cloud.provider.com' TARGET_LOCATION: '/login' ACS_INDEXES: '1;2' ACS_1_LABEL: 'set 1' ACS_1_ATTRS: 'name;familyName;fiscalNumber;email' ACS_2_LABEL: 'set 2' ACS_2_ATTRS: 'spidCode;fiscalNumber'
You can use
docker-compose.quickstart.yml, which is available in this repository. -
Execute the Docker environmnet with the following command
$ docker-compose up --buildIt will
-
build the docker image
-
generate a self-signed certificate for TLS (
SERVER_NAMEused asCN), SAML assertions signature (SAML SignatureasCN) and SAML metadata signature (SAML Metadata SignatureasCN) -
generate the Shibboleth/Httpd configuration according to the environment variables
-
execure
shibdandhttpd
-
-
If everything gone well, you should be able to access the URL
https://<SERVER_NAME>/metadataOpen it and use the following information
entityIDunder<md:EntityDescriptor>tag<ds:X509Certificate>under<md:SPSSODescriptor>tagLocationunder<md:SingleLogoutService>tagLocationunder<md:AssertionConsumerService>tag- attributes names under
<md:AttributeConsumingService>tags
to register you authentication proxy on
https://idp.spid.gov.it:8080 -
Open the URL
https://<SERVER_NAME>/accessand click on
Test on /whoami (lucia/password123)
It starts an authentication process that will end on
/whoamiendpoint where all the information about the authentication will be dumped.
-
Create a directory to store SAML certificates and another to store log files
$ mkdir -vp \ /opt/authproxy/certs/{saml,tls} \ /opt/authproxy/log/{httpd,shibboleth,shibboleth-www} -
Create/Obtain X509 certificates for TLS and SAML signatures and store them as follows
/opt/authproxy/certs ├── saml │ ├── sp-cert.pem │ ├── sp-key.pem │ ├── sp-meta-cert.pem │ └── sp-meta-key.pem └── tls ├── server.crt └── server.key -
Create a docker compose file as follows. Be sure to set environment variables to values reflecting your real environment.
version: '3' services: authproxy: image: spid-auth-proxy build: context: . dockerfile: Dockerfile ports: - '80:80' - '443:443' volumes: - '/opt/authproxy/certs/saml:/opt/shibboleth-sp/certs:ro' - '/opt/authproxy/certs/tls/server.crt:/etc/pki/tls/certs/server.crt:ro' - '/opt/authproxy/certs/tls/server.key:/etc/pki/tls/private/server.key:ro' - '/opt/authproxy/log:/var/log' environment: MODE: 'prod' ORGANIZATION: 'My eGov Service' SERVER_NAME: 'my.auth.proxy.com' ERROR_URL: 'https://my.auth.proxy.com/error' ENTITY_ID: 'https://my.auth.proxy.com' TARGET_BACKEND: 'https://mytargetapp.my.cloud.provider.com' TARGET_LOCATION: '/login' ACS_INDEXES: '1;2' ACS_1_LABEL: 'set 1' ACS_1_ATTRS: 'name;familyName;fiscalNumber;email' ACS_2_LABEL: 'set 2' ACS_2_ATTRS: 'spidCode;fiscalNumber'
Be sure that
MODEenvvar is set toprod.The URL specified in
ERROR_URLshould be an endpoint that is able to manage errors as mentioned inhttps://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPErrors#NativeSPErrors-Redirection -
If necessary, revise the
httpdconfiguration files underetc/httpd/conf.din order to fit with your requirements -
Execute the Docker environmnet with the following command
$ docker-compose up --build -
Register your authentication proxy on the IdP by providing the information contained at
https://<SERVER_NAME>/metadata -
In order to use the authentication proxy, you application should initialise the the authentication by calling
https://<SERVER_NAME>/iam/Login?target=https://<SERVER_NAME>/login&entityID=<IDP ENTITY_ID>Once authenticated, the callback (
/login) will proxy the response to your backend (TARGET_BACKEND) by including within the request headers the authentication result.
The AttributeConsumingService (ACS) elements can be defined by using a set
of properly named environment variables.
Firstly, you have to declare the indexes of your ACSs by defining the
ACS_INDEXES variable with all the indexes separated by a ;.
Then, for each ACS, you have to define the label with ACS_<INDEX>_LABEL and
the list of the attributes with ACS_<INDEX>_ATTRS. The attributes must be
specified as ; separated list.
For instance, to the define two ACSs (with index 1 and 27) where the
first includes the attributes spidCode and fiscalNumber while the latter
name and placeOfBirth, the environment variables must be defined and set
as follows
environment:
ACS_INDEXES: '1;27'
ACS_1_LABEL: 'My First Set'
ACS_1_ATTRS: 'spidCode;fiscalNumber'
ACS_27_LABEL: 'My Second Set'
ACS_27_ATTRS: 'name;placeOfBirth'The ACS_* environment variables are also used to configure the AttributeChecker handler.
The environment variables of the example will generate the following configuration
(nested in the resulting /etc/shibboleth/shibboleth2.xml)
<!-- Check the returned attributes -->
<Handler type="AttributeChecker" Location="/AttrChecker" template="attrChecker.html" flushSession="true">
<AND>
<OR>
<Rule require="authnContextClassRef">https://www.spid.gov.it/SpidL1</Rule>
<Rule require="authnContextClassRef">https://www.spid.gov.it/SpidL2</Rule>
<Rule require="authnContextClassRef">https://www.spid.gov.it/SpidL3</Rule>
</OR>
<OR>
<!-- Check AttributeConsumingService with index 1 -->
<AND>
<AND>
<Rule require="SPIDCODE"/>
<Rule require="FISCALNUMBER"/>
</AND>
<AND>
<NOT><Rule require="ADDRESS"/></NOT>
<NOT><Rule require="COMPANYNAME"/></NOT>
<NOT><Rule require="COUNTYOFBIRTH"/></NOT>
<NOT><Rule require="DATEOFBIRTH"/></NOT>
<NOT><Rule require="DIGITALADDRESS"/></NOT>
<NOT><Rule require="EMAIL"/></NOT>
<NOT><Rule require="EXPIRATIONDATE"/></NOT>
<NOT><Rule require="FAMILYNAME"/></NOT>
<NOT><Rule require="GENDER"/></NOT>
<NOT><Rule require="IDCARD"/></NOT>
<NOT><Rule require="IVACODE"/></NOT>
<NOT><Rule require="MOBILEPHONE"/></NOT>
<NOT><Rule require="NAME"/></NOT>
<NOT><Rule require="PLACEOFBIRTH"/></NOT>
<NOT><Rule require="REGISTEREDOFFICE"/></NOT>
</AND>
</AND>
<!-- Check AttributeConsumingService with index 27 -->
<AND>
<AND>
<Rule require="NAME"/>
<Rule require="PLACEOFBIRTH"/>
</AND>
<AND>
<NOT><Rule require="ADDRESS"/></NOT>
<NOT><Rule require="COMPANYNAME"/></NOT>
<NOT><Rule require="COUNTYOFBIRTH"/></NOT>
<NOT><Rule require="DATEOFBIRTH"/></NOT>
<NOT><Rule require="DIGITALADDRESS"/></NOT>
<NOT><Rule require="EMAIL"/></NOT>
<NOT><Rule require="EXPIRATIONDATE"/></NOT>
<NOT><Rule require="FAMILYNAME"/></NOT>
<NOT><Rule require="FISCALNUMBER"/></NOT>
<NOT><Rule require="GENDER"/></NOT>
<NOT><Rule require="IDCARD"/></NOT>
<NOT><Rule require="IVACODE"/></NOT>
<NOT><Rule require="MOBILEPHONE"/></NOT>
<NOT><Rule require="REGISTEREDOFFICE"/></NOT>
<NOT><Rule require="SPIDCODE"/></NOT>
</AND>
</AND>
</OR>
</AND>
</Handler>Furthermore, ACS_* variables are used to generate SessionInitiator elements.
The environment variables of the example will generate the following configuration
(nested in the resulting /etc/shibboleth/shibboleth2.xml)
<!-- SessionInitiator for AttributeConsumingService 0 -->
<SessionInitiator type="SAML2"
Location="/Login0"
isDefault="true"
entityID="https://sp.example.com"
outgoingBinding="urn:oasis:names:tc:SAML:profiles:SSO:request-init"
isPassive="false"
signing="true">
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Version="2.0" ID="placeholder0.example.com" IssueInstant="1970-01-01T00:00:00Z"
AttributeConsumingServiceIndex="0" ForceAuthn="true">
<saml:Issuer
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
NameQualifier="https://sp.example.com">
https://sp.example.com
</saml:Issuer>
<samlp:NameIDPolicy
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
/>
</samlp:AuthnRequest>
</SessionInitiator>
<!-- SessionInitiator for AttributeConsumingService 27 -->
<SessionInitiator type="SAML2"
Location="/Login27"
isDefault="true"
entityID="https://sp.example.com"
outgoingBinding="urn:oasis:names:tc:SAML:profiles:SSO:request-init"
isPassive="false"
signing="true">
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Version="2.0" ID="placeholder27.example.com" IssueInstant="1970-01-01T00:00:00Z"
AttributeConsumingServiceIndex="27" ForceAuthn="true">
<saml:Issuer
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
NameQualifier="https://sp.example.com">
https://sp.example.com
</saml:Issuer>
<samlp:NameIDPolicy
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
/>
</samlp:AuthnRequest>
</SessionInitiator>With this mechanism, you can dynamically specify the AttributeConsumingService by using the URLs /iam/Login0, /iam/Login27 and so on. For instance
https://sp.example.com/iam/Login0?target=https://sp.example.com/login&entityID=https://idp.spid.gov.it
^^^^^^