Hej alla på eleg-projekt-listan!
Vi håller ju på med att ta fram en "proof-of-concept" för att kunna visa hur en fri e-legitimation kan utfädras och användas. Vi har en CA-programvara för utfäraden som kan användas för att skapa certifikat, och vi vill också kunna visa exempel på hur en "förlitande part" kan funka.
Nu finns en lite annorlunda test-sida som exempel på hur en "förlitande part" kan fungera, alltså en webbsida där det krävs ett klient-certifikat (e-leg) för att komma in på sidan och där sidan kan använda information från certifikatet (som personnummer för användaren som anslutit).
Det är en server som kör Debian GNU/Linux och använder programvarorna nginx, gunicorn och flask, på följande vis.
I nginx-konfigurationen finns då bl.a. de här raderna: --------------------------------------------------------- # Here, specify the CA certificate from the issuer ssl_client_certificate /home/elias/ca-cert/issuingca.crt.pem; ssl_verify_client on; location / { if ($ssl_client_verify != "SUCCESS") { return 401; } proxy_redirect off; proxy_set_header X-EID-CERT $ssl_client_escaped_cert; proxy_pass http://127.0.0.1:8000; } ---------------------------------------------------------
där filen issuingca.crt.pem är certifikatet för utfärdaren, som vi alltså har skapat med vår CA-programvara. Förlitande part behöver få det certifikatet från utfäraden och installera det på sin server.
Raden med "proxy_pass" betyder att man skickar vidare till applikationen som finns på port 8000 och "proxy_set_header X-EID-CERT $ssl_client_escaped_cert" betyder att klientcertifikatet skickas vidare dit i form av en header med namnet "X-EID-CERT".
Sen körs gunicorn (körs som en systemd-tjänst) som lyssnar på port 8000 och som kör en Flask-applikation såhär:
/usr/bin/gunicorn eid-flask-app:app
och själva applikationen är ett litet python-program som ser ut såhär: --------------------------------------------------------- from flask import Flask from flask import request from cryptography import x509 from cryptography.hazmat.backends import default_backend from urllib.parse import unquote
app = Flask(__name__)
@app.route('/') def hello(): cert = request.headers.get('X-EID-CERT') cert_unquoted = unquote(cert) cert_decoded = x509.load_pem_x509_certificate(bytes(cert_unquoted, 'utf-8'), default_backend()) cert_subject=cert_decoded.subject oid = x509.ObjectIdentifier("1.3.6.1.4.1.55594.1.3.121") attrs = cert_subject.get_attributes_for_oid(oid) personnummer = attrs[0].value return 'Hej! personnummer = {}\n'.format(personnummer) ---------------------------------------------------------
Python-programmet använder alltså headern 'X-EID-CERT' med klientcertifikatet som nginx skickade vidare och plockar därifrån fram personnumret som finns i ett visst fält i certifikatet. Nu gör programmet inget mer än att skriva personnumret vilket inte är så spännande, men poängen är att programmet kan implementera vilken funktionalitet man vill, programmet körs för en identifierad användare och kan göra olika saker beroende på peronnumret. Till exempel kan programmet visa information som bara just den personen ska få se, eller ge tillgång till funktioner som just den personen ska få använda.
Det verkar fungera, kan testas med curl:
$ curl --cert eid_200007777777.crt.pem --key eid.key.pem https://eid-test-2.eliasrudberg.se/ Hej! personnummer = 200007777777
Texten "Hej! personnummer = 200007777777" som visas har alltså skapats av sista raden i python-programmet.
Det går även att testa i webbläsare om användaren först lägger in sitt klientcert webbläsaren.
Filerna finns i git-repot här: https://codeberg.org/DFRI-eID/go-eid-test-ca/src/branch/main/nginx-test
Vad tror ni om det här, är den här sortens test ett vettigt sätt att visa hur en fri och öppen e-legitimation skulle kunna fungera?
/ Elias
PS Alla som vill testa är välkomna att höra av sig till mig.
PS2 Nästa möte är 2024-07-22 klockan 18