Pre-requisites
If you haven't configured your Keycloak instance, check our other articles:
- Set up Keycloak to manage your users and their access to tools and platforms
- Use Keycloak as both Identity Broker using Keycloak as Identity Provider - Based on Keycloak Quay.io v22.0.5 (check the Identity Broker Keycloak instance setup)
In order to set up Keycloak as an Identity Broker for SSO using the Redmine OpenID plugin, you will need:
- SSH access to the plugin folder for your Redmine instance
- Be able to either upload files or pull files from a Git repository to that plugin directory
- Have Administrator level access to your Redmine instance
- Have Administrator level access to your Keycloak instance
Useful ressources:
- Keycloak Docker repository: Keycloak Docker Official Image
- Redmine Docker repository: Redmine Docker Official Image
- Redmine plugin repository: Redmine Openid Connect plugin
The setup will be done using Keycloak v22 and Redmine v5.0.5 using official and un-modified Docker images but the plugin configuration can also be done on non-container based instances.
Set up the plugin on the Redmine host server
Connect through your SSH client to your Redmine host and install the plugin
cd /YOUR_REDMINE_PLUGIN_DIR/
sudo git clone https://github.com/devopskube/redmine_openid_connect.git
My Redmine setup only requires that I restart the container (check the Redmine setup article to know more).
If you are not using a container-based Redmine instance, install the plugin the usual way.
cd /YOUR_REDMINE_DIR
bundle install
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
rake redmine:plugins RAILS_ENV=production
sudo touch /opt/redmine/tmp/restart.txt
Then log into your Redmine using Administrator access and make sure the plugin is visible in the /admin/plugins page:
Configure Keycloak
For this example we have set up a Keycloak instance :
Parameter | Value |
---|---|
Redmine base URL | https://redmine.nicksopenworld.com |
Keycloak base URL | https://broker.nicksopenworld.com |
REALM | nicksopenworld |
Get the OpenID endpoint information
Retrieve the OpenID Endpoint Configuration information for the Realm:
Create a dedicated OpenID client
Connect to your Keycloak platform as Administrator, go to the client management menu of your REALM and create a new client:
Client type | OpenID Connect |
---|---|
Client ID | Value of your choice. For our example: redmineopenid |
Name | Optional. Value of your choice. For our example: RedmineOpenID |
Description | Optional. Value of your choice. For our example: empty |
Always display in UI | Allows the client to be visible for guest users. For our example: Off |
On the next page:
Parameter | Value |
---|---|
Client authentication | Default is Off which creates a public client. We will need to get client secret which means the client must be confidential. For our example: On |
Authorization | Optional. Enable/Disable fine grain management. For our example: Off |
Authentication flow | Defines authentication methods supported. For our example: standard flow & Direct access grants |
On the last page:
Parameter | Value |
---|---|
Root URL | https://redmine.nicksopenworld.com |
Home URL | Optional. Default URL to use to redirect/return to the client. For our example: empty |
Valid redirect URIs | Optional. Authorized URI patterns in the authentication process. For our example: empty |
Valid post logout redirect URIs | Optional. Authorized URI patterns for redirection post logout. For our example: empty |
Web origins | Optional. Allows filtering of authentication request sources. For our example: empty |
The fields can be updated at any time should you wish to to some security hardening later on.
Configure the created OpenID client
Get the Client secret
Go to the Credentials tab to visualise and save the Client secret value for later:
Client Role creation
Redmine Administrator management
The Redmine OpenID plugin allows user authentication and, if needed, creation as either Administrator or standard user in Redmine.
This is done by defining a Role value that will be assigned to users.
For this example, we will set Admin as client Role.
No attribute or any further configuration required.
User filtering
The Redmine OpenID plugin has a filtering system available that can be user when you have multiple different teams in your organisation accessing tools through the same authentication tool.
We can set up one or multiple roles in the Redmine OpenID client that will serve as filter: if filtering is enabled and a user doesn't have any of the authorized roles assigned to him, then SSO will be disabled to him.
For our example, Dev and Support roles have been set up.
Client scopes & Mappers
If you want to push specific data to your platform, you can set up built-in mappers or create your own:
In older versions of Keycloak, you needed to manually add the values.
In version 22, as long as setting Full scope alllowed is set:
If you are using an older version of Keycloak or any JBOSS keycloak docker image, here are the mappers required:
Name | Mapper Type | User Session Note | Token Claim Name | Claim JSON Type | Add to ID token | Add to access token | Add to userinfo |
---|---|---|---|---|---|---|---|
Client ID | User Session Note | clientId | clientId | String | On | On | On |
username | User Property | username | user_name | String | On | On | On |
given name | User Property | firstName | given_name | String | On | On | On |
User Property | String | On | On | On | |||
family name | User Property | lastName | family_name | String | On | On | On |
member_of | Group Membership | group | String | On | On | On |
Login/logout client configuration
You also have Login and Logout parameters. We will leave default values for our current setup.
Configure Redmine
Then log into your Redmine using Administrator access and go the the Redmine OpenID plugin configuration page /settings/plugin/redmine_openid_connect.
OpenID Connect Configuration | Description |
---|---|
Enabled | Allows you to enable/disable SSO using OpenID plugin without having to remove the plugin. For our example: On |
Client ID | Client ID set in your Keycloak client For our example: redmineopenid |
OpenID Connect server url | Issuer URL from the OpenID endpoints. Beware as the format depends on your authentication platform but can also depend on the version as it does for Keycloak: - v16 format: https://KEYCLOAKURL/auth/realms/REALMID Example: https://oldkeycloak.nicksopenworld.com/auth/realms/nicksopenworld - v22 format / our example: https://KEYCLOAKURL/realms/REALMID For our example: https://broker.nicksopenworld.com/realms/nicksopenworld |
Client Secret | Value taken from the Credentials tab in your Keycloak Redmine client |
OpenID Connect scopes (comma-separated) | openid |
Authorized group (blank if all users are authorized) | This is the filtering option. Note: if filtering is used, members of the Admin group must also be members of the authorized group otherwise they won't be able to log in. For our example: Support |
Admins group (members of this group are treated as admin) | For our example: Admin |
How often to retrieve openid configuration (default 1 day) | For our example: empty |
Disable Ssl Validation | For our example: Off |
Login Selector | Enable/Disable use of the redmine login page itself: if disabled, accessing the Redmine login page will automatically send you to the Keycloak authentication page. This means that if you have other authentication methods on Redmine's login page such as SAML SSO or Giltab OpenID, these would no longer be accessible if this parameter is disabled. For our example: On |
Create user if not exists | Allows automatic creation of users in Redmine using information pushed by Keycloak if necessary. For our example: On |
Users from the following auth sources will be required to login with SSO | Bugged & unusable feature as of version 0.9.4 (November 2023) |
!! WARNING !! .
When updating the Plugin information, I have found that some of the updates are only taken into account if you restart Redmine (either as a service or a container).
Test your setup
Connect to your Keycloak instance and create a test user:
- Set a password
- Assign it the role(s) to allows login if you want to use filtering ( "Support" client role here) or Administrator ( "Admin" client role ) to log in as Redmine Administrator
Try and log-in using the plugin using a private session of your favorite browser.
You can close the browser, update the user configuration in Keycloak and reconnect through OpenID SSO in a private session to test out all possible settings.
Debug and explore
If your tests don't give the results you're expecting, you'll have to do some debug analysis.
One way to go is to check the Redmine or Keycloak logs but in the case of OpenID exchanges, you can also check the payload using APIs.
Requirements:
- an API client (I'll be using Postman)
- a method to decode JSON Web Token . We'll be using the Jwt.io online decoder.
Configure the API call
Set up the API call with the following parameters:
OpenID Connect Configuration | Description |
---|---|
client_id | For our example: redmineopenid |
client_secret | Secret for that client. |
scope | openid |
grant_type | password |
username | Test user's username. |
password | Test user's password. |
The API response should contain an access_token which is the value that must be decoded.
Decode the access_token payload
Go to Jwt.io and paste the
Note: please use another more secure solution if the token is for a critical service.
Online ressources are useful but their security can't be garanteed.
The system will decode the token and make it readable to you so you can check the information and attributes being sent:
Conclusion
With this, you should now have a simplified way to manage your Redmine Users.
Please note that this plugin can be used on a Redmine instance on which are also installed:
- Redmine SAML: meaning you could choose SAML for Keycloak/Redmine SSO configuration
- Redmine Omniauth gitlab plugin: which is used to allow users created and managed in Gitlab to connect to Redmine. Check the Gitlab/Redmine SSO configuration for more details.