I am building a Spring Social application that supports multiple tenants. The application identifies the tenants based on the url (e.g., tenant1.example.com and tenant2.example.com). I want to allow users of the application to connect using Facebook or Twitter. The issue I am having is that each tenant is a unique business and will have its own unique set of Facebook & twitter credentials. I don't think I can have more than one Facebook ConnectionFactory instance or more than one Twitter ConnectionFactory instance in my ConnectionFactoryRegistry. For example, this will not work:
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory("tenant1ClientId", "tenant1ClientSecret"));
registry.addConnectionFactory(new FacebookConnectionFactory("tenant2ClientId", "tenant2ClientSecret"));
The above will not work because, according to the Spring Social documentation, the locator returns a single instance.
public interface ConnectionFactoryLocator {
ConnectionFactory<?> getConnectionFactory(String providerId);
<A> ConnectionFactory<A> getConnectionFactory(Class<A> apiType);
Set<String> registeredProviderIds();
}
I thought about creating a ConnectInterceptor and injecting the relevant tenant credentials into the provided ConnectionFactory instance during the preConnect() step, but I suspect that will not work in a multi-threaded web application since the connectionFactory instance is shared.
So, my next thought was to simply create a unique ConnectionFactoryRegistry instance for each tenant. That solves the above issue.
But then the problem moves to the ConnectController (Spring's OAuth dance controller). Since the application can only have one controller, and the controller only holds one registry, how would I instruct the controller to use the right registry based on the tenant?
What is the right way to build a multitenant Spring Social application which will support unique ConnectionFactory instances for each tenant? Ideally, I would NOT want to define the ConnectionFactory instances in XML, since they are dynamic and stored in a DB.