Authentication and Authorisation
There are many ways to secure webservices. The easiest one is to use an external reverse proxy.
Since this can be tricky to set up and is limited in what it can do, FROST offers some simple auth* options.
Auth* has to happen in two places: in the HTTP package and in the MQTT package. To make things
flexible, authentication is handled by classes that implement an interface, just like the
persistence backends. The interface to be implemented is de.fraunhofer.iosb.ilt.sta.util.AuthProvider.
An example docker-compose file with basic auth set up can be found at:
docker-compose-separated-basicauth.yaml
More fine-grained authorisation rules can be configured using:
- plugins with
EntityType
validators (for example STAplus),
- plugins with
Security Wrappers
and Security Validators
(for example this Demonstrator),
- PostgreSQL Row-level security (see
persistence.transactionRole
setting).
Using Security Wrappers
and Security Validators
it is possible define in minute detail what a user is allowed to read, create, update and delete.
The rules for this can take into account what the relations are that each Entity has with other Entities, as deep as required.
Setting this up correctly is not trivial and a mistake in the authorisation may inadvertently open your data for reading or even editing.
Therefore, we strongly recommend you contact us for support if your use case requires fine-grained authorisation.
Roles
FROST-Server asks the AuthProvider if the user has the following roles:
- read:
Can the user read, both on HTTP and MQTT.
- create:
Can the user create new entities, both on HTTP and MQTT.
- update:
Can the user update entities. This is only possible over HTTP.
- delete:
Can the user delete entities. This is only possible over HTTP.
- admin:
Can the user call the DatabaseStatus script. This is only possible over HTTP.
Currently there are two auth packages included: FROST-Server.Auth.Basic
and FROST-Server.Auth.Keycloak
.
Auth settings
These are generic settings for authentication/authorisation.
- auth.provider:
The java class used to configure authentication/authorisation. Currently implemented are:
de.fraunhofer.iosb.ilt.frostserver.auth.basic.BasicAuthProvider
:
An authentication provider that user basic authentication for HTTP, and stores user information in a database.
de.fraunhofer.iosb.ilt.frostserver.auth.keycloak.KeycloakAuthProvider
:
An authentication provider that uses a keycloak server for authentication.
- auth.allowAnonymousRead:
If true, anonymous users are allowed to read (GET) data.
- auth.authenticateOnly: since 2.2.0
Let the auth module only handle authentication, not authorisation. If this is set the auth module attaches the user principal to each request, but no authoristion restrictions are applied. Use this when authorisation is handled by other components. default: false.
- auth.autoUpdateDatabase:
Automatically apply database updates.
- auth.role.read:
The role in the external authentication system that represents read (GET) access.
- auth.role.create:
The role in the external authentication system that represents create (POST) access.
- auth.role.update:
The role in the external authentication system that represents update (PUT/PATCH) access.
- auth.role.delete:
The role in the external authentication system that represents delete (DELETE) access.
- auth.role.admin:
The role in the external authentication system that represents admin (DatabaseStatus) access.
Settings for the auth provider class BasicAuthProvider
The BasicAuthProvider needs a database to store its usernames, passwords and user roles.
This database can be the same as the database used by the persistence manager, but it can also be
a different database. The database has the same structure as described in the
DataSourceRealm documentation of Tomcat
except with the table and column names in upper case, like the rest of the database.
If you let this provider create its database tables (with auth.autoUpdateDatabase) it will
create three default users:
- read:
password read
, has only role read
- write:
password write
, has roles read
, create
and update
- admin:
password admin
, has roles read
, create
, update
, delete
and admin
You should change these default users! The creation only happens at the moment you
first try to authenticate, so do an authentication attempt to have tables created.
The BasicAuthProvider has the following specific settings:
- auth.realmName:
The name of the realm that the browser displays when asking for username and password.
- auth.plainTextPassword: since 2.1.0
If true (the default), passwords are stored in plain text.
Otherwise password can use any result of the PostgreSQL crypt function,
for example with Blowfish variant 2a (recommended):
INSERT INTO "USERS" VALUES ('my_user', crypt('my_password', gen_salt('bf', 12)))
.
- auth.db.jndi.datasource:
JNDI data source name, used when running in Tomcat/Wildfly. When using JNDI only set this option. When not using JNDI all other options can be used.
- auth.db.driver:
The Database driver to use. For PostgreSQL this should be: org.postgresql.Driver
- auth.db.url:
The database connection url. Example: jdbc:postgresql://localhost:5432/sensorthings
- auth.db.username:
The username to use when connecting to the database.
- auth.db.password:
The password to use when connecting to the database.
- auth.db.conn.max:
The maximum number of database connections to use.
- auth.db.conn.idle.max:
The maximum number of idle database connections to keep open.
- auth.db.conn.idle.min:
The minimum number of idle database connections to keep open.
Settings for the auth provider class KeycloakAuthProvider
Keycloak requires a JSON config file. The contents of this file are provided by the Keycloak server.
There are three ways to pass this configuration to FROST:
- setting the content directly in the option
keycloakConfig
,
- saving the config in a file and passing the file path in the option
keycloakConfigFile
,
- or having FROST download it from the server, by setting the option
keycloakConfigUrl
and optionally keycloakConfigSecret
.
When setting roles for a user, the roles need to be set explicitly for the FROST client.
Realm roles do not automatically apply to FROST.
- auth.keycloakConfig:
The json content of the keycloak json config file.
- auth.keycloakConfigFile:
The path to the keycloak json config file.
- auth.keycloakConfigUrl:
The URL on the Keycloak server that can be used to download the Keycloak config file. Usually this url is in the form
of: https://keycloak.example.com/auth/realms/[realm]/clients-registrations/install/[client id]
- auth.keycloakConfigSecret:
If the client has “access-type” set to “confidential” then a secret is required to download the configuration.
This secret can be found in the configuration itself, in Keycloak.