-
Notifications
You must be signed in to change notification settings - Fork 23
API authentication
VIP API can be secured with either:
- A per-user API key, which can be generated or renewed manually under the "My account" page in VIP-portal. One can then authenticate with this key in the
apikeyHTTP header, using a client such as https://github.com/virtual-imaging-platform/VIP-python-client, or any other HTTP client:
MYKEY="..."
curl -X GET -H "apikey: $MYKEY" https://vip.creatis.insa-lyon.fr/rest/executions
API keys offer a simple and straightforward authentication method, but as keys are personal and constant secrets, they are also limited to executions environments where these limitations are acceptable (typically, a personal machine).
- An OIDC bearer token, obtained from a third-party Keycloak server that has been whitelisted in VIP-portal.
Bearer tokens are more suited to advanced production workflows where VIP-portal shares authentication and data with other systems. The present details how to configure OIDC bearer token authentication with VIP-portal and a Keycloak server.
VIP-portal can be configured to accept OIDC bearer tokens for API authentication, from one or several Keycloak OIDC servers:
- Set
keycloak.active=truein$HOME/.vip/vip-api.conf - Create a
$HOME/.vip/vip-oidc.jsonfile, with the URL of the Keycloak server:
{
"servers":[{
"url":"https://keycloak_server_host/realms/test"
}]
}
The full schema supported by vip-oidc.json is as follows:
-
servers(array of objects, mandatory): The list of Keycloak servers. -
servers[].url(string, mandatory): Base URL of the OIDC server. It must be unique across servers, and point to the realm name. The relevant OIDC URLs (such as jwks_uri) are then resolved using the.well-known/openid-configurationendpoint. -
servers[].use-resource-role-map(boolean, optional, default false): Whether to use therealm_access(if false) orresource_access(if true) field of the bearer token to get roles mapping. -
servers[].resource(string, mandatory ifuse-resource-role-map=true): Resource name (i.e. Keycloak client ID) to use forresource_accessroles mapping.
This section only describes a very basic Keycloak configuration, for testing purposes. It is not suited for full production. The full Keycloak documentation can be found at https://www.keycloak.org/documentation.
- Download and install a Keycloak instance, for instance on https://github.com/keycloak/keycloak/releases/.
- Start the Keycloak server:
keycloak-$version/bin/kc.sh start-dev --http-port=$port. - Create a realm.
- In the realm, create a client, and enable the "Direct access grant" authentication flow.
- In the realm, create a user.
- Make sure the user has an email, name and firstname.
- Under "Credentials", define the user password.
- Optionally, if you want to access role-restricted endpoints:
- Under "Realm roles", create the roles: "ROLE_ADMINISTRATOR", "ROLE_ADVANCED", "ROLE_SERVICE".
- Assign relevant roles to the user in the "Roles mapping" tab of user configuration.
Once both VIP-portal and Keycloak server are properly configured, the OIDC bearer token authentication to VIP API occurs as follows:
# VIP an Keycloak servers
keycloakServer="https://..."
realmName="test"
vipServer="https://..."
# User credentials, for authentication to keycloak. In production, these are typically prompted interactively.
clientId="..."
clientSecret="..."
userName="..."
userPass="..."
# Initial login to Keycloak with user credentials. In the response:
# .access_token is the initial bearer token usable for a short duration
# .refresh_token, out of scope here, allows to get more bearer tokens without prompting again for user authentication
token=$(curl -s -X POST "$keycloakServer/realms/$realmName/protocol/openid-connect/token" --data-urlencode grant_type="password" --data-urlencode client_id="$clientId" --data-urlencode client_secret="$clientSecret" --data-urlencode username="$userName" --data-urlencode password="$userPass" | jq -r .access_token)
# Call VIP API with Keycloak token:
curl -s -H "Authorization: Bearer $token" "$vipServer/rest/executions"
When processing an API request with a Authorization: Bearer $token header, VIP-portal server checks that the token has been signed by an authorized OIDC server using the following process:
- Check that the Keycloak server URL is referenced in vip-oidc.json
- Get the signing keys from Keycloak server, with two server-to-server HTTP requests (these are cached):
-
GET $keycloakServer/realms/$realmName/.well-known/openid-configurationto getjwks_uri -
GET jwks_urito get the signing keys
-
- Verify the token signature with the obtained keys
- For role-restricted endpoints, get roles mapping from the token, and check them against the endpoint roles