Description
In the Mendix Cloud, you can use
TLS client certificate verification to ensure that end-users can only access your app, or specific parts of it, if they provide a client certificate that is signed by a specific root or intermediate certificate authorities.
This mechanism does not verify whether the client certificate presented by the end-user is linked to the user entity in the app. To increase security, you can add this verification using the Mendix Cloud Client Certificate Verification Module.
Typical Usage Scenario
The Mendix Cloud Client Certificate Verification module uses
request headers inserted by the Mendix Cloud to verify whether the certificate provided by the end-user is registered, linked to the user entity in the app, and allowed to be used. The end-user is only allowed to continue if all those requirements are met. If one of these requirements is not met, the request is blocked.
Features and Limitations
The module provides logic to verify the client certificate of an end-user for several request types:
- Client requests coming from the browser to the Mendix app
- Although the the module will most likely work correctly with native mobile logins, the module has not been designed or tested to work with native mobile apps
- REST requests made to a published REST service
- OData requests made to a published OData service
- Web service requests made to a published web service
For other type of requests, such as to custom Java request handlers, you can easily reuse and customize the existing logic for other request types.
The module assumes that every end-user provides their own client certificate.
The module assumes that end-users are authenticating to the Mendix app using a user name and password. It does not apply verification if end-users are authenticating using the SAML, OIDC, or LDAP SSO modules.
The module uses
request headers inserted by the Mendix Cloud to verify the certificate provided by the end-user, so it will not work outside of the Mendix Cloud. However, you can use it to provide insights into how you could verify client certificates when running outside of the Mendix Cloud.
Dependencies
To use the module, your app must fulfill the following criteria:
Implementation
To add the Mendix Cloud Client Certificate Verification Module to your app, perform the following steps:
- Import the Mendix Cloud Client Certificate Verification Module into your app.
- Add the Administrator module role of the Mendix Cloud Client Certificate Verification Module to a user role in your app, if needed. End-users with a user role including the Administrator module role are allowed to view, add, edit and delete registered client certificates through the UI.
- Add the RestUser module role of the Mendix Cloud Client Certificate Verification Module to a user role in your app, if needed. End-users with a user role including the RestUser module role are allowed to view, add and update registered client certificates through the REST APIs.
- Add the ClientCertificate_Overview page to the navigation of your app, if needed. End-users with the Administrator module role can view, add, edit and delete registered client certificates through this page.
- Add the appropriate verification microflows to your app. See Verification, below.
- Configure your app to recognize which end-users are verified and which client certificates they are using. See Configuration, below.
Verification
The Mendix Cloud Client Certificate Verification module provides a number of microflows which verify the client certificate provided by the client and, where necessary, do the regular login checks for basic authentication (for example, does the user exist, are they blocked, are they active, is their password correct, should the end-user be blocked on too many failed attempts).
If the client certificate is verified, the end-user is allowed to access the app.
The different options are described below:
Verifying a Certificate for Client Requests Made from the Browser to the Mendix App
If you want to verify an end-user’s client certificate every time they sign in to your app from the browser, you can enable the custom login action provided by this module. Add the
ASU_AfterStartup_ReplaceLoginAction microflow (in the
USE_ME folder) to
the after startup microflow in the app settings of your app to enable the custom login action.
If the end-user is not authenticated or the certificate is not verified, they will not be allowed to log in, and will receive a message telling them they can’t sign in (for security reasons, the message does not explicitly mention this is because of a failed client certificate verification).
Verifying a Certificate for REST or OData Requests Made to a Published Service
If you want to verify an end-user’s client certificate when they make a REST or OData request, you can choose one of two options:
- Verify the end-user’s client certificate in a custom authentication microflow — the preferred method
- Verify the end-user’s client certificate in the REST or OData operation microflow
Verifying a Certificate in a Custom Authentication Microflow
If the end-user is not authenticated or the certificate is not verified, they will not be allowed to use the REST operation and will receive a 401 Unauthorized response.
Verifying a Certificate in the REST or OData Operation Microflow
You can verify the end-user’s certificate in
a published REST operation’s microflow by adding the
ClientCertificate_CheckClientCertificateAllowed_ForREST_OData microflow (in the
USE_ME folder) as a microflow action at the start of every published REST/OData operation microflow of each published REST/OData service. This microflow is also exposed as microflow action
Check Client Certificate For Published REST or OData service (under the
Client Certificates category) in
the toolbox.
A disadvantage of this method is that you must do this for every published REST/Odata operation of every published REST/OData service. This is why adding the custom authentication microflow to each service is preferred.
The advantage of this method is that no checks on authentication are needed, as authentication has already been done. Only the end-user’s certificate will be verified. This makes it suitable for use where authentication to the REST or OData operation is through SAML, OIDC, or LDAP SSO.
If the certificate is not verified, the end-user will not be allowed to use the REST operation, and will receive a 401 Unauthorized response.
Verify an End-User’s Client Certificate for Web Service Requests Made to a Published Web Service
You can verify the end-user’s certificate in
a published web service operation’s microflow by adding the
ClientCertificate_CheckClientCertificateAllowed_ForSOAP microflow (in the
USE_ME folder) as a microflow action at the start of every published web service operation microflow for each published web service. This microflow is also exposed as microflow action
Check Client Certificate For Published Web Service (under the
Client Certificates category) in
the toolbox.
You must add the verification to every published web service operation microflow, as the HTTP request and its headers (used in the verification) are not available in a custom authentication microflow for a published web service.
There are no checks on the (basic) authentication, as authentication has already been done. Only the end-user’s certificate will be verified.
If the certificate is not verified, the end-user will not be be allowed to use the web service operation, and will receive a 401 Unauthorized response.
Configuration
Once the module is implemented and verification has been added where needed, end-users can only use the parts of your app that have verification, when they use a client certificate that is registered in the module, associated with the end-user, and allowed to be used.
This means that client certificates must be registered in the module before they can be used.
The module provides three ways to register and update certificates:
- End-users with the Administrator module role can add and update registered client certificates via the UI.
- End-users with the RestUser module role can add and update registered client certificates via the REST API. For more information, see REST Operations, below.
- You can enable auto-update, to automatically register certificates and associate them with the end-user. See Auto-update, below.
Adding a New Registered Certificate for an End-User Using the UI
To add a new registered certificate for an end-user using the UI, follow these steps:
- Sign into your app with the Administrator role.
- In your app, open the ClientCertificate_Overview page.
- Click the New button.
- Provide the following information:
- User - The end-user the client certificate will be associated to
- Serial (string) - The serial number of the client certificate
- Thumbprint (string) - The thumbprint of the client certificate
- Allowed (boolean) - This indicates whether the new client certificate can be used by the end-user (true) or not (false).
- Click Save to store the new client certificate. If you are adding a certificate with Allowed set to true , click Proceed to allow the use of this client certificate or click Cancel to leave the certificate marked as no allowed. This verification is added to prevent an administrator allowing a certificate by accident.
- If you are adding a certificate with Allowed set to true for an end-user who has other certificates active, click Yes to block all other certificates for the same end-user, making this certificate the only certificate they can use. Click No to skip this step; this might result in multiple certificates being allowed for a single end-user.
Updating an Existing Registered Client Certificate Using the UI
To update an existing registered client certificate using the UI, follow these steps:
- Sign into your app with the Administrator role.
- In your app, open the ClientCertificate_Overview page.
- Select the certificate that you want to update.
- Click the Edit button.
- For the Allowed (boolean) parameter, select one of the following values:
- True - The new client certificate can be used by the end-user
- False - The certificate cannot be used
- Click Save.
- If you are assigning a certificate where Allowed is currently set to false and you are now allowing it, click Proceed to allow the use of this client certificate or click Cancel to leave the certificate marked as no allowed. This verification is added to prevent an administrator allowing a certificate by accident.
- If you are allowing a certificate for an end-user who has other certificates active, click Yes to block all other certificates for the same end-user, making this certificate the only certificate they can use. Click No to skip this step; this might result in multiple certificates being allowed for a single end-user.
Constants
The module has a number of constants. The following constant should be configured:
- AutoUpdateClientCertificateForUser. Enables auto-update ( when set to true) or not (when set to false ). See Auto-update, below for more information. Default value: false.
The following constants should not require a change:
- HttpHeaderAuthorization: key of the HTTP header containing the credentials for basic authentication. Default value: Authorization.
- HttpHeaderKeyClientCertificateSerial: key of the HTTP header containing the serial number of the client certificate. Default value: Ssl-Client-Serial.
- HttpHeaderKeyClientCertificateThumbprint: key of the HTTP header containing the thumbprint of the client certificate. Default value: Ssl-Client-Fingerprint.
- LogNodeName: the name of the log node used to log messages. Default value: MendixCloudClientCertificateVerificationModule.
Auto-update
By default, end-users can only use client certificates that have been registered in the module. If an end-user provides a client certificate that is not registered, their connection will be blocked. This means that you would have to add and update all client certificates manually, or via the REST API, to make sure that the correct client certificate is used and allowed for every user.
As an alternative, you can enable the auto-update feature. This means that the module will automatically register any new client certificate provided by an end-user. It will also block all other client certificates for that end-user.
You can enable the auto-update feature by setting the
AutoUpdateClientCertificateForUser constant to true. See also
Constants above.
For example, end-user X signs in to your app for the first time with certificate 1. If the auto-update feature is disabled (default) the end-user will only be allowed to access the app if client certificate 1 is registered in the module for this user. This means you have to register this client certificate (either via the UI or the API) before the end-user can use it.
If the auto-update feature is enabled, the client certificate will be registered for this user automatically. This means that the end-user can use the client certificate immediately, without having to register the client certificate first.
If the end-user subsequently signs in with certificate 2, the auto-update feature will automatically register this new certificate for the user and block the old certificate. This means that the end-user can no longer user certificate 1. If they do provide certificate 1, their access will be blocked as certificate 1 is no longer allowed.
REST Operations
To allow the management of registered client certificates to be automated, the module includes several REST operations.
Listing All Registered Client Certificates
To get a list of all registered client certificates, you can make a GET request to {app-url}/rest/clientcertificatesmodule/v1/client_certificates. This will return a list of all registered client certificates. Optionally, you can provide the query parameter only_allowed with the value true (for example: {app-url}/rest/clientcertificatesmodule/v1/client_certificates?only_allowed=true) to retrieve only the client certificates that are currently allowed to be used.
Response:
[ { "allowed": true, "serial": "01", "thumbprint": "ABC", "user": { "name": "user1" } } ]
Get a Specific Client Certificate
To get a specific registered client certificate, you can make a GET request to {app-url}/rest/clientcertificatesmodule/v1/client_certificates/{client_certificate_thumbprint}. This will return the registered client certificate.
If no certificate can be found with the provided thumbprint, the REST operation will return a 404 Not Found response.
Response:
{ "allowed": true, "serial": "01", "thumbprint": "ABC", "user": { "name": "user1" } }
Listing all Registered Client Certificates for a User
To get a list of all registered client certificates for a specific user, you can make a GET request to {app-url}/rest/clientcertificatesmodule/v1/users/{username}/client_certificates. This will return a list of all client certificates registered for the user.
Optionally, you can provide the query parameter only_allowed with the value true to retrieve only the client certificates that are currently allowed to be used.
If no user can be found with the provided user name, the REST operation will return a 404 Not Found response.
Response:
[ { "allowed": true, "serial": "01", "thumbprint": "ABC", "user": { "name": "user1" } } ]
For security reasons, the module does not expose a REST operation to retrieve all user names.
Adding a New Registered Client Certificate for a User
To register a new client certificate for a user, you can make a POST request to {app-url}/rest/clientcertificatesmodule/v1/users/{username}/client_certificates. The client certificate will be added and associated with the user with the provided user name.
The REST operation expects a JSON object in the body with the following parameters:
- Allowed (boolean) - Indicates whether the new client certificate can be used by the user (true) or not (false)
- Serial (string) - The serial number of the client certificate
- Thumbprint (string) - The thumbprint of the client certificate
Optionally, you can provide the query parameter block_existing_certificates with the value true to automatically block all registered client certificates of the user, except for the new one, making that one the only client certificate that can be used by the end-user.
If no user can be found with the provided user name, the REST operation will return a 404 Not Found response.
If the client certificate already exists, the REST operation will return a 422 Unprocessable Entity response.
Request:
{ "allowed": true, "serial": "01", "thumbprint": "ABC" }
Response:
{ "allowed": true, "serial": "01", "thumbprint": "ABC", "user": { "name": "string" } }
Updating an Existing Registered Client Certificate
To update the allowed attribute of a registered client certificate, you can make a PATCH request to {app-url}/rest/clientcertificatesmodule/v1/client_certificates/{client_certificate_thumbprint}. This will return the registered client certificate.
The REST operation expects a JSON object in the body with the following parameters:
- allowed (boolean): indicates whether the new client certificate can be used by the end-user (true) or not (false).
Optionally, you can provide the query parameter block_existing_certificates with the value true to automatically block all registered client certificates of the user the client certificate is associated with, making the certificate the only certificate than can be used by the end-user.
If no certificate can be found with the provided thumbprint, the REST operation will return a 404 Not Found response.
Request:
{ "allowed": true }
Response:
{ "allowed": true, "serial": "01", "thumbprint": "ABC", "user": { "name": "user1" } }
Troubleshooting
Set the log level of the
MendixCloudClientCertificateVerificationModule to DEBUG to get more detailed information on how each client certificate is processed and why a specific client certificate is (not) accepted.
Known issues
None