Inhalt

Ein Beispiel für einen OGC-Zugriff wäre folgende Parametrisierung der URL:

  • https://monitor.ioer.de/monitor_api
  • /user?
  • id=_F13RG& : Indikator ID
  • key=5HbHOLs7eKQmHJ8r5og2P91qr9tAviBO& : Generierter API-Key des Nutzers, welcher über die Website erstellt wurde
  • service=wcs : Gibt an, welcher OGC-Service genutzt werden soll (wfs,wcs, wms)

Alle URl und Indikatoren lassen sich auch direkt über die Tabellenansicht im Userbereich anzeigen.

Im folgenden Diagramm ist die Funktionsweise des Streaming-Dienstes dokumentiert. getService

Im ersten Schritt werden aus der URL die entsprechenden Parameter herausgefiltert. Dann wird geprüft ob der API-Key korrekt ist, indem die in der Datenbank hinterlegten- mit den angefragten Werten verglichen werden. Ist der API-Key fehlerhaft, wird eine entsprechende Fehlermeldung an den Clienten zurück geschickt. Ist der Key korrekt wird die Anfrage an den MapServer für den entsprechenden Service gestellt und der Response an den Clienten gestreamt.

route(/login)

Login

Diese Methode baut auf die Flask-Bibliothek Flask-Login auf und behandelt das einloggen des Nutzers über das entsprechende Formular. Innerhalb der Methode werden dabei nacheinander folgende Bedingungen überprüft:

  1. Stimmen Username und Passwort überein
  2. Welche Rechte hat der Nutzer → 1 für User und 2 für Admin, welche in der Datenbank unter der Tabelle users in der Spalte _access: abgelegt.

getService

route (/signup)

Registrierung

Diese Methode hat die Aufgabe die von Nutzer eingetragenen und an den HTTP-Endpoint geschickten Daten in der Datenbank zu speichern. Eine weitere Aufgabe besteht darin zu prüfen, ob der Nutzername oder die Mailadresse bereits in der Datenbank vorhanden ist, in diesem Fall wird eine entsprechende Fehlermeldung an den Clienten zurückgegeben. Stimmen alle Felder überein wird eine neue Instanz der Klasse-User erzeugt und diese in der Datenbank abgelegt. Für das Speichern in der DB wird die Bibliothek Flask-SQLAlchemy verwendet.

Ein Beispiel für das programmatische Anlegen eines neuen Nutzers ist im folgenden Beispiel aufgeführt:

new_user = User(username=username, email=email, password=hashed_password, lastname=form.lastname.data,
                firstname=form.firstname.data, facility=form.facility.data, access=1,
                business=form.business.data, confirmed=False)
db.session.add(new_user)

Wurde der Nutzer angelegt, wird eine Mail an seine angegebene Adresse geschickt, um den Account zu verifizieren. Diese Aufgabe wird von der Route Mail-Confirm übernommen.

Für den Clienten wird das Template signup.html aus dem static-Verzeichnis gerendert, über dieses erfolgt die Eingabe. Fehler werden durch Flask-Markup in das template eingefügt.

route (/confirm/token)

Diese Route ruft die Methode confirm_email(token_pass) auf, ihr muss der generierte Token übergeben werden. Hierbei wird die Email-Adresse anhand des generierten Tokens überprüft. Der Nutzer bekommt nach seiner Anmeldung eine Mail mit dem Registrierungslink, beim anklicken wird er an diesen Enpoint geleitet. Ist der Token korrekt wird in der Datenbank in der Tabelle users die Spalte confirmed auf True gesetzt. Am Schluss wird der User ausgeloggt, um sich anzumelden.

Bei einem Fehler wird die entsprechende Fehlermeldung angezeigt.

Für den Clienten wird das Template confirmed_mail.html aus dem static-Verzeichnis gerendert.

route (/services)

Diese Route hat die Aufgabe aus dem static-Verzeichnis dem Clienten alle Services aufzulisten. Hierfür wird die service.html gerendert. Die Funktion prüft dabei ob der Nutzer angemeldet ist, um auch nur berechtigte Zugriffe zuzulassen. Ist der Nutzer nicht angemeldet, wird die login.html gerendert.

route (/reset)

Passwort zurücksetzen

uml

Diese Route hat die Aufgabe das zurücksetzen des Passwortes zu steuern. Hat der Nutzer seine Emailadresse eingegeben, wird überprüft ob dieses in der Datenbank hinterlegt ist. Trifft dies zu wird ein Token generiert und mit der Hilfe der Mailer-Klasse das Passwort an die angegebene Mailadresse geschickt. der generierte Token wird dabei mit der Hilfe der Token-Klasse erstellt und wird aus der Mailadresse generiert.

