IoT Geräte mit OIDC individuell authentifizieren
- von Nicolai Mainiero
Nicolai Mainiero, Softwarearchitekt bei sidion
Jedes IoT Gerät, sei es nun ein Sensor oder ein FireTV Stick, benötigt einen Server mit dem es Daten austauschen kann. Und da nicht jedes beliebige Gerät Informationen mit dem Server austauschen soll, benötigt es eine Möglichkeit sich beim Server zu authentifizieren. Bei manchen Geräten kann man die Zugangsdaten bereits bei der Auslieferung fest hinterlegen, da sie vom Endbenutzer nicht mehr weiter konfiguriert werden müssen. Bei anderen Geräten ist allerdings eine individuelle Kennung bzw. Benutzeraccount notwendig. Am Beispiel einer Status-LED, die die presence information eines MS Teams Benutzers visualisiert, also seine Verfügbarkeit und Aktivität repräsentiert, soll gezeigt werden wie sich das mit OIDC realisieren lässt. Dann können die anderen Haushaltsmitglieder direkt sehen, ob Mama gerade in einem Meeting ist und nicht gestört werden darf.
MS Teams presence information
Microsoft bietet mit der Graph REST API eine Schnittstelle, über die viele verschiedene Dienste der Microsoft 365 Plattform angesprochen werden können. Neben den E-Mails, dem Kalender oder Notizen aus OneNote kann auch auf den Präsenz Status von MS Teams zugegriffen werden. Eine Anfrage an den entsprechenden Endpunkt GET /me/presence
liefert dann einen Status in folgender Form:
{
"id":"string",
"availability":"string",
"activity":"string"
}
Mögliche Werte der Antwort sind in folgender Tabelle zusammengefasst:
Property | Typ | Beschreibung |
---|---|---|
id | string | Die id des Benuzters |
availability | string | Die Basispräsenzinformationen für einen Benutzer. Mögliche Werte sind Available , AvailableIdle , Away , BeRightBack , Busy , BusyIdle , DoNotDisturb , Offline , PresenceUnknown |
activity | string | Die zusätzlichen Informationen zur Verfügbarkeit eines Benutzers. Mögliche Werte sind Available , Away , BeRightBack , Busy , DoNotDisturb , InACall , InAConferenceCall , Inactive , InAMeeting , Offline , OffWork , OutOfOffice , PresenceUnknown , Presenting , UrgentInterruptionsOnly |
Für die Status-LED mit Hilfe eines ESP8266 werden allerdings nur ein Teil der möglichen Kombinationen ausgewertet.
Hardware
Die Status-LED wird wir bereits erwähnt von einem ESP8266 (z.B. WeMos D1 mini) gesteuert. Der Einfachheit halber wurde auf ein Entwicklungsboard zurückgegriffen, dass alle digitalen Ein-/Ausgänge zugänglich macht und auch einen USB-Port anbietet, über den der Mikrocontroller programmiert werden kann. Zusätzlich kommt ein Band mit WS2812B LEDs zum Einsatz. Diese LEDs haben einen zusätzlichen IC, der es ermöglicht die LEDs individuell anzusteuern.
Der Mikrocontroller kann dann mit Hilfe der Arduino IDE [^1] programmiert werden.
Eingeschränkte Eingabemöglichkeit
Um die Graph API von Microsoft nutzen zu können muss sich der Mikrocontroller authentifizieren. Klar ist, dass es keine Option ist Benutzername und Passwort im Quellcode zu speichern. Leider haben die IoT Geräte auch oft keine oder nur sehr beschränkte Eingabemöglichkeiten, die die Eingabe eines sicheren Passworts mit Sonderzeichen und Zahlen sehr umständlich macht. In solchen Fällen kann auf den OAuth 2.0 Device Authorization Grant [^2] zurückgegriffen werden, der genau für diesen Zweck, Geräte ohne Browser oder mit limitieren Eingabemöglichkeiten, definiert worden ist.
Folgendes Diagramm beschreibt den Ablauf des device code flows.
Gestartet wird der Ablauf durch folgenden HTTP Request.
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e&scope=user.read%20openid%20profile
Die client_id
ist die Applikation ID die man sich im Azure Portal – App registrations für die Anwendung erzeugt hat. Siehe hierzu auch die Dokumentation der Microsoft identity platform [^3]. Ein erfolgreicher Request unter anderem mit folgenden Informationen beantwortet: user_code
und verification_uri
. Die verification_uri
und der user_code
werden nun dem Anwender präsentiert. Zum Beispiel in dem die URL durch ein QR Code neben dem user_code
auf einem OLED Display angezeigt wird. Alternativ kann man auch einen Webserver auf dem Mikrocontroller starten, der diese beiden Informationen dann als Webseite ausliefert.
Mit diesen beiden Informationen kann sich der Benutzer nun an einem Handy oder Desktop-PC einloggen und dem IoT Gerät den Zugriff auf seinen Account gewähren. Währenddessen ruft der Mikrocontroller den /token
Endpunkt wiederholt mit dem device_code
auf, der aus dem ersten POST Request bekannt ist.
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:device_code
&client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&device_code=GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...
Sobald sich der Anwender erfolgreich angemeldet und die Freigabe für das IoT Gerät erteilt hat, ist der /token
Request erfolgreich und enthält die für OAuth2 typischen Informationen:
{
"token_type": "Bearer",
"scope": "User.Read profile openid email",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
Mit accces_token
und refresh_token
kann jetzt die Graph REST API aufgerufen werden um die presence information abzurufen und die LED je nach Status zu aktualisieren.
FAZIT
Der Device Authorization Grant ist eine zuverlässige Möglichkeit Geräte ohne eigenen Browser oder mit eingeschränkten Eingabemöglichkeit dennoch via OAuth2 zu authentifizieren. Für die Darstellung des user_code
und der verification_url
gibt es verschiedene Möglichkeiten. Von einem kleinen OLED Display, über einen eingebauten Webserver oder sogar die Anzeige auf einem Fernseher via HDMI.
Mit der presence information der Graph REST API von Microsoft 365 kann man praktisch den aktuellen Status des Anwenders abfragen und mit Hilfe des LED-Bands ansprechend visualisieren.
Ein vollständiges Beispiel findet sich unter [^5]
[^1]: Arduino IDE [^2]: OAuth 2.0 Device Authorization Grant [^3]: Microsoft identity platform documentation [^4]: OAuth 2.0 device authorization grant flow [^5]: Example