Skip to content

OAuth2 Authentication

Marvin Wohlfarth edited this page Jun 2, 2020 · 3 revisions

OAuth2 Authentication

The OAuth2 framework is used to provide data integrity and to enable secure messaging. Unauthorized devices and clients must not be able to publish or subscribe to the broker.

Backend

In the current state, the authorization and the resource server are integrated into the MBP platform. These two components could also be externalized and run as independent servers.

OAuth2 Authorization Server

The authorization server is the main component for the authorization. Currently, clients are created in-memory with hard-coded details. There are two types of clients at the moment:

  1. Devices

    • Client-ID: device-client
    • Grant Types: authorization code, refresh token
    • Scope: write
    • Access Token Validity: 300 seconds / 5 minutes
    • Refresh Token Validity: -1 / never expires
      • If the validity of refresh token needs to be set to a specific time intervall, the whole authorization process needs to be triggered again (request authorization code -> request access token with this code), when the refresh token expires. This is currently not supported as it involves the MBP frontend as well. (If a client requests a new access token using a refresh token, he will receive a new access token and a new refresh token, but the valid time of the refresh token is not reset)
  2. MBP-Platform

    • Client-ID: mpb
    • Grant Types: client credentials
    • Scope: read (MBP cannot publish on the broker, just read)
    • Access Token Validity: 600 seconds / 10 minutes

OAuth2 Resource Server

The resource server enables a granular access control for resources on the server based on properties access tokens. In the current state, the resource server does permit all kind of requests without any access control.

Security Configuration

In the security configuration for the MBP platform, access with to the API is restricted, all requests must be authenticated via basic http authentication. To enable Mosquitto to check access tokens with the backend, the following API endpoints are opened to be accessable without authentication:

  • /api/checkOauthTokenUser
  • /api/checkOauthTokenSuperuser
  • /api/checkOauthTokenAcl

A detailed description of these endpoints is given below.

RestOauthController

This class defines rest endpoints for the authentication flow with OAuth2.

  • /api/auth_code
    • This endpoint is necessary for the authorization server in case of the grant type authorization code. The authorization code is handed back to the caller via a redirect uri. The uri is defined in this controller and has a single param called code.

The Mosquitto authentication plugin requires three endpoints. Each request to these endpoints needs the access token to be set as authorization request header!

For each connection request of a client, the token, which is handed to Mosquitto, is checked back with checkOauthTokenUser and checkOauthTokenSuperuser.

For each publish or subscribe request of a client, the token is checked back with checkOauthTokenAcl.

  • /api/checkOauthTokenUser

    • Check the provided token with the /oauth/check_token endpoint of the authorization server.
    • Return 200 if the token is valid and verified, 401 otherwise.
  • /api/checkOauthTokenSuperuser

    • Check if the client, which is providing the token, has superuser access rights. In the current state, the MBP does not support a superuser.
    • Returns always 401.
  • /api/checkOauthTokenAcl

    • Check if the given token has access rights for the requested topic and access level. The auth plugin sends a request to this endpoint with the access token of the client as well as the topic id, client id, and access level it is requesting access to.
    • Four access levels:
      • 0 = NONE
      • 1 = READ
      • 2 = WRITE
      • 4 = SUBSCRIBE
    • In the current state, access for specific client ids is hardcoded in OAuth2AuthorizationService.java

MongoDB

In the initial setup of the MBP platform, three users are configured and saved to the MongoDB.

  • admin
    • Standard administration user for the frontend.
  • mbp
    • User for the MBP platform. In the background, the MBP platform is using this username and the according password to be able to retrieve an access token and connect to the Mosquitto broker.
  • device-client
    • User for all IoT devices. This username and password is used e.g. in python scripts for the basic http authentication.

MQTT Service

The MBP platform uses this Java class to connect to Mosquitto.

If a secured Mosquitto is used, the property broker_location=LOCAL_SECURE is written in config.properties.

During the startup of the MBP, the MQTT service checks for this property. If it does not exist, a normal MQTT client is created and initialized.

If a secured Mosquitto is used:

  • Create the MQTT service object.
  • Delay the initiaization for 60 seconds: the request for an access token needs to wait for the API to be available.
  • refreshOAuth2Token(): This method is scheduled to run after 60 seconds for the first time and then every 10 minutes (the time of the validity of the access token for the MBP). Every 10 minutes, a new access token for the MBP platform is requested and the MQTT service is reconnected. Otherwise, the MBP platform would not be able to read data from the Mosquitto.

IP addresses

All IP addresses for the usage in the backend are stored in application.properties. Currently, it is intended, that the whole setup runs on the same machine, so all addresses are pointing to localhost.

Frontend

Settings View

A user with admin rights has now the possibility, to select between four different broker locations:

  1. Local

    • Mosquitto runs on the same machine as the MBP platform, no authentication is enabled.
  2. Local & secured

    • Mosquitto runs on the same machine as the MBP platform, but has authentication enabled.
  3. Remote

    • Mosquitto runs on a remote machine, no authentication is enabled.
  4. Remote & secured

    • Mosquitto runs on a machine, but has authentication enabled.

The selection defines, how the MBP platform is connecting itself to the Mosquitto. If there is no authentication, the normal initialization of the MQTT service is used. If authentication is enabled, the scheduled method refreshOauth2Token() is used to initialize the MQTT service.

Extraction/ Control Operators View

When a new operator is registered, a parameter with the id device_code is automatically added. If no secured broker is used, this parameter can be removed, otherwise it should be retained.

Sensors View

After a new sensor was registered, it can be opened by clicking on it. In the deployment parameters, there is then the device_code parameter pre-filled with a six-digit code. This code was requested automatically in the background using the currently logged in client credentials and is the OAuth2 authorization code. After deploying the operator, this code will be used during the startup by the client to retrieve an access token.

Mosquitto Broker

There are two ways to install the Mosquitto broker. Normal and secured.

Normal Installation

Linux:

  • Nothing to do. Just run install.sh as described in the README of the MBP.

Windows:

  • Install Mosquitto as described in the README.

Secured Broker Installation

  • Prerequisite: Docker must be setup and configured to be used via CLI on the host environment!
  • Configuration files are located in the subdirectory /mosquitto.
  • Secured Mosquitto is build as Docker container with the plugin go-auth, which is written in go. The configuration for the plugin is placed in mosquitto-go-auth.conf.
  • This config file is included in the normal mosquitto.conf with include_dir.
  • As default host for the plugin to send the authorization requests to is set localhost.
  • On Windows:
    • Edit auth_opt_jwt_host in mosquitto-go-auth.conf. Read the comments in the config file for further explanations.
    • Set broker_location=LOCAL_SECURE manually in config.properties of MBP backend.
    • Build the secured broker manually:
      • Run in mosquitto subdirectory: docker build -t mosquitto-go-auth .
      • Run docker run -d -p 1883:1883 -p 1884:1884 mosquitto-go-auth
  • On Linux:
    • Configuration is per default setup for Linux.
    • Run sh install.sh secure.
    • After installation: config.properties has an additional line with broker_location=LOCAL_SECURE
    • Before rerun of installation script: remove the modification of config.properties!

Go-Auth-Plugin

https://github.com/iegomez/mosquitto-go-auth

Devices

Currently, only devices using python scripts are supported to use the OAuth2 authentication.

Adapter Scripts

To include authentication in a MQTT client with python, copy oauth2_token_manager.py (located in /resources/adapter-scripts/temperature_oauth to the destination of your existing script. It must be always in the same directory! Then add this file as import:

import oauth2_token_manager

Create your MQTT client:

   client = oauth2_token_manager.mqttClient(hostname, 1883, id, device_code)

For reference, please have a look into sensoradapter_temperature_stub.py

Continue using the MQTT client as usual. The OAuth2 token manager is automatically requesting access tokens and refreshing them with refresh tokens.

For usage without HTTPS, the following flag is needed in oauth2_token_manager.py:

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

Troubleshooting

  • When modifying Python scripts with Windows: check that End of Line Sequence is set to LF. Standard on Windows is CRLF!
Clone this wiki locally