route (/reset/token)

Diese Route wird aufgerufen, wenn der Nutzer seine Mail zum zurücksetzen des Passwortes bekommen hat und den darin enthaltenen Link klickt.

Ein Beispiel Link wäre folgender:

https://monitor.ioer.de/monitor_api/reset/ImwubXVjaGFAaW9lci5kZSI.D6xN-w.Ik_GXgQuTDrleuX_Skg_YHr9K5Y

Im ersten Schritt wird der übergebene Token überprüft, ist er korrekt kann das Passwort geändert werden. Ist der Token nicht korrekt oder ausgelaufen (siehe Token)

Durch das gerenderte HTML-Dokument reset_passwort.html aus dem static bekommt der Nutzer die Möglichkeit ein neues Passwort anzugeben.

Models

Mailer

Diese Klasse übernimmt im User-Service die Aufgabe alle notwendigen Mails zu verschicken, über die Methode send_mail wird ein neues Mail-Objekt instanziiert, aus der Bibliothek Flask-Mail und an den angegebenen User (to) gesendet. Der Inhalt der Mail ist dabei innerhalb des template fest vorgegeben und befindet sich im static als reset_password_mail.html.

uml

User

Diese Klasse erbt von UserMixin und db.Model und ist das Grundgerüst eines neuen/angemeldeten Nutzers. Die Klassen-Variable confirmed gibt hierbei wieder ob dem Nutzer seine Mailadresse bestätigt ist oder nicht. Default ist Sie None. Die Klasse bildet dabei alle Felder der Datenbanktabelle user ab, in welcher alle notwendigen Informationen abgelegt sind.

uml

Methodenname Parameter Return Info
init username, password, email,lastname,firstname,facility,access,business,confirmed,confirmed_on=None Constructor :wink: Diese Methode erstellt eine neue Instanz der Klasse User, hierbei ist der Parameter confirmed_on als Default None.
is_authenticated   Boolean:state Methode welche wiedergibt, ob der Nutzer authentifiziert ist, also ob seine Mail korrekt ist
is_active   String:access gibt wieder, welche rechte der Nutzer besitzt → TODO
is_anonymous   Boolean:state zeigt an ob der Nutzer einen Anonymen Status besitzt → TODO
get_id   int:id gibt die Id des Nutzers zurück

Token

Diese Klasse regelt das Verifizieren und erstellen eines Token. Sie wird hierbei bei der Überprüfung der Mailadresse des Nutzers eingesetzt. Für die Serilizierung wurde die Bibliothek itsdangerous eingesetzt.

token

Methodenname Parameter Return Info
generate_confirmation_token() String:email String:token Methode, welche aus der übergebenen Mailadresse einen Token erstellt
confirm_token String:token, Int:expiration String:email Methode welche den Token zu der übergebenen Mail transformiert. Anhand der expiration kann festgelegt werden, wie lange der Token gültig ist. Default ist 3600

Sicherheit

In diesem Kapitel wird der Punkt Sicherheit der API-Dokumentiert, hierbei wurde größtenteils auf die On-Board Mittel der Flask-Library zurückgegriffen.

URL-Manipulierung

Um auch nur berechtigte Nutzer die jeweilige URL zur Verfügung zu stellen, wurde der Dekorator @login_required aus der Bibliothek Flask-Login eingesetzt. Ist der Nutzer nicht angemeldet wird er zurück auf die Anmeldeseite geleitet. Somit ist es nicht möglich unangemeldet auf die OGC-Service Seite zuzugreifen.
Anbei die Fallunterscheidung:

    if current_user.is_authenticated:
        return render_template('user/services.html', key=current_user.api_key, access=current_user.access)
    else:
       return redirect("{}login".format(Config.URL_ENDPOINT))

SQL-Injektion

SQL-Injection (dt. SQL-Einschleusung) bezeichnet das Ausnutzen einer Sicherheitslücke in Zusammenhang mit SQL-Datenbanken, die durch mangelnde Maskierung oder Überprüfung von Metazeichen in Benutzereingaben entsteht. Wikipedia

Dies kann beispielsweise auftreten wenn Passwort und Username von der Datenbank abgefragt werden und dabei der Template String für den Username so manipuliert wird, das immer True zurückgegeben wird. In der Anwendung wurde die Bibliothek Flask-SQLAlchemy eingesetzt. Welche die entsprechenden Nutzer herausfiltert.
Am Besipiel wurde die Email übergeben und der Nutzer aus der DB authentifiziert.

user = User.query.filter_by(email=email).first()