Authentication providers are not loaded before authentication is initialized
When we put authentication providers into a plugin, we missed something about initialization order: we now have the sequence of provider initialization between spring and module check that is mismatched, leading to module providers never being available.
This is the current sequence:
// here it's RudderConfig initialization... 2018-10-22 15:01:59] INFO bootchecks - Update existing API token to 'RW' autorization level. // then spring is bootstrapped [2018-10-22 15:01:59] INFO org.eclipse.jetty.server.handler.ContextHandler.rudder_web - Initializing Spring root WebApplicationContext [2018-10-22 15:01:59] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started [2018-10-22 15:01:59] INFO org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Mon Oct 22 15:01:59 CEST 2018]; root of context hierarchy // here we start loading AppConfigAuth, starting with the XML definition of everything (including modules' spring config file) [2018-10-22 15:01:59] INFO org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Successfully resolved class for [bootstrap.liftweb.AppConfigAuth] 2018-10-22 15:01:59 JRebel: Monitoring Spring bean definitions in '/home/fanf/java/workspaces/rudder-project/rudder/rudder-web/target/classes/applicationContext-security.xml'. [2018-10-22 15:01:59] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext-security.xml] // here, we reach the point where we look for providers - but module not loaded yet, so license check forbid to use anything not standard [2018-10-22 15:02:00] WARN application - Required authentication method 'ldap' in property 'rudder.auth.provider' is not know by Rudder. Perhaps you are missing a plugin? [2018-10-22 15:02:00] INFO application - Loaded authentication provider(s):  [2018-10-22 15:02:00] INFO org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4682882a: startup date [Mon Oct 22 15:02:00 CEST 2018]; parent: Root WebApplicationContext [2018-10-22 15:02:01] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 1757 ms // end spring init // now Boot is started, loading modules [2018-10-22 15:02:01] INFO bootstrap.liftweb.Boot - classpath [2018-10-22 15:02:01] INFO org.reflections.Reflections - Reflections took 34 ms to scan 2 urls, producing 5 keys and 8 values // oh, new providers! [2018-10-22 15:02:01] INFO application - Add backend providers 'Enterprise Authentication Backends: 'ldap','radius'' // but it's too late, Jen.
Updated by François ARMAND almost 3 years ago
Before, we used to load auth provider definition as a dependency of the main Auth context. This is not possibile, because the available providers are defined at runtime, depending of license status.
So we need to change the spring AuthenticationProvider to provides one that gives the correct list of backend at runtime. It seems that AuthenticationProvider is hardly overridable / extensible in such a way, so perhaps we will need to suffer some more with a proxy implementation, and switching at runtime the real implementation. Hoping there's no cache in the way, and the performances are not too bad.
Updated by François ARMAND almost 3 years ago
So, we have 5 things to pounder:
- 1/ there is the definition of spring authentication backends. We can say that it is fixed between restart of the application. IE: each backend gives a spring provider, because that's the way it is, but is could have been a static config by code.
- 2/ there's the rudder-web.properties file, which today defines everything and is only loaded one time at the begining of rudder startup,
- 3/ there's the spring authentication infrastructure. It needs all code/xml available and loaded in classpath and access to rudder properties. It can't be changed easely after upgrade.
- 4/ there's the plugin loading (ie the logic of a plugin registering it's services). It's done toward the start of Boot execution
- 5/ there's the license-related check, that need to be perform at run-time.
Also: in the mid-term, everything need to be updatable at run time, so we need to be able to change the configuration of a backend at runtime.