Custom AuthProvider : access to JiveGlobals.getProperty() fails

Hello,

I’m writing a new implemation of AuthProvider. I’m adding it as a jar file in the /lib of my Openfire.
I need to access to properties which are set inside the database (in ofproperty).
I’ve checked how Openfire instantiates new AuthProvider and I found the following code:

    private static void initProvider(final Class clazz) {

        // Check if we need to reset the auth provider class
        if (authProvider == null || !clazz.equals(authProvider.getClass())) {
            try {
                authProvider = (AuthProvider)clazz.newInstance();
            }
            catch (Exception e) {
                Log.error("Error loading auth provider: " + clazz.getName(), e);
                authProvider = new DefaultAuthProvider();
            }
        }
    }

So in the constructor of my new class, I added some calls to JiveGlobals.getProperty(“x.y.z”):

        String myParam= JiveGlobals.getProperty(x.y.z);
        if (myParam==null)
            throw new Exception("property x.y.z not available");

But at Openfire startup, the exception is thrown, the property is not available:

2019.07.04 17:52:40 INFO  [main]: org.jivesoftware.openfire.XMPPServer - Accessing SystemProperty field org.jivesoftware.openfire.auth.AuthFactory#PASSWORD_KEY
2019.07.04 17:52:40 ERROR [main]: com.my.example - MyNewAuthProviderImpl() No MyParam available, Impossible to use this authentication method.
2019.07.04 17:52:40 ERROR [main]: org.jivesoftware.openfire.auth.AuthFactory - Error loading auth provider: com.my.example
java.lang.Exception: Missing or incorrect parameter: x.y.z
        at com.my.example.<init>(MyNewAuthProviderImpl.java:62) ~[InternalChatAuthLib-1.0-shaded.jar:?]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_191]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_191]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_191]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_191]
        at java.lang.Class.newInstance(Class.java:442) ~[?:1.8.0_191]
        at org.jivesoftware.openfire.auth.AuthFactory.initProvider(AuthFactory.java:79) [xmppserver-4.4.0-SNAPSHOT.jar:4.4.0-SNAPSHOT]
        at org.jivesoftware.openfire.auth.AuthFactory.<clinit>(AuthFactory.java:71) [xmppserver-4.4.0-SNAPSHOT.jar:4.4.0-SNAPSHOT]
        at sun.misc.Unsafe.ensureClassInitialized(Native Method) ~[?:1.8.0_191]
        at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43) [?:1.8.0_191]
        at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:156) [?:1.8.0_191]
        at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1088) [?:1.8.0_191]
        at java.lang.reflect.Field.getFieldAccessor(Field.java:1069) [?:1.8.0_191]
        at java.lang.reflect.Field.get(Field.java:393) [?:1.8.0_191]
        at org.jivesoftware.openfire.XMPPServer.scanForSystemPropertyClasses(XMPPServer.java:739) [xmppserver-4.4.0-SNAPSHOT.jar:4.4.0-SNAPSHOT]
        at org.jivesoftware.openfire.XMPPServer.start(XMPPServer.java:708) [xmppserver-4.4.0-SNAPSHOT.jar:4.4.0-SNAPSHOT]
        at org.jivesoftware.openfire.XMPPServer.<init>(XMPPServer.java:263) [xmppserver-4.4.0-SNAPSHOT.jar:4.4.0-SNAPSHOT]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_191]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [?:1.8.0_191]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [?:1.8.0_191]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [?:1.8.0_191]
        at java.lang.Class.newInstance(Class.java:442) [?:1.8.0_191]
        at org.jivesoftware.openfire.starter.ServerStarter.start(ServerStarter.java:92) [startup.jar:4.4.0-SNAPSHOT]
        at org.jivesoftware.openfire.starter.ServerStarter.main(ServerStarter.java:56) [startup.jar:4.4.0-SNAPSHOT]

What am I missing there ?

Are you sure that there is a property x.y.z?

Greg

I created it in the database, in ofproperty, so yes it’s present (I’m triple checking the spelling, but it seems OK :frowning: )

Does it show up on the system properties page? That page is also a better way of creating it (Openfire will cache the contents, so it’s possible that creating it direct in the database will not work unless you restart everything).

Greg

Ok so I think I found why properties are not found:

I tested to get every properties available in the database at the beginning of my constructor:

for (String name : JiveProperties.getInstance().getPropertyNames()) {
	Log.info("PropertyName=[{}]", name);
}

The output is the following:

2019.07.05 10:52:51 INFO  [main]: my.example.package.NewAuthProviderImpl - PropertyName=[{}]
2019.07.05 10:52:51 INFO  [main]: my.example.package.NewAuthProviderImpl - PropertyName=[{}]
2019.07.05 10:52:51 INFO  [main]: my.example.package.NewAuthProviderImpl - PropertyName=[{}]
....

So when my class is loaded by AuthFactory.java, no properties from the database look to be available ??

edit: @gdt
Yes, it show up in the admin panel (and I need to create those properties by code ^^). I already restarted my server multiple times also.

edit 2:
Sorry, my code above is wrong, I just forgot to add the ‘name’ variable to display… So it turns out that I have my parameters available

And I found my parameters with this:

for (String name : JiveProperties.getInstance().getPropertyNames()) {
	if (name.equalsIgnoreCase("myparam.is.caseSensitive") {
		String value = JiveProperties.getInstance().getProperty(name, "");
		Log.info("PropertyName=[{}],Value=[{}]", name, value);
	}
}

Result :
2019.07.05 11:29:35 INFO [main]: my.example.package.NewAuthProviderImpl - PropertyName=[myparam.is.caseSensitive],Value=[abcdef]

So it turns out that when using JiveGlobals, or JiveProperties, I should keep everything case insensitive??
Still in the database, the case is kept.
And there is no way to tell JiveGlobals.getProperty() to be case insensitive ?..

FWIW, JiveProperties.getInstance().getPropertyNames() could be simpliified to JiveGlobals.getPropertyNames()

In addition you’re not actually including the name of the property in the Log.info statement, which probably doesn’t help. Including the keys & values in the output would help.

I originally thought that you were using JiveGlobals “too early” but ruled that out as the AuthFactory uses JiveGlobals to determine which AuthProvider to use - so clearly at least one JiveGlobal is working, the rest will be too.

Greg

Yes you’re right about the log statement.
Just check what I added in my previous post.

By the way, thank you for your help :slight_smile:

My understanding is that keys are all case-sensitive.

There’s nothing to suggest in your code that this isn’t the case.

I’d like to see the output of

Log.info("PropertyName=[{}],Value=[{}]", name, JiveGlobals.getProperty(name);
Log.info("PropertyName (upper)=[{}],Value=[{}]", name, JiveGlobals.getProperty(name.toUpperCase());
Log.info("PropertyName (lower)=[{}],Value=[{}]", name, JiveGlobals.getProperty(name.toLowerCase());

to confirm that.

Greg

Well, as you could expect the error was coming from my Code :sweat_smile: (I had another test in the same ‘if’ that was making it fails, but properties were correctly retrieved…)
So JiveGlobals, and JiveProperties are working well, thanks for them :smiley:

Sorry for the time and thank you for your help @gdt

1 Like