Basics:

The selection of an authentication and authorization method depends on multiple factors. For example it depends on the architecture of your project. If it is a monolithic architecture or a microservice based architecture. Then it depends on the usage of the user and roles. Whether you want to use it only for your own purpose or to open your service to third parties.

Authentication:

Authentication is about identity of a user. A user has to verify that he is who he claims to be, for example by knowing a username, password pair.

HTTP Basic Authentication:

Username and password are placed inside the Authorization HTTP header. Connection has to be secured with TLS and has to be added to every request. For this you can simply use the Kong Basic Plugin or check the credentials by your own. Then you have to setup a database with users and credentials (never use plaintext storage). This means that on every incoming request, you will have to compare it with your database.

Session Authentication

Session Authentication is based on a session cookie. It contains a session id, that is matched to an unique session, that expires after some time. Most webpages use this type of authentication. For example if you have the possibility to stay logged in, a session cookie with higher lifetime, e.g. 30 days, will be generated. This will need an additional service and database, where opaque session ids get generated and stored. Then you can compare the value of a session cookie from an incoming request with your database and connect the session id to an user id.

Token Authentication

Token Authentication is based on an opaque token like the one that is in the session cookie. But it gets placed inside the Authorization header and not the cookie header. Therefore the developer can decide where to save the token. The advantage is that it can be used by platforms where cookies are not usable. The disadvantage is that the places can be less secure then a secure HTTP-only cookie, because the session storage can be accessable by malisious javascript. Some implementations only setup an endless initial token, but it is better to set an expiration to the token.

OpenID Connect

based on token authentication

  • für User Authentication
  • führt ID Token ein (JWT - JSON Web Token) -> JSON based Identity Protocols
  • beinhaltet Informationen über den User -> strukturierte, festgelegte Eigenschaften
  • hilfreich wenn UI an User angepasst werden soll
  • UserInfo endpoint: Protected resource that, when presented with an access token by the client, returns authorized information about the end user
  • Beim erstmaligen Login per OAuth z.b. per Basic Authentication wird Token generiert, der später nur noch mitgesendet wird
  • Validation des Tokens = Authentication des Users

Teilnehmer:

  • Relying Party = OAuth2 Client
  • Identity Provider = OAuth 2.0 authorization server

API Key

For a lot of web services, you have to add an api key as query parameter. This means, that mostly you have to register as an developer to get this key. With that ke you will then have the right to access some resources. The advantage is that it is very easy to use. The problem is that you cannot add an identiy to this key, like at the token or session based authentiction, because this key can be get public and then it is not really authentication as you dont know the identity of the user. With an api key you can only give permissions to use a service that does not need identity.

Result:

I would use the OpenID Connect standard, based on OAuth 2.0 to have a standardized token based authentication. Based on the requirements, the tokens can be validate without checking against an database, which makes it highly flexible.

Authorization:

Authorization is about permissions and roles. After the authentication, you will know the identity of an user, but not what he is allowed to access or not. Therefore you need to have an permission system.

  • User Authorization
  • Client Authorization

OAuth2:

