Despite the recent departure of the lead author, Eran Hammer, from the OAuth 2.0 specification with what would seem to be a crippling end to the very popular protocol, the OAuth 2.0 Sky is in fact NOT falling. Hammer cites one of the main reasons for leaving the specification is the fact that the specification is "getting more complex, less interoperable, less useful, more incomplete, and most importantly, less secure." He states, "OAuth 2.0 at the hand of a developer with deep understanding of web security will likely result is a secure implementation. However, at the hands of most developers - as has been the experience from the past two years - 2.0 is likely to produce insecure implementations." This is an alarming statement considering most sites on the web use a form of OAuth to share resources. Despite this, Hammer states that the spec is not "dead", he just thinks it's bad. He shares some good points on the future of OAuth and what you need to know if you are implementing it. As of this article, the OAuth wikipedia page shows a list of service providers that actively use a form of the OAuth protocol.

Spring Social OAuth

So, regardless of where you think the specification is going, the reality is that so many service providers have already adopted OAuth as the de-facto standard for sharing private resources across the web, it doesn't look it will be going anywhere anytime soon.

Why Broadleaf uses Spring Social

If you have a Spring application and are looking to integrate with an OAuth provider, there's no reason not to use Spring Social. As Hammer's statement alludes to, implementing the OAuth "dance" is a non-trivial task. Because OAuth is still a moving specification, a lot of providers have their own implementations. Managing these connections across multiple providers yourself would be very hard and tedious. The good folks over at Spring realized this and came up with the Spring Social framework. The framework makes it extremely easy to integrate with service providers that use OAuth such as Facebook and Twitter. One of the key benefits is the abstraction layer that it provides on top of the different authentication schemes. It currently handles both OAuth 1 and OAuth 2. Spring Social provides clear interfaces, so if you want to integrate with your own custom provider, there is an easy way to extend Spring Social Core to do so.

What does this mean to my eCommerce Site?

It's now pretty apparent that social media can play a huge part in developing a relationship between a customer and their merchant. The hard part is finding the right way to utilize social media to communicate your message clearly to your consumers. Twitter posted a case study that outlines how Zappos uses their service to generate over 1,200 conversations per month with its customers. Well the team at Broadlef realize that alot of merchants want the ability to utilize these services. We plan to make it easy for the framework to integrate with these services using Spring Social.

Why integrate Broadleaf with Facebook and Twitter?

Catering to your Customers

What if you had the ability to target specific content or promotions based on a tweet or attributes on your facebook profile? In a following post, I will discuss some ways to utilize the integrations with Facebook and Twitter to cater your content to your customers using Broadleaf.

In the meantime, let your customers sign in with their social networks

As of Broadleaf Commerce 2.1, the framework provides integrations points necessary to use Spring Social. Below, I will outline the steps necessary to add a "Sign in with Twitter" or "Sign in with Facebook" button to the Broadleaf Demo Site.

Spring Social Login

Step 1) Add the Spring Social dependencies to your root POM

<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
    <version>1.0.2.RELEASE</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-twitter</artifactId>
    <version>1.0.2.RELEASE</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-web</artifactId>
    <version>1.0.2.RELEASE</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>

Make sure to add the dependencies to your Site POM as well

<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-twitter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-web</artifactId>
</dependency>

Step 2) Create a new applicationContext-social.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
     http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <bean id="connectionFactoryLocator" class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
        <property name="connectionFactories">
            <list>
                <bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
                    <constructor-arg value="${facebook.clientId}" />
                    <constructor-arg value="${facebook.clientSecret}" />
                </bean>
                <bean class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
                    <constructor-arg value="${twitter.consumerKey}" />
                    <constructor-arg value="${twitter.consumerSecret}" />
                </bean>
            </list>
        </property>
    </bean>

    <bean id="usersConnectionRepository" class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
        <constructor-arg ref="webDS" />
        <constructor-arg ref="connectionFactoryLocator" />
        <constructor-arg ref="textEncryptor" />
        <aop:scoped-proxy proxy-target-class="false" />
        <property name="tablePrefix" value="BLC_"/>
    </bean>

    <bean id="connectionRepository" factory-method="createConnectionRepository" factory-bean="usersConnectionRepository" scope="request">
        <constructor-arg value="#{session.customer.username}" />
        <aop:scoped-proxy proxy-target-class="false" />
    </bean>

    <!-- Configure this to use the Broadleaf Runtime Environment properties file -->
    <bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
          factory-method="noOpText" />
    </beans>

Modify the current applicationContext-servlet.xml and add the following bean:

    <bean class="org.springframework.social.connect.web.ProviderSignInController">
        <property name="applicationUrl" value="${application.url}" />
        <property name="signUpUrl" value="/register" />
        <property name="signInUrl" value="/login" />
    </bean>

Modify the current applicationContext-security.xml and add the following "https" intercept

    <!-- Spring Social endpoints -->
    <sec:intercept-url pattern="/signin/**" requires-channel="https" />

Step 3) Modify your Broadleaf Runtime Properties files

For example, my development.properties file looks like:

#Spring Social
facebook.clientId=my_client_id
facebook.clientSecret=my_client_secret

twitter.consumerKey=my_consumer_key
twitter.consumerSecret=my_consumer_secret

application.url=http://127.0.0.1:8080

Step 4) Add your new applicationContext-social.xml to web.xml

<context-param>
    <param-name>patchConfigLocation</param-name>
    <param-value>
        classpath:/bl-open-admin-contentClient-applicationContext.xml
        classpath:/bl-cms-contentClient-applicationContext.xml
        classpath:/applicationContext.xml
        /WEB-INF/applicationContext-datasource.xml
        /WEB-INF/applicationContext-email.xml
        /WEB-INF/applicationContext-security.xml
        /WEB-INF/applicationContext-social.xml
        /WEB-INF/applicationContext.xml          
    </param-value>
</context-param>

Step 5) Change your RegisterController to extend BroadleafSocialRegisterController

By default, it extends BroadleafRegisterController

@Controller
@RequestMapping("/register")
public class RegisterController extends BroadleafSocialRegisterController {
 ...
}

Step 6) Finally, add the sign in buttons to your login page

Add the following html to login.html

<h4>OR</h4>

<blc:form th:action="@{/signin/twitter}" method="POST">
    <button type="submit"><img th:src="@{/img/social/sign-in-with-twitter-l-sm.png}"/></button>
</blc:form>

<br/>

<blc:form th:action="@{/signin/facebook}" method="POST">
    <button type="submit"><img th:src="@{/img/social/facebook_16.png}"/> �???�??�?�  Sign in with Facebook</button>
</blc:form>

Done!

Test your integrations with Facebook and Twitter! Now your customers can login with their Facebook and Twitter account instead of signing in with your application's credentials.