Awesome
iiif-image-auth
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.
Requirements
You need Docker and docker-compose.
Configuration
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.
Run
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
.
Implementation details
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.
Additional configuration
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"
Acknowledgements
The Flask auth app heavily borrowed from sasaporta/flask-security-admin-example and the flask-admin/flask-admin examples.