With OAuth 2.0 you have to between user and client authorization.

  • ist für Client Authorization (https://oauth.net/articles/authentication/)
  • Genauer “Delegation”
  • Client z.b 3rd party app muss user credentials nicht kennen
  • wie man sich bekannt gibt (Authentication) egal (https://tools.ietf.org/html/rfc6749#section-3.1)
  • gut wenn man noch third party apps integrieren möchte, die dann als Client agieren
  • für eigene Applikationen ist dann das Frontend oder die App der Client
  • Client sagt welche Berechtigungen er haben will, z.b Facebook API App möchte Zugang zu Likes
  • OAuth authorisiert Clients nicht User -> nicht was der User machen darf oder nicht darf

Teil von OAuth:

  • Token muss bei Erhalt des Requests validiert werden - noch gültig oder abgelaufen
  • Berechtigungen überprüfen, die nötig sind für die Resource (die am Anfang durch den User authorisiert wurden)

Nicht Teil von OAuth:

  • User Authorization
  • dafür muss die User ID aus dem Token extrahiert werden (überhaupt möglich mit OAuth2 eher nicht ?)
  • danach dann Rolle des Users und benötigte Berechtigungen überprüfen
  • OpenID Connect baut auf OAuth auf, um User ID zu erweitern [1] [2]
  • Access Token kann auch JWT sein -> darin könnte eine User ID vorhanden sein, Access Token könnte einfach validiert werden
  • Problematisch für Deaktiveren von Tokens da es keine zentrale Instanz gibt wo man nachfragt
  • kann gelöst werden in dem außerhalb eine Referenz und am API Gatewaydie Referenz in einen Wert umgewandelt wird
  • dann könnte Referenz gelöscht werden

Teilnehmer:

  • Resource Owner (RO): the user
  • Client: the web or mobile app
  • Authorization Service (AS): OAuth 2.0 server
  • Resource Server (RS): where the actual service is stored

Verschiedene Flows:

  • The code flow (or web server flow) -> backend beim clien notwendig
  • Client credential flow
  • Resource owner credential flow
  • Implicit flow -> client frontend reicht aus

Ablauf:

  • The Client requests access to the Resource Server by calling the Authorization Server.
  • The Authorization Server redirects to allow the user to authenticate, which is usually performed within a browser. This is essentially signing into an authorization server, not the app. ** Authentication des User z.b. durch Basic Auth
  • The Authorization Server then validates the user credentials and provides an Access Token to client, which can be use to call the Resource Server
  • The Client then sends the Token to the Resource Server
  • The Resource Server asks the Authorization Server if the token is valid.
  • The Authorization Server validates the Token, returning relevant information to the Resource Server i.e. time till token expiration, who the token belongs too.
  • The Resource Server then provides data to the Client. In our case, the requested emails are unbarred and delivered to the client.

Username und Rolle/Rechte in DB

  • einfach User in einer DB anlegen
  • bei jedem Request nach erfolgreicher Authentication Rechte des Users mittels Usernamen abfragen
  • OpenID Connect setzt darauf auf, ID Token kann genutzt werden um DB zu checken
  • bei Microservices müsste entweder jeder request mit Basic Authentication den Usernamen übermitteln oder
  • mit Session Authentication müsste jede Session mit Usernamen verknüpft sein
  • bei API Gateway müsste nur dort Authorization überprüft werden
  • ohne API Gateway in jedem Service

  • einfach
  • beschränkt, möglich wenn z.B. nur das Frontend verwendet wird, praktisch für Monoliten

OAuth2’s User-Managed Access (UMA) Profile

  • http://www.keycloak.org/docs/3.0/authorization_services/topics/service/overview.html
  • Service als Resource Server registriert sich beim Authorization Server
  • nur möglich wenn User Authorization mit am Service (nicht mgl für Methode 2.3 da Veränderung am Service notwendig)

XACML

JSON Policy

  • siehe Ory Ladon

Ergebnis:

  • OAuth zur Client Authorization, da perfekt für 3rd party apps
  • Code Flow für 3rd party apps
  • Implicit Flow oder Resource Owner Password Credentials Flow für front end
  • User Authorization durch User - Rollen - Berechtigungen DB basierend auf OpenID Connect

Gegebenheiten:

  • mehrere Microservices
  • Kong API Gateway
  • Services sollen innerhalb des Netzwerkes einfach zu bedienen sein
  • Platform soll aber auch von extern erreichbar sein
  • Services können im nachhinein dazu kommen
  • 3rd party apps sollten möglich sein

Fragestellungen:

  1. wie am einfachsten Zugriffschutz umsetzen
  2. Was muss umgesetzt werden

Methoden in Microservice Architektur

  • verschiedene Ebenen: Aufbau (wo was machen), genutzte Techniken (OAuth, Basic Auth,..), Umsetzung (bestehende Lösungen, eigene Implementation)

Methode 1: Ohne API Gateway

  • jeder Service überprüft Zugriffsrechte (Authentication und Authorization)
  • ohne vorgeschaltetes Gateway, jeder Service wird direkt angesprochen
  • Kong Gateway müsste Access Token und JWT Token / Credentials dann an Services weiterleiten

  • jeder Microservice kann eigene Mechanismen verwenden
  • unabhängig von Kong

Methode 1.1 Auslagerung in neuen Service

Beispiel mit OAuth:

Aufwand:

  • Authorization Service für OAuth bereitstellen -> extra Service
  • Authorization Service für User bereitstellen -> extra Service
  • Datenbank mit Usern und Rollen

  • wenig redundant da ausgelagert
  • einfach umzusetzen
  • Abhängigkeit -> schlecht für Wiederverwendbarkeit des Service -> Service so anpassen, dass auch ohne Zugriffsschutz nutzbar
  • Auth Server selber aufsetzen
  • Kong wird quasi nicht genutzt

Methode 1.2: Kapselung

Beispiel mit OAuth

  • User Authentication, User Authorization und Client Authorization am Service (Kapselung)
  • jeder Service beinhaltet gesamte Zugriffslogik.
  • Service validiert Token und führt User Authentication aus und erhält Rolle des Users durch Datenbankabfrage mittels dem JWT Token
  • Zugriffsschutz muss nicht Teil des Service kann -> kann auch ohne funktionieren

Aufwand:

  • Authorization Service für OAuth bereitstellen
  • Authorization Service für User bereitstellen
  • Datenbank mit Usern und Rollen

  • keine Abhängigkeit -> gut für Wiederverwendbarkeit
  • sehr sicher -> Security in Depth
  • gegen Microservices Paradigma, je nach Definition, Zugriffslogik kann auch essentieller Teil sei
  • hoher Aufwand
  • hohe Redundanz (z.b Rollen müssen bei jedem service angelegt werden)

Methode 1.3: Auslagerung von Authentication

Beipsiel mit OAuth:

  • User Authorization am Service und Auslagerung von User Authentication
  • jeder Service macht Authorization (OAuth und User Authoriztion)
  • checkt was darf der Nutzer/die Rolle
  • User Authentication wird ausgelagert:
  • Service erhält Request mit Basic Auth Headern und überprüft Authentication über extra Service oder Validierung des ID Tokens
  • wenn bestätigt, dann Berechtigung des Users checken
  • eine Datenbasis für User, da die für alle Services gleich sind

Aufwand:

  • eigene Datenbasis für Authorization pro Service

  • eigene Rollendefinitionen pro Service einfach möglich
  • kann redundant sein

-> SEPL: alle Services haben gleiche Userbasis, alle Services haben gleiche Rollen?

Methode 2: API Gateway

  • vorgeschalteter API Gateway für alle Anfragen von außen.
  • Mehrere Gateways möglich:
  • OAuth Gateway für 3rd Party Apps
  • Web Gateway mit Session based Authentication für Websiten
  • unterteilt je nach dem ob Auth am Gateway oder am Service gemacht wird
  • weitere Unterteilung wie Methoden 1, was im Service gemacht wird oder ausgelagert wird

  • geringer Aufwand da bereits Plugin für Auth Server vorhanden

Methode 2.1: User Authentication am Gateway

Beispiel mit OAuth

  • OAuth Authorization und User Authentication am Gateway
  • Kong Gateway macht OAuth Authorization und User Authentication
  • User Authorization:
  • Weiterleitung des gesamten JWTs, des JSON vom user-info endpoint (mit user id, user role)
  • dann entweder hardcoded im service (if user_role = admin), DB Lookup mit user id oder role und checken ob berechtigung für api vorhanden
  • Entweder ausgelagert und mit gemeinsamer Datenbasis oder je Service eigene User Authorization
  • Service komplett auslagern -> dieser validiert Token und erhält Rolle oder User ID und macht DB Lookup für Berechtigungen auf API
  • DB müsste nicht User und Rollen mappen, wenn Rolle gleich im JWT
  • wenn Service nicht erreichbar wird request geblockt

  • Kong OAuth Plugin
  • Kong OpenID Connect Plugin nur Enterprise
  • Github

Aufwand:

  • OAuth Authorization -> Plugin
  • User Authentication -> entweder Plugin oder extra Service + Datenbank mit Usern, Passwörter Hashes
  • User Authorization -> extra Service + Datenbank für Rollen und Berechtigungen für APIs
  • Login Seite (Authentication) und Seite wo Berechtigung erteilt wird müssen selbst implementiert werden
  • Kong Gateway müsste User ID aus dem JWT Token oder JWT Token weiterleiten
  • besser wäre JWT für Sicherheit

  • stark auf Kong basierend
  • zwei Sicherheitsschichten: Gateway und im Service
  • eigene Rollen je Service möglich
  • Änderungen an den Services

Beispiel mit Basic Authentication

  • Basic Authentication am Gateway
  • Kong Basic Auth Plugin
  • Weiterleitung der user id an Service
  • dann User Authorization am Service

Methode 2.2 (nur mit OAuth): OAuth Authorization am Gateway

  • Kong OAuth Plugin stellt OAuth Authorization Server bereit
  • Kong Gateway leitet nur JWT Token weiter an Service
  • Service leitet Token an User Authentication und Authorization Service weiter (angenommen Services sind ausgelagert)
  • theoretisch auch unterteilbar in ausgelagerten User Authorization Service oder im Service selbst
  • bei Erstellen des Access Tokens müsste der AS auch den ID Token vom User Authentication Service mitsenden

Aufwand:

  • User Authorization -> extra Service
  • USer Authentication -> extra Service

  • Kong wird genutzt
  • Service zur User Authrorization wird ausgelagert
  • geringere Änderung an den Services
  • Plugin generiert keine ID Tokens -> Anapssung des Plugins

Methode 2.3: Authentication und Authorization am Gateway

Beispiel mit OAuth:

  • OAuth Authorization, User Authentication und User Authorization am Gateway
  • Kong Gateway macht alle Checks und blockiert gleich den Request wenn Rechte nicht vorhanden
  • wie Services anbinden?
  • Plugin 2 -> Session, Login automatisch bei erstem Service request
  • Eigenes Plugin -> jeder Request müsste Tokens beinhalten, hinter Kong
  • JWT Plugin von Kong, nicht brauchbar, da Consumer angelegt werden muss -> redundant mit Identity Provider wie Keycloak
  • Getrennt von Kong (kein Mehrwert)

  • nur eine Datenbasis mit APIs und Rollen
  • nur Kong basierend
  • keine Änderung an den Services notwendig
  • Single Point of Failure
  • keine Plugins die auch User Authorization implementieren
  • nur eine Sicherheitsschicht

Aufwand:

  • Client Authorization (OAuth) -> Plugin
  • User Authentication -> Plugin z.b von Github
  • User Authorization -> Service

Softwarelösungen:

Kong OAuth Plugin

  • bietet OAuth Authorization Server an
  • APIs /authorize und /token
  • zusätzlich notwendig: Authentication Seite (Berechtigung erteilen) und Login Seite imlementieren
  • Backend kommuniziert dann mit /authorize endpoint

  • nicht änderbar

Kong OpenID Connect Plugin 1

  • nur Enterprise Version von Kong

Kong OpenID Connect Plugin 2

  • Plugin von Nokia, um Kong zu einem Relying Party zu machen
  • zusätzlich notwendig:
  • Authorization Server für OAuth - extra Service oder Hydra oder Keycloak ?
  • implementiert nur User Authentication -> User Authorization fehlt
  • https://github.com/nokia/kong-oidc/issues/15
  • leitet dereferenzierte JWT also User Claims weiter -> schlecht für zweite sicherheitsschicht
  • single sign on, bei jedem request wird geprüft, wenn nicht authenticated, dann redirect zu AS, mit Session Cookie kann dann jeder anderer Service verwendet werden

Ory Hydra

  • OAuth and open ID server
  • verwaltete Keys, Validation
  • zusätzlich notwendig: User Management
  • ähnlich wie Kong Plugin OAuth Web App für den Consent Flow und User Management
  • User Authorization: Zusammen mit Ory Ladon um Rolen zu verwalten bzw. beinhaltet Lado bereits
  • User Managemtn nur für username und credentials -> post an ladon für rollen

Kong Basic Auth Plugin

  • User werden bei Kong angelegt
  • bei jedem Request Credentials angeben
  • Weiterleitung der User ID an den Service, wo dann auf Consumer Datenbank von Kong zugegriffen werden müsste
  • zusätzlich notwendig: Datenbank mit Rollen, Berechtigungen je API mit Verbindung zu Consumer Datenbank

Kong OpenID Connect Plugin 3

  • wie Kong OpenID Connect Plugin 2

[Keycloack]

  • vollwertiger OpenID Provder mit Login und Consent sowie User Management
  • zusätzlich notwendig: User Authoriztaion
  • Anbindung an Kong entweder mit Kong OpenID Connect Plugin 2 oder getrennt von Kong siehe oder hinter Kong
  • mit Plugin 2: OAtuh startet gleich beim Aufruf egal welcher Service
  • ohne Plugin 2 (also getrennt oder hinter Kong): jeder request muss Tokens beinhaltet sonst wird abgewiesen, Login muss explizit vorher gemacht werden

Follow up

This post tries to present a way to implement the solution 2.4.

More informationens:

  • https://nordicapis.com/how-to-control-user-identity-within-microservices/
  • https://nordicapis.com/api-security-oauth-openid-connect-depth/
  • https://auth0.com/docs/protocols/oidc
  • https://de.slideshare.net/2botech/neo-securitystack
  • https://connect2id.com/learn/openid-connect
  • https://blogs.mulesoft.com/dev/api-dev/api-security-ways-to-authenticate-and-authorize/
  • https://connect2id.com/blog/how-to-validate-an-openid-connect-id-token
  • https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
  • https://www.nginx.com/blog/authenticating-users-existing-applications-openid-connect-nginx-plus/
  • https://www.nginx.com/blog/authenticating-api-clients-jwt-nginx-plus/
  • https://blog.codecentric.de/2016/08/single-sign-mit-keycloak-als-openid-connect-provider/
  • https://ncarlier.gitbooks.io/oss-api-management/content/howto-kong_with_keycloak.html
  • https://www.us-cert.gov/bsi/articles/knowledge/principles/defense-in-depth
  • http://www.grahamlea.com/2015/07/microservices-security-questions/
  • https://sdtimes.com/securing-microservices-the-api-gateway-authentication-and-authorization/