Custom auth provider in a plugin

Hi folks,

I’‘m currently working on integrating Wildfire into an existing application to provide IM/chat services to users. This will touch a few different places in Wildfire, but for now I’'m just attempting to add a custom auth provider that authenticates against our application.

I have created a plugin which is loading successfully and showing up in the admin interface. I have also created a class that implements AuthProvider in the JAR with the plugin class. I was hoping that Wildfire would add my plugin jar to the classpath and then be able to find the configured AuthProvider inside, but it appears that this is not the case.

Is there a way to make this work? I’'d rather keep all of my extra bits self-contained in a plugin if possible, for ease of deployment.

2 Likes

Authentication provider that uses any JDBC tables. Useful for integrating into existing user systems. This is a feature contributed by David Snopek.

http://www.jivesoftware.org/issues/browse/JM-606

or

http://www.jivesoftware.org/community/thread.jspa?messageID=116311&#116311

Create jdbc authenticates plugin for wildfire is no problem.

Thanks for the pointer zhuam, but unfortunately a generic JDBC auth provider is not what I need. The existing system I’'m trying to integrate with exposes a SOAP webservice which is what I need to use for authentication. Consequently, I need to write my own auth provider specific to my application.

My question was more about packaging a custom auth provider than writing one. I have created a plugin (that is, a .jar file under the “plugins” directory) which contains a plugin class, which is loading successfully, and an AuthProvider. My hope was that Wildfire would add my plugin’'s .jar file to the classpath before it tried to load the auth provider class specified in wildfire.xml, but it appears that it does not. I see this in my error log:

2006.03.29 14:11:29 [org.jivesoftware.wildfire.auth.AuthFactory.(XMPPServer.java:135)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

at java.lang.reflect.Constructor.newInstance(Unknown Source)

at java.lang.Class.newInstance0(Unknown Source)

at java.lang.Class.newInstance(Unknown Source)

at org.jivesoftware.wildfire.starter.ServerStarter.start(ServerStarter.java:88)

at org.jivesoftware.wildfire.starter.ServerStarter.main(ServerStarter.java:49)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)

at com.exe4j.runtime.WinLauncher.main(Unknown Source)

(where the com.mycompany.dft.jabber.AuthProvider class is in a .jar file under the “lib” directory in my plugin.)

My guess is that Wildfire is trying to load the auth provider before it has loaded the plugins. Is this accurate? Is there any way around this? As I stated previously, I’'d rather keep all of my stuff in one self-contained plugin module rather than installing stuff all over the place. Alternative solutions welcome.

Hi,

Although there is no specific documentation saying you can’'t put your AuthProvider in a plugin, the general documentation indicates that the AuthProviders should go into the lib dir.

A quick review of the trace and the wildfire source shows the the way the class loading / startup sequence means that your AuthProvider won’'t be found on the classpath until its too late

I am afraid that you will have to put your AuthProvider in a separate jar from your plugin in the lib dir. Perhaps it a valid change request, otherwise the documentation should be cleared up.

Hope that helps,

Conor.

Thanks Conor. I had feared as much.

After reviewing some of the code, it appears that even if the components were initialized in a different order the auth class loader wouldn’'t be able to “see” the plugin .jar since that is only visible inside the plugin class loader.

This seems a shame, but I guess I’'ll just have to live with it!

Conor is exactly right. Loading the auth provider is part of the bootstrap process when starting up the server. Plugins are loaded after that which means that you can’'t have an auth provider as a plugin.

The general rule is: plugin classes can see main wildfire classes. Main classes cannot see plugin classes.

Regards,

Matt

Oh , Thanks .

So that means I have to crack open the code, include my custom class and then recompile the whole thing every time a new release is out?

Sorry for being lazy, but would it be possible to just include my package as a JAR archive and put it in the wildfire lib directory in order to make it available?

Its okay to be lazy, it should work if its in a JAR archive in the lib directory.

Cheers,

Alex

Thanks Matt.

Just to be completely clear on the steps to do this (we’re doing something very similar for a hybrid auth provider):

  1. Write your custom auth provider that implements AuthProvider. Package into a jar and deploy into the openfire lib directory.
  2. Change the system property for provider.auth.className to be org.jivesoftware.openfire.auth.HybridAuthProvider
  3. Add a new system property for “hybridAuthProvider.primaryProvider.className” to be your first auth provider (the .className is needed on that property, I think the Javadoc example is a bit misleading).
  4. Add a new property for the secondary authprovider, e.g. hybridAuthProvider.secondaryProvider.className = com.acme.foo.BarAuthProvider
  5. Register your cusomer authproviders in openfire.xml as below:
<provider>
     <auth>
       <className>com.foo.auth.CustomAuthProvider</className>
     </auth>
   </provider>

I’m trying to start openfire but it’s not coming up (with no error messages in the logs). Is there anything else I need to bear in mind?

1 Like

I would love to hear the resolution here - did you ever get it to work?

We did get it to work - that was so long ago now I can’t remember what the resolution was though! Are you having problems?

Hello Mikey,

I am just starting down the path of doing the same thing for my application. We also have a user data store that will require customization to how users are authenticated.

I was hoping I could integrate openfire with an AD user store and do a custom database implementation along with the ldap/AD configuration (for a different set of users). It seems only one or the other for a user store configuration is supported (as far as I can tell).

So, my only option it seems is to do this same thing … I was hoping I could follow the path that was outlined here, but then I got to the end and see a problem was encountered with no resolution! Yikes! I didn’t want to progress without some sort of “warm fuzzy” that it was going to eventually work. It seems like you got it to work - so I will proceed.

Thanks!

Anna.

All working fine here - remember that you’ll need to use one of those authentication types for logging into the admin console… Good luck!

Hello Mikey -

Thanks for the good wishes! I feel I am close …

With your custom auth provider did you use SASL authentication in your process? If not - how did you get around the SASL authentication requirements or is there a way to remove the SASL requirement from your auth provider?

Anna.

This has been resolved, but I just wanted to respond for the readers of these discussions:

When creating a custom Auth provider if you do not want to provide SASL authentication within your new auth provider construct set the Openfire configuration sasl.mechs to anonymous.

1 Like

Mikey -

How do I configure my authentication type to be used for logging into my admin console?

Anna.

Hi Anna,

Sorry, I think my post was a bit misleading, let me try to clear it up.

When using our custom auth token provider, the password entered by the user is actually a long token that no-one would be expected to remember. The user never enters that password directly, it’s supplied by the client app they use (we write our own client app for chatting in Actionscript).

However, we still want our system admins to log in to the admin console using an easy to remember password, so we enable the standard authentication which is against the internal Openfire DB.

So to be clear - you don’t need specific authentication to get into the admin console - it’s just something we do (which I’m not even sure is right to be honest).

Are you having problems getting into the admin console with your new authentication?

Hello Mikey -

Thanks for keeping up with me

The answer is “yes” to your last question. I am unable to log into the console. I thought it might have something to do with what you were saying in your previous post, but maybe I’m on the wrong track.

Some background is: I don’t have a hybrid auth provider - just one overridden provider with my own class talking SSL to my server to authenticate users. Getting the certificates wrestled into submission was a chore in and of itself but that’s another story

I thought that my regular authentication provider would be used for console authentication - but apparently that is incorrect? I can log in my “admin” user through a jabber client and see my authentication provider doing it’s job. But, when I navigate to ip:9090 and use those same credentials I am unable to log in. I see a log line in warn.log regarding the failed console login attempt, but no “authentication attempt” is logged by my custom authentication provider.

Here is what the log line in warn.log looks like:

2011.03.25 10:27:50 Failed admin console login attempt by admin@prx.eng.westminster.polycom.com from 10.33.24.55

I have this configuration for my admin user and I am not overriding (via my configuration DB) the default admin provider (so I think I am getting DefaultAdminProvider functionality):

admin.authorizedJIDs = admin@prx.eng.westminster.polycom.com

admin.authroizedUsernames = admin

Do you have any suggestions on what might be going wrong?

Anna.