-
Notifications
You must be signed in to change notification settings - Fork 555
External Authentication configuration
Chamilo 2 supports multiple external authentication methods configured through the config/authentication.yaml file. A template file authentication.dist.yaml is provided as a starting point in recent versions.
This file uses YAML syntax. Each entry within the authentication block corresponds to an access URL and contains the enabled authentication methods along with their required parameters.
Note that most of the authentication methods below require a change in this file + a cache clean-up so that the new authentication option will appear on the login page (or wherever it needs to appear). Also, clearing the cache on a production server will have a lasting effect of potentially several minutes during which page loading speed will be awful. This action should thus be taken at a time of low usage or during an official maintenance window. Cleaning the cache can be done with php bin/console cache:clear on the command line (followed by php bin/console cache:warmup), or using the visual option in Administration > System > Clean temporary files.
Table of contents
- General structure
- Authentication priority
- OAuth2 - Generic
- OAuth2 - Facebook
- OAuth2 - Keycloak
- OAuth2 - Azure (Microsoft Entra ID)
- LDAP
- SCIM (User provisioning)
parameters:
authentication:
<access_url_id>:
<auth_method>:
<provider_name>:
<config_key>: <value>| Placeholder | Description | Examples |
|---|---|---|
<access_url_id> |
Access URL ID |
default, 2, 3
|
<auth_method> |
Authentication method type |
oauth2, ldap, scim
|
<provider_name> |
Provider name (OAuth2 only) |
generic, facebook, keycloak, azure
|
<config_key> |
Provider-specific configuration key | See each method below |
When multiple methods are enabled, Chamilo checks them in the following order:
-
LDAP (if enabled and
force_as_login_methodistrue) - OAuth2 providers (in the order they appear in the configuration)
All authentication methods support the
force_as_login_methodkey. When set totrue, that method becomes the exclusive authentication method for the access URL.
Generic OAuth2 authentication compatible with any provider that implements the OAuth2 protocol (e.g., Google, GitLab).
This is the equivalent of the OAuth2 plugin configuration from Chamilo v1.11.*.
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables this method |
title |
string | Yes | Display name shown on the login page |
client_id |
string | Yes | OAuth2 client ID |
client_secret |
string | Yes | OAuth2 client secret |
allow_create_new_users |
boolean | No | Automatically creates new users if not found in Chamilo |
allow_update_user_info |
boolean | No | Updates user information from the provider on each login |
These keys are nested under provider_options.
| Key | Type | Required | Description |
|---|---|---|---|
urlAuthorize |
string | Yes | URL to request authorization |
urlAccessToken |
string | Yes | URL to request an access token |
urlResourceOwnerDetails |
string | Yes | URL returning the authenticated user's information as JSON |
responseResourceOwnerId |
string | No | JSON key for the user's unique identifier. Default: sub
|
accessTokenMethod |
string | No | HTTP method for the access token request |
accessTokenResourceOwnerId |
string | No | Key for the resource owner ID in the access token response |
scopeSeparator |
string | No | Character used to separate scopes. Default: ,
|
responseError |
string | No | JSON key for error messages. Default: error
|
responseCode |
string | No | JSON key for error codes |
scopes |
array | No | OAuth2 scopes to request. Default: ['openid']
|
pkceMethod |
string | No | PKCE method (e.g., S256) |
These keys map the provider's JSON response fields to Chamilo user attributes.
| Key | Type | Required | Description |
|---|---|---|---|
resource_owner_username_field |
string | No | Field to use as username |
resource_owner_firstname_field |
string | Yes | Field to use as first name |
resource_owner_lastname_field |
string | Yes | Field to use as last name |
resource_owner_email_field |
string | Yes | Field to use as e-mail |
These keys control how the provider's response determines the user's role in Chamilo.
| Key | Type | Required | Description |
|---|---|---|---|
resource_owner_status_field |
string | No | JSON key containing the user's role identifier |
resource_owner_teacher_status_field |
string | No | Value that maps to Course Manager / Teacher (role 1) |
resource_owner_sessadmin_status_field |
string | No | Value that maps to Session Administrator (role 3) |
resource_owner_hr_status_field |
string | No | Value that maps to HRM (role 4) |
resource_owner_student_status_field |
string | No | Value that maps to Student (role 5) |
resource_owner_anon_status_field |
string | No | Value that maps to Anonymous (role 6) |
| Key | Type | Required | Description |
|---|---|---|---|
resource_owner_urls_field |
string | No | JSON path expression to extract access URLs. Values should match access_url.id or access_url.url in Chamilo. |
The * wildcard iterates over array indices. For example, data.0.domaines.*.url resolves to:
$jsonArray["data"][0]["domaines"][0]["url"]
$jsonArray["data"][0]["domaines"][1]["url"]
$jsonArray["data"][0]["domaines"][2]["url"]
...
Enables login with Facebook. Requires a registered app at Meta for Developers.
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables this method |
title |
string | Yes | Display name shown on the login page |
client_id |
string | Yes | Facebook App ID |
client_secret |
string | Yes | Facebook App secret |
graph_api_version |
string | No | Graph API version. See available versions. Default: v20.0
|
Authentication using a Keycloak server (OpenID Connect compatible).
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables this method |
title |
string | Yes | Display name shown on the login page |
client_id |
string | Yes | Client ID registered in Keycloak |
client_secret |
string | Yes | Client secret |
auth_server_url |
string | Yes | Base URL of the Keycloak server |
realm |
string | Yes | Realm name |
version |
string | No | Keycloak version compatibility |
encryptionAlgorithm |
string | No | Encryption algorithm (e.g., RS256) |
encryptionKeyPath |
string | No | Path to the encryption key file (e.g., ../key.pem) |
encryptionKey |
string | No | Encryption key or certificate contents |
Authentication via Microsoft Entra ID (formerly Azure AD).
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables this method |
title |
string | Yes | Display name shown on the login page |
client_id |
string | Yes | Azure application (client) ID |
client_secret |
string | Yes | Shared client secret (not needed if using a certificate) |
url_api |
string | Yes | Microsoft Graph API base URL (e.g., https://graph.microsoft.com) |
tenant |
string | No | Azure Tenant ID. Required for synchronization commands. Default: common
|
url_login |
string | No | Login domain. Default: https://login.microsoftonline.com/
|
path_authorize |
string | No | OAuth authorization path |
path_token |
string | No | OAuth token path |
scope |
array | No | OAuth scopes sent with the request |
resource |
string | No | OAuth resource field |
auth_with_resource |
string | No | Send the resource field with the auth request |
api_version |
string | No | API version. Default: 1.6
|
default_end_point_version |
string | No | Endpoint version. Default: 1.0
|
Use these instead of client_secret to authenticate with a client certificate.
| Key | Type | Required | Description |
|---|---|---|---|
client_certificate_private_key |
string | No | Contents of the private key (PEM format) |
client_certificate_thumbprint |
string | No | Hexadecimal thumbprint of the certificate (e.g., B4A94A83092455AC4D3AC827F02B61646EAAC43D) |
| Key | Type | Required | Description |
|---|---|---|---|
provisioning |
boolean | No | Automatically create new users (as students) from Azure when not found in Chamilo |
update_users |
boolean | No | Update user data from Azure at the start of each session |
force_logout |
boolean | No | Show a button to force logout from the Azure session |
deactivate_nonexisting_users |
boolean | No | Deactivate Chamilo accounts that no longer exist in Azure |
script_users_delta |
boolean | No | Sync only newly created, updated, or deleted users (delta sync instead of full read) |
script_usergroups_delta |
boolean | No | Sync only changed groups and memberships (delta sync instead of full read) |
| Key | Type | Required | Description |
|---|---|---|---|
group_id.admin |
string | No | Azure group ID for platform administrators |
group_id.session_admin |
string | No | Azure group ID for session administrators |
group_id.teacher |
string | No | Azure group ID for teachers |
group_filter_regex |
string | No | Regex to filter which groups are synchronized (e.g., .*(FIL|PAR).*) |
| Key | Type | Required | Description |
|---|---|---|---|
existing_user_verification_order |
string | No | Order for matching Azure users to Chamilo accounts. Default: 1, 2, 3
|
The verification order values are:
| Order | Chamilo extra field | Azure attribute |
|---|---|---|
1 |
organisationemail |
mail |
2 |
azure_id |
mailNickname |
3 |
azure_uid |
id |
Each time a user authenticates via Entra ID, Chamilo runs the following lookup sequence to find the matching account. The first match wins.
Step 1 — Extra field lookup (configurable order)
Chamilo checks the three extra fields in the order defined by existing_user_verification_order (default: 1, 2, 3):
| Check | Chamilo extra field | Matched against |
|---|---|---|
| 1 | organisationemail |
mail from Entra ID |
| 2 | azure_id |
mailNickname from Entra ID |
| 3 | azure_uid |
id (object ID) from Entra ID |
Step 2 — Email fallback (case-insensitive)
If no extra field match is found, Chamilo searches for a user whose email matches the Entra ID mail attribute, ignoring case differences (e.g. Angel@empresa.com matches angel@empresa.com).
Step 3 — Username fallback (case-insensitive)
If the email lookup also fails, Chamilo searches for a user whose username matches the Entra ID userPrincipalName attribute, also case-insensitively.
Why case-insensitive fallbacks matter: Entra ID typically sends names and addresses with standard casing (e.g. first letter capitalized), while existing Chamilo accounts may have been created in all-lowercase. Without case-insensitive matching, the lookup fails and Chamilo attempts to create a duplicate account, which triggers a unique-constraint error on the
usernamecolumn.
If no user is found
- If
provisioning: true→ a new Chamilo account is created as a student using the data from Entra ID. - If
provisioning: false→ the login is rejected with an error.
When a user is found (or just created), the following fields are written from Entra ID into the Chamilo account:
| Chamilo field | Entra ID source |
|---|---|
| First name | givenName |
| Last name | surname |
mail |
|
| Username | userPrincipalName |
| Phone |
telephoneNumber → businessPhones[0] → mobilePhone (first available) |
| Active status | accountEnabled |
Extra: organisationemail
|
mail |
Extra: azure_id
|
mailNickname |
Extra: azure_uid
|
id (object ID) |
The role is always set to Student during synchronization. Group-based role promotion (admin, teacher, session admin) happens separately via the group sync commands.
If
update_users: false, existing users are returned as-is and none of the above fields are updated.
User language
The preferredLanguage attribute from Entra ID (e.g. fr-BE, nl-BE) is resolved to the closest available Chamilo language using the following fallback chain:
- Exact match (
fr_BE) - Short 2-letter code (
fr) - Canonical variant — same letters for language and country (
fr_FR) - Any available language with the same prefix (
fr_*) - If nothing matches → platform default language
If Entra ID sends no language, the user's existing language in Chamilo is preserved.
Authentication using the LDAP protocol (compatible with Active Directory, OpenLDAP, etc.).
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables this method |
title |
string | Yes | Display name for this method |
force_as_login_method |
boolean | No | Forces LDAP as the exclusive login method for this access URL |
connection_string |
string | Yes | LDAP server URL (e.g., ldap://localhost:389 or ldaps://localhost:636) |
protocol_version |
int | Yes | LDAP protocol version. Default: 3
|
referrals |
boolean | No | Automatically follow referrals returned by the LDAP server |
| Key | Type | Required | Description |
|---|---|---|---|
dn_string |
string | No | DN template for direct user bind (e.g., uid={user_identifier},dc=chamilo,dc=org). Default: {user_identifier}
|
query_string |
string | No | LDAP query template for searching users (alternative to direct bind) |
base_dn |
string | No | Base DN from which searches start |
search_dn |
string | No | Service account DN used for search operations |
search_password |
string | No | Service account password (e.g., CN=admin,dc=chamilo,dc=org) |
filter |
string | No | Additional LDAP filter (e.g., (objectClass=person)) |
uid_key |
string | No | Attribute used as the unique identifier (e.g., uid, sAMAccountName). Default: uid
|
password_attribute |
string | No | Attribute storing the user's password (e.g., userPassword) |
| Key | Type | Required | Description |
|---|---|---|---|
data_correspondence.firstname |
string | Yes | LDAP attribute for the user's first name |
data_correspondence.lastname |
string | Yes | LDAP attribute for the user's last name |
data_correspondence.email |
string | Yes | LDAP attribute for the user's email |
data_correspondence.locale |
string | No | LDAP attribute for the user's locale |
data_correspondence.role |
string | No | LDAP attribute for the user's role |
data_correspondence.phone |
string | No | LDAP attribute for the user's phone |
data_correspondence.active |
string | No | LDAP attribute for the user's active status |
data_correspondence.admin |
string | No | LDAP attribute for the user's admin status |
SCIM (System for Cross-domain Identity Management) is used for automated user provisioning and synchronization from external identity providers.
SCIM is not an interactive login method. It creates, updates, and deactivates users programmatically.
| Key | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | Enables or disables SCIM provisioning |
auth_source |
string | No | Authentication source for managed users. Default: platform
|
SCIM requests are authenticated using a static token defined in the .env file:
SCIM_TOKEN=your-secure-random-token
Resource Types
| Method | Endpoint |
|---|---|
GET |
/scim/v2/ResourceTypes |
GET |
/scim/v2/ResourceTypes/{resourceType} |
Schemas
| Method | Endpoint |
|---|---|
GET |
/scim/v2/Schemas |
GET |
/scim/v2/Schemas/{schemaId} |
Users
| Method | Endpoint | Description |
|---|---|---|
GET |
/scim/v2/Users |
List all users |
POST |
/scim/v2/Users |
Create a user |
GET |
/scim/v2/Users/{uuid} |
Get a specific user |
PUT |
/scim/v2/Users/{uuid} |
Replace a user |
PATCH |
/scim/v2/Users/{uuid} |
Update a user |
DELETE |
/scim/v2/Users/{uuid} |
Delete a user |
-
Home
- Tools and sessions
- Quiz: Importing
- Releases
- Community
- Development
- Getting started
- Development principles
- Technical design decisions
- Coding conventions v1
- Coding conventions v2
- Add a new Chamilo setting
- Database structure
- Date and time management
- Permissions
- Password management
- Session expiry time
- Code annotation types
- Code quality checkers
- Converting legacy SQL
- Settings migration v1 → v2
- Configurations
- Secure development policy
- Plugin development
- Adding page types
- Design
- Integration
