Customizing the loading of provider’s configuration in Secure Social

In my last project, which I had to use a lot of features of Secure Social, I had to customize the way this plugin loads social credentials from the securesocial.conf file. Let me explain a little bit my problem. It is a multi tenant app and the tenant is defined by a subdomain. For example, client1.domain.com.br(negrito) and client2.domain.com.br(negrito) should load different configurations of facebook.

The problem is that Secure Social loads the social credentials from a configuration file. By default it is not possible to load multiple configurations, at least as far as I know :). So, in order to allow this kind of behavior, I had to specialize the provider and change this part of the plugin. Let’s see the code and the problems.

The first thing we need to is to inherit from the FacebookProvider class(italico) and override a method which name is settings(negrito)

    public class CustomFacebookProvider extends FacebookProvider{
	
    	public CustomFacebookProvider(Application application) {
    		super(application);
    	}
	
	
    	@Override
    	public OAuth2Settings settings() {
            
    	}
	
    }

This method is invoked to load the configuration. The default behavior is to load all information in the application startup, take a look in github(link para o github). Now we need to access the database and load the specific credentials of a tenant


	@Override
	public OAuth2Settings settings() {		;
		User client = Users.findByDomain(Context.current()._requestHeader().domain())
		return new OAuth2Settings(
						"https://graph.facebook.com/oauth/authorize",
						"https://graph.facebook.com/oauth/access_token",
						client.getFacebookConfig().getClientId(),
						client.getFacebookConfig().getClientSecret(),
						Option.apply("email"));
	}

There is just one problem, and it is a big one. I am using the Java version of Play and, at this point, the request was not set in the ThreadLocal(italico) used by Play to handle the execution of a client. In order to solve this problem, I had to use a little bit of bad practice of code, which is called POG here in Brazil(Programação orientada a gambiarra) . There is a method called doAuth(italico) which is responsible for authenticate a user in Secure Social and this same method receives a request as a parameter. So take a look in my solution:


        private static ThreadLocal<String> domainContext = new ThreadLocal<>();

	@Override
	public OAuth2Settings settings() {		;
		User client = Users.findByDomain(domainContext.get())
		return new OAuth2Settings(
						"https://graph.facebook.com/oauth/authorize",
						"https://graph.facebook.com/oauth/access_token",
						client.getFacebookConfig().getClientId(),
						client.getFacebookConfig().getClientSecret(),
						Option.apply("email"));
	}

	@Override
	public <A> Either<Result, SocialUser> doAuth(final Request<A> request) {
		domainContext.set(request.domain());
		Either<Result, SocialUser> doAuth = super.doAuth(request);
		domainContext.set(null);
		return doAuth;
	}

I used a ThreadLocal to store the current request and use it in the method settings(italico). I know it is not the best, but I could not store this request in a instance variable because the provider is loaded as a plugin, and plugins are singletons. Using this technique I can retrieve the domain and pass it to the method responsible for loading the tenant information.

The last part is that you have to change the configuration in your play.plugins(negrito) file.

   10001:security.securesocial.CustomFacebookProvider

That is it folks! Every week I try to write something that was useful for me in one my projects. If you have any topic that is interesting for you, comment here and I will be glad in writing about!

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s