-
Notifications
You must be signed in to change notification settings - Fork 14
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.
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.
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:
-
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)
-
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
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.
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.
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
.
- 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
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.
- Check the provided token with the
-
/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
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.
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.
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
.
A user with admin rights has now the possibility, to select between four different broker locations:
-
Local
- Mosquitto runs on the same machine as the MBP platform, no authentication is enabled.
-
Local & secured
- Mosquitto runs on the same machine as the MBP platform, but has authentication enabled.
-
Remote
- Mosquitto runs on a remote machine, no authentication is enabled.
-
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.
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.
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.
There are two ways to install the Mosquitto broker. Normal and secured.
Linux:
- Nothing to do. Just run
install.sh
as described in the README of the MBP.
Windows:
- Install Mosquitto as described in the README.
- 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
withinclude_dir
. - As default host for the plugin to send the authorization requests to is set
localhost
. - On Windows:
- Edit
auth_opt_jwt_host
inmosquitto-go-auth.conf
. Read the comments in the config file for further explanations. - Set
broker_location=LOCAL_SECURE
manually inconfig.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
- Run in mosquitto subdirectory:
- Edit
- On Linux:
- Configuration is per default setup for Linux.
- Run
sh install.sh secure
. - After installation:
config.properties
has an additional line withbroker_location=LOCAL_SECURE
- Before rerun of installation script: remove the modification of
config.properties
!
https://github.com/iegomez/mosquitto-go-auth
Currently, only devices using python scripts are supported to use the OAuth2 authentication.
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'
- When modifying Python scripts with Windows: check that End of Line Sequence is set to LF. Standard on Windows is CRLF!
Universität Stuttgart - MBP Team 🔧