Spring Social offers a fairly complete implementation for most use cases. Yet, it doesn’t cover some issues, like what to do if you want to add two (or more) different
ConnectionFactories to the same social provider.
This could, for example, be useful if you have a platform that is used by several customers, each of which want to keep their user data separate from one another. Here, we will show you a way to work around that, but first we will take a look at the possible solutions.
Note that in this blog post we will only use LinkedIn as an example, but you can do it with any other social API.
If, for this issue, you would use the “normal” approach of adding a different social provider, that is, by creating a second
LinkedInConnectionFactory next to the first
LinkedInConnectionFactory, you would get the following:
Now, although the
clientSecret are different, Spring Social still considers them both the same. Why? Because Spring Social uses the
providerId and API-class to identify
ConnectionFactories. And because those are still the same in the above snippet, this will result in
A ConnectionFactory for provider ”linkedin” has already been registered" being thrown by the
ConnectionFactoryRegistry. In other words: Not a solution.
To tackle this we will create our own additional
ConnectionFactory with a different
The problem isn’t completely solved by registering our
FooLinkedInConnectionFactory next to Spring Social’s own
LinkedInConnectionFactory though. This time you get
A ConnectionFactory for API [LinkedIn] has already been registered", which is again thrown by the
You can see why these exceptions were thrown when you take a look at
ConnectionFactoryRegistry and its method
ConnectionFactoryRegistry keeps the
ConnectionFactories in two maps: One based on the
providerId, the other on the API-type. So while we did give our
FooLinkedInConnectionFactory a different
providerId, we still need to adapt the method above, so it accepts the same API more than once.
You can do this by adding a new
boolean parameter to the method that indicates whether the
ConnectionFactory needs to be added to the API-based map, or only to the
ConnectionFactoryLocator has two methods to get the correct
ConnectionFactory for a provider: One method is based on the API, the other one on the
With our solution, it is preferred to use
getConnectionFactory( String providerId ), because the API-based one will not be able to return every registered
Just like with Spring’s
addConnectionFactory-method is used while instantiating the bean.
Wrapping it all up
The change is in and of itself very minimal and contained. You just need to create the additional
ConnectionFactories and then make your own implementation of Spring Social’s
ConnectionFactoryLocator. In it, you adapt the
addConnectionFactory-method with a new boolean property, so that only one
ConnectionFactory is added to the API-map for each social provider. With these small changes, it is now possible to keep the user data separate for different customers. For more Spring Social use cases, see How to Render the Social Login Flow in a Popup.