This repository contains the code of the backend used by the web and mobile applications of the Digital citizenship project.
This is the backend that supports the italia-app mobile application.
This project is part of the Italian Digital Citizenship initiative, see the main repository for further information.
The italia-app
application will authenticate to the backend in two steps:
- an initial user initiated SPID authentication process (SAML2 based) that identifies the user and, on success, triggers the creation of a new authentication session (associated to a session token)
- subsequent requests to the backend will be authenticated via a bearer session token
When a client (the mobile app or a browser) wants to login with the backend it will call the /login
endpoint with the
IDP entityID as parameter in the query string. The backend will then builds an authorization URL and performs a redirect
to the chosen IDP. The authentication process will continue to the IDP website. If the authentication process ends with
success the IDP will redirect the client to an HTML page with a form that will auto-post itself to the
/assertionConsumerService
endpoint with a SAMLResponse as an hidden field. The backend will parse and validate the
SAMLResponse to extract all the user attributes (fiscal code, first name, last name, email), then it will generates an
unique alphanumeric string as token and saves an User object to the SessionStorage
service using the token as key.
Finally the backend will redirect the client to the value of the environment variable CLIENT_REDIRECTION_URL
with the
token in the query string. The client must saves the token and use it in all API request.
The code that manage this flow are in the spid-passport
package (more info
here), and in the src/strategies/spidStrategy.js
and
src/controllers/authenticationController.js
files.
All API requests sent by the client to the backend must have an Authorization: Bearer
header with the value of the
token obtained from the SPID authentication process. The token is used to retrieve the User object from the
SessionStorage
service.
The code that manage this flow are in the src/strategies/bearerTokenStrategy.js
file.
- Docker and Docker Compose
To fully simulate the SPID authentication process we use the images provided by spid-testenv-backoffice and spid-testenv-identityserver projects.
A Linux/macOS environment is required at the moment.
- clone the project in a folder called
italia-backend
- go to the project's folder
- run
scripts/build-tools.sh
to build thetools
Docker image - run
scripts/yarn.sh
to install backend dependencies - run
scripts/generate-proxy-api-models.sh
to generate the models defined in api_proxy.yaml and api_notifications.yaml - run
scripts/generate-api-client.sh
to generate the Autorest API Client - run
scripts/build.sh
to compile the Typescript files - run
docker-compose up -d
to start the containers - edit your
/etc/hosts
file by adding:
localhost spid-testenv-identityserver
localhost italia-backend
- wait a couple of minutes to let the IDP start (or monitor the process with
$ tail -f logs/idp/wso2carbon.log
) - run
scripts/import-spid-data.sh
to configure the local IDP - copy
app/.env.example
toapp/.env
and fill the variables with your values - point your browser to https://italia-backend
If you are using Docker with a Docker Machine replace localhost
with the IP of the Docker Machine
(More details here).
backend
: the backend Node application that serves the web and mobile applicationsspid-testenv-identityserver
: the test IDP serverspid-testenv-backoffice
: simple configuration interface to manage the test IDP server
Nginx is reachable at https://italia-backend:80
IDP is reachable at https://spid-testenv-identityserver:9443 (user: admin
, password: admin
)
IDP simple backoffice is reachable at https://spid-testenv-identityserver:8080
Those are all Environment variables needed by the application:
Variable name | Description | type |
---|---|---|
API_KEY | The key used to authenticate to the API backend | string |
API_URL | The API backend URL | string |
CLIENT_REDIRECTION_URL | The path where the user will be redirected after a successful SPID login | string |
CLIENT_ERROR_REDIRECTION_URL | The path where the user will be redirected when en error occurs during SPID login | string |
PORT | The HTTP port the Express server is listening to | int |
REDIS_URL | The URL of a Redis instance | string |
TOKEN_DURATION_IN_SECONDS | The number of seconds a session token is considered valid | int |
SAML_CALLBACK_URL | The absolute URL of the assertion consumer service endpoint | string |
SAML_ISSUER | The issuer id for this Service Provider | string |
SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX | The index in the attribute consumer list | int |
PRE_SHARED_KEY | The key shared with the API backend to authenticate the webhook notifications | string |
ALLOW_NOTIFY_IP_SOURCE_RANGE | The range in CIDR form of allowed IPs for the webhook notifications | string |
AZURE_NH_HUB_NAME | The hub name configured in the Azure Notification HUB | string |
AZURE_NH_ENDPOINT | The endpoint URL configured in the Azure Notification HUB | string |
Application logs are saved into the logs folder.
The setup procedure adds some test users to the test IDP server, the full list could be retrieved in
spid-batch-import/spid-users.json
. To add more users connect to https://spid-testenv-identityserver:8080 and
navigate to: service provider > Servizi registrati and click on Utenti.
A Linux/macOS environment is required at the moment.
- use
nodenv
to run the correct version of Nodejs as specified inapp/.node-version
- run Jest tests directly or with
scripts/test.sh
In general follow the Node Best Practices.
The API client is generated with the AutoRest tool, in case of API change you need to regenerate the client code:
- run the command
yarn generate:api-client
The backend implements a SAML Service Provider - for authenticating the clients
it needs a certificate that you can generate with the following command
(you need to have openssl
available in your path):
$ yarn generate:test-certs
In a world of evolutionary architecture, it's important to record certain design decisions for the benefit of future team members as well as for external oversight. Architecture Decision Records is a technique for capturing important architectural decisions along with their context and consequences. We store these details in source control, along with code, as then they can provide a record that remains in sync with the code itself.
We use ADRs to track architectural decisions of this initiative.
This repository is configured for Nat Pryce's adr-tools.
Here's the decisions we taken so far:
ADR | Title | PR (discussion) |
---|---|---|
1 | Record architecture decisions | |
2 | Backend runs on Docker on local environments | |
3 | Use OpenAPI to defined the API specs | |
4 | Use a dependency injection container |
I installed on my mac but seems that https://italia-backend:80 is not working (ping italia-backend return a host error)
Check out /etc/hosts Remember that in some cases you need to use your docker-machine ip (get it from >docker-machine ip) instead of localhost.
I followed all the steps but when i go to https://italia-backend it shows me the same as https://italia-backend:8080
This problem seems to be dependent on how Docker for Mac (doesn't) manage well the /etc/hosts file. If you install Docker Toolbox it works fine (and can coexist) (Read more at https://medium.com/@itseranga/set-hosts-in-docker-for-mac-2029276fd448)
When i run the scripts/import-spid-data.sh file, after the first entries the script display a lot of errors like
# users imported: -- Error [object Object]
Have you waited the IDP to start successfully? Wait a minute and retry.