A simple IIIF-Image API server with IIIF-Auth API support.
This Docker setup provides:
- digilib image server
- or IIPImage image server built with OpenJPEG for JPEG2000 image support
- Flask authentication web application using Flask-Admin and Flask-Security
- Nginx proxy connecting the image and the authentication server
Images from the configured image folder (IMAGE_DIR) are served at the IIIF Image API endpoint
http://your.server/iiif/images/ and IIIF Presentation API manifests at http://your.server/iiif/manifests/
(digilib uses "!" as path separator so your directory mydir/mysubdir becomes
http://your.server/iiif/manifests/mydir!mysubdir).
The authentication server user management frontend can be reached at
http://your.server/auth/admin/ (initial user: AUTH_ADMIN_USERID, AUTH_ADMIN_PASSWORD).
All images are accessible for all users defined in the authentication server.
If you want to extend the application to implement more granular permissions
look at validate() in auth/app.py.
You need Docker and docker-compose.
Create a .env file by copying the sample file:
cp .env.template .env
Edit .env and put your host name in VIRTUAL_HOST and the image
directory on your host in IMAGE_DIR.
Add secrets (random strings) to AUTH_SECRET_KEY and AUTH_PASSWORD_SALT and user
credentials for the initial admin user in AUTH_ADMIN_USERID and AUTH_ADMIN_PASSWORD.
Enter a database connection in AUTH_DB_CONNECTION (e.g. a sqlite file inside the container).
Add LETSENCRYPT_EMAIL for the letsencrypt-proxy-companion.
docker-compose up -d
Starts the image and auth server and proxy at port 80 and 443.
The letsencrypt-proxy-companion automatically downloads letsencrypt SSL certificates.
If you like to use iipsrv instead of digilib run:
docker-compose -f docker-compose-iipsrv.yml up -d
With iipsrv you need to supply your own manifests in a directory that you set in MANIFEST_DIR.
Authorization for image (and manifest) requests relies on the Nginx http_auth_request module configured in the files proxy/vhost.d/default and proxy/vhost.d/default_location.
For every request by the client to the proxy the proxy makes another request (without body)
to the query_auth endpoint in the auth application and forwards the clients original
request only if the auth application returns a 200 result code.
The query_auth endpoint checks the clients credentials provided either as a session cookie
of a Flask-Login session or a token in the Authorization header.
When the client does not provide the necessary credentials the query_auth endpoint returns a
401 error code. In this case the proxy sends a response with a 401 status code to the client
including a preconfigured manifest or image info document as the message body.
The document includes ULRs for the Access Cookie Service and Access Token Service service
endpoints as required by the IIIF-Auth specification.
The Access Cookie Service is implemented by the /iiif-login endpoint. It is supposed to be
opened in a separate tab by the IIIF client. It will provide a login form if the user is
not already logged in and try to close the window after a successful login. This interaction
will set a session cookie for the content domain.
The Access Token Service is implemented by the /iiif-token endpoint. It is supposed to
be opened in an iframe with a PostMessage handler by the IIIF client. It returns a token
if the request had a session cookie and an error code otherwise.
To prevent the letsencrypt-proxy-companion from trying to fetch certificates you can disable the service
by creating a file docker-compose.override.yml with the contents:
version: '3'
services:
certbot:
image: tianon/true
restart: "no"
The Flask auth app heavily borrowed from sasaporta/flask-security-admin-example and the flask-admin/flask-admin examples.