apache / shiro

Apache Shiro
https://shiro.apache.org/
Apache License 2.0
4.32k stars 2.31k forks source link

[Question] Cannot resolve system env variables from shiro.ini #1617

Closed m-ignatov closed 3 months ago

m-ignatov commented 3 months ago

Search before asking

Environment

JDK 21 Apache TomEE Docker

Shiro version

Shiro BOM 2.0.1, javax namespace

What was the actual outcome?

An exception occurs during application startup: The object with id [{LDAP_USER_DN_TEMPLATE}] has not yet been defined and therefore cannot be referenced. Please ensure objects are defined in the order in which they should be created and made available for future reference.

FYI, Shiro 2.0.0 works fine, the issue comes with 2.0.1.

What was the expected outcome?

Application starts up normally with the env vars populated into the LDAP realm.

How to reproduce

; shiro.ini
[main]
ldapRealm = org.apache.shiro.realm.ldap.DefaultLdapRealm
ldapRealm.userDnTemplate = ${LDAP_USER_DN_TEMPLATE}
# docker-compose.yml
environment:
  - LDAP_USER_DN_TEMPLATE=uid={0},ou=users,dc=company,dc=org
<!-- web.xml -->
<listener>
    <listener-class>com.company.extensions.security.ShiroInitListener</listener-class>
</listener>

Setting singleton security manager:

public class ShiroInitListener extends EnvironmentLoaderListener implements ServletContextListener {

  @Override
  public void contextInitialized(ServletContextEvent servletContextEvent) {
    WebEnvironment webEnvironment = super.initEnvironment(servletContextEvent.getServletContext());
    SecurityUtils.setSecurityManager(webEnvironment.getWebSecurityManager());
  }
}

Debug logs

2024-07-26 13:46:04.384 [main] ERROR o.a.shiro.web.env.EnvironmentLoader - Shiro environment initialization failed
org.apache.shiro.config.ogdl.UnresolveableReferenceException: The object with id [{LDAP_USER_DN_TEMPLATE}] has not yet been defined and therefore cannot be referenced.  Please ensure objects are defined in the order in which they should be created and made available for future reference.
    at org.apache.shiro.config.ogdl.ReflectionBuilder.getReferencedObject(ReflectionBuilder.java:442)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.resolveReference(ReflectionBuilder.java:457)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.resolveValue(ReflectionBuilder.java:614)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.applyProperty(ReflectionBuilder.java:776)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.applySingleProperty(ReflectionBuilder.java:424)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.applyProperty(ReflectionBuilder.java:385)
    at org.apache.shiro.config.ogdl.ReflectionBuilder$AssignmentStatement.doExecute(ReflectionBuilder.java:1039)
    at org.apache.shiro.config.ogdl.ReflectionBuilder$Statement.execute(ReflectionBuilder.java:971)
    at org.apache.shiro.config.ogdl.ReflectionBuilder$BeanConfigurationProcessor.execute(ReflectionBuilder.java:842)
    at org.apache.shiro.config.ogdl.ReflectionBuilder.buildObjects(ReflectionBuilder.java:309)
    at org.apache.shiro.ini.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:194)
    at org.apache.shiro.ini.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:152)
    at org.apache.shiro.ini.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:120)
    at org.apache.shiro.ini.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:111)
    at org.apache.shiro.ini.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:50)
    at org.apache.shiro.ini.IniFactorySupport.createInstance(IniFactorySupport.java:156)
    at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:50)
    at org.apache.shiro.web.env.IniWebEnvironment.createWebSecurityManager(IniWebEnvironment.java:316)
    at org.apache.shiro.web.env.IniWebEnvironment.configure(IniWebEnvironment.java:138)
    at org.apache.shiro.web.env.IniWebEnvironment.init(IniWebEnvironment.java:89)
    at org.apache.shiro.lang.util.LifecycleUtils.init(LifecycleUtils.java:45)
    at org.apache.shiro.lang.util.LifecycleUtils.init(LifecycleUtils.java:40)
    at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:321)
    at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:142)
    at com.company.extensions.security.ShiroInitListener.contextInitialized(ShiroInitListener.java:15)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4462)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4914)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:661)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1023)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1910)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown Source)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:824)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:474)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1617)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:318)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:114)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:345)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:893)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:794)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown Source)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:248)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:921)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:772)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478)
lprimak commented 3 months ago

Shiro 2.0.0 introduced a regression from 1.x where it made commons-configuration2 mandatory. See https://github.com/apache/shiro/issues/1352 for more details. Shiro 2.0.1 made commons-configuration2 optional again. You need to include the following in your maven pom:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-configuration2</artifactId>
            <version>2.11.0</version>
        </dependency>

Above should fix your issue.

Feel free to reopen if this doesn't solve your problem