History
In the meantime, some time has passed as @nilmerg explained me how to create a own custom backend. The requirement was to call Icinga from an application portal (beside the possability via DbBackend) and use its authentication information for the login. Because it's a kind of external backend I should use as role model
|
class ExternalBackend implements UserBackendInterface |
.
Now I have finally managed to do this, but I noticed a few things that I would like to describe here
Describe the bug
During the development I recognized that my module with the own backend is loaded too late and/or the authentifcation call was after putting the credentials into the LoginForm.
Depending on the situation icingaweb produces a lot of error messages like:
Can't create authentication backend "portal". An exception was thrown: <- Icinga\Exception\ConfigurationError in /usr/share/php/Icinga/Authentication/User/UserBackend.php with message: Authentication configuration for user backend "xxx" defines an invalid backend type. Backend type "xxx" is not supported
It doesn't matter in which order I configured my backend and the DbBackend at /etc/icingaweb2/authentication.ini. Because of that I had to debug the complete login sequence.
To Reproduce
The first problem (or actually hurdle) I encourtered is the function
|
protected function authExternal() |
which is triggerd by
|
public function isAuthenticated() |
. The problem what I saw is here, that the function authExternal checks if the backend is a instace of the class
ExternalBackend. So If I create my own backend with the implemation of the Interface
UserBackendInterface. The function returns false everytime and consequently the authentication fails. Here is the workarround for now that the own backend extends the class
ExternalBackend although the most things isn't needed from that class. Maybe to create an own interface, which also will be checked in
authExternal instead of the class name? Just to produce nicer code.
The second problem I encourtered is this call
|
foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) { |
. All installed and activated modules are loaded alphabetically. For example I choose as name for my module "Mybackend". If there are many other modules loaded before like "audit", "icingadb" etc. it takes time, until the own module is loaded. And here happens a big problem: During loading every module and register possible custom backends, following function gets triggerd
|
protected function includeScript($file) |
This function includes the configuration.php and excutes the existing PHP code. If there is a code like (from icingadb-web):
$auth = Auth::getInstance();
$authenticated = Icinga::app()->isWeb() && $auth->isAuthenticated();
the call will fail, because the own modul isn't loaded and the own backend isn't registred yet. This produces the mentioned error message above and happens as long as, until the own module gets loaded! Depending on the number of modules installed, the log file becomes filled with error messages!
The only workarround for this is to rename the own module to a little senseless name like "aaamybackend" to provoke the fact that the own module with the own backend is loaded first.
Expected behavior
I know this is a still rare case. Maybe not everybody is crazy like my/us 😆 to create a own backend. So get a solution for this will be low prio I think. For loading in a specific order instead of alphabetical could be to set something like a load order. So that, the call
Icinga::app()->getModuleManager()->getLoadedModules() returns the correct and needed order.
And for the "problem" with authExternal a solution could be an own interface as I wrote before. But that's only that the code will be nicer, not more.
I just wanted to draw attention to it.
Your Environment
Include as many relevant details about the environment you experienced the problem in
- Icinga Web 2 version and modules (System - About): 2.12.1
- Web browser used: Edge (128.0.2739.79) / Firefox (115.15.0esr)
- Icinga 2 version used (
icinga2 --version): 2.14.2-1
- PHP version used (
php --version): 8.0.30
- Server operating system and version: RHEL 9.4
History
In the meantime, some time has passed as @nilmerg explained me how to create a own custom backend. The requirement was to call Icinga from an application portal (beside the possability via DbBackend) and use its authentication information for the login. Because it's a kind of external backend I should use as role model
icingaweb2/library/Icinga/Authentication/User/ExternalBackend.php
Line 13 in c4b6e4b
Now I have finally managed to do this, but I noticed a few things that I would like to describe here
Describe the bug
During the development I recognized that my module with the own backend is loaded too late and/or the authentifcation call was after putting the credentials into the LoginForm.
Depending on the situation icingaweb produces a lot of error messages like:
Can't create authentication backend "portal". An exception was thrown: <- Icinga\Exception\ConfigurationError in /usr/share/php/Icinga/Authentication/User/UserBackend.php with message: Authentication configuration for user backend "xxx" defines an invalid backend type. Backend type "xxx" is not supportedIt doesn't matter in which order I configured my backend and the DbBackend at
/etc/icingaweb2/authentication.ini. Because of that I had to debug the complete login sequence.To Reproduce
The first problem (or actually hurdle) I encourtered is the function
icingaweb2/library/Icinga/Authentication/Auth.php
Line 239 in c4b6e4b
icingaweb2/library/Icinga/Authentication/Auth.php
Line 88 in c4b6e4b
ExternalBackend. So If I create my own backend with the implemation of the InterfaceUserBackendInterface. The function returns false everytime and consequently the authentication fails. Here is the workarround for now that the own backend extends the classExternalBackendalthough the most things isn't needed from that class. Maybe to create an own interface, which also will be checked inauthExternalinstead of the class name? Just to produce nicer code.The second problem I encourtered is this call
icingaweb2/library/Icinga/Authentication/User/UserBackend.php
Line 91 in c4b6e4b
icingaweb2/library/Icinga/Application/Modules/Module.php
Line 1374 in c4b6e4b
the call will fail, because the own modul isn't loaded and the own backend isn't registred yet. This produces the mentioned error message above and happens as long as, until the own module gets loaded! Depending on the number of modules installed, the log file becomes filled with error messages!
The only workarround for this is to rename the own module to a little senseless name like "aaamybackend" to provoke the fact that the own module with the own backend is loaded first.
Expected behavior
I know this is a still rare case. Maybe not everybody is crazy like my/us 😆 to create a own backend. So get a solution for this will be low prio I think. For loading in a specific order instead of alphabetical could be to set something like a load order. So that, the call
Icinga::app()->getModuleManager()->getLoadedModules()returns the correct and needed order.And for the "problem" with
authExternala solution could be an own interface as I wrote before. But that's only that the code will be nicer, not more.I just wanted to draw attention to it.
Your Environment
Include as many relevant details about the environment you experienced the problem in
icinga2 --version): 2.14.2-1php --version): 8.0.30