Booting up Spring Social

46
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Booting up Spring Social By Craig Walls

description

Speaker: Craig Walls Applied Spring Track In recent years, people are using social networks like Facebook and Twitter to connect, meet, and share experiences and ideas. But it's not just people making connections; modern applications are also leveraging the APIs provided by the social networks to connect with their users and customers. It's hard to find applications these days that aren't somehow connected to their users via social APIs. Spring Social is an extension to the Spring Framework that enables you to create applications that connect with APIs. With it, your application can offer social login, learn about its users' interests, and inject itself into their social graph. In this session, we'll take a look at the latest that Spring Social has to offer, including integration with Spring Security, automatic reconnect, and a dramatically simpler configuration model using Spring Boot.

Transcript of Booting up Spring Social

Page 1: Booting up Spring Social

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Booting up Spring SocialBy Craig Walls

Page 2: Booting up Spring Social

Contents

• Introduction to “Social” apps • Adventures in API security • The Spring Social Connection • Building “Social” apps with Spring Social • Final thoughts

2

Page 3: Booting up Spring Social

Introduction to “Social” Apps

3

Page 4: Booting up Spring Social

The Web is Social

• 74% of adult internet users use social networking sites • Facebook has 1.32 BILLION monthly active users • Many web application allow users to register and/or signin using

their social credentials • Social engagement builds trust; trust builds loyalty; loyalty results

in customers

4

Sources: • about.twitter.com/company • newsroom.fb.com/company-info • http://www.pewinternet.org/2013/12/30/social-media-update-2013/

Page 5: Booting up Spring Social

Comparing the social networks

5

0

0.35

0.7

1.05

1.4

Facebook Google+ Instagram Twitter LinkedIn

Mon

thly

act

ive

user

s (in

bill

ions

)

Sources: • about.twitter.com/company • newsroom.fb.com/company-info • instagram.com/about/us • www.linkedin.com/company • thenextweb.com/google/2013/10/29/two-years-later-google-growing-540m-active-users-worldwide-1-5b-photos-uploaded/

Page 6: Booting up Spring Social

Social Opportunities

• Inject your product/service into your customer’s social graph • Social marketing • Social sign-on • Social customer service

6

Page 7: Booting up Spring Social

However…

“Social” is not really the point

7

Page 8: Booting up Spring Social

It’s about API Integration

“Connect” vs. “Social” APIs not necessarily “friends”

8

Page 9: Booting up Spring Social

Adventures in API Security

9

Page 10: Booting up Spring Social

How APIs are secured

• HTTP Basic authentication • Application keys • Homegrown authentication schemes • OAuth 1.0(a) • OAuth 2 Bearer tokens • OAuth 2 MAC tokens

10

Page 11: Booting up Spring Social

OAuth in a Nutshell (The Easy Slide)

11

May I get a list of Craig’s friends?

Spring.io wants to see a list of your friends.

Is that okay with you?Hmmm...I guess that’s okay

Craig says okay. Here’s a token proving you have access to his stuff

Page 12: Booting up Spring Social

The OAuth 2 “Dance” (A Difficult Slide)

12

Similar to OAuth 1.0a flow Start with redirect to provider

After authorization, redirect back to client with authorization code

Code is exchanged for access token

!Client must keep tokens

confidential !

Appropriate for server-side of a web application

Page 13: Booting up Spring Social

The OAuth 1 “Dance” (Slightly More Difficult Slide)

13

A. Request an unauthorized request token

B. Request token returned to consumer

C. Redirect user to provider for authorization

D. Authorization verifier returned to consumer (OAuth 1.0a)

E. Exchange request token/verifier for access token

F. Access token and secret returned to consumer

G. Sign requests using access token to access API endpoints

Page 14: Booting up Spring Social

Making OAuth 2 API Requests (Brace Yourself)

14

Authorization: Bearer e139a950-2fc5-4822-9266-8a2b572108c5

Put Authorization header on all requests

Can optionally be sent in access_token parameter

Page 15: Booting up Spring Social

Making OAuth 1 API Requests (The Scary Slide)

15

Create a base string Encode all query/form parameters

Sort all query/form parameters Concatenate them, separated with “&”

HTTP Method + “&” + URL + “&” + sorted/encoded parameters Encrypt the base string to create a signature

HMAC-SHA1 is common Spec also allows for PLAINTEXT and RSA-SHA1 Add Authorization header to the API request

Authorization: OAuth oauth_callback="oob", oauth_signature="cyajrKmSnVemFg71TqmBSfOf6bU%3D", oauth_version="1.0", oauth_nonce="-128541705", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="kqAm0GiPCT2owEtyTLPsug", !oauth_token="161064614-st1sOR9vKUP65jALY2HFox8YQoT0Aa29JjvKrJSk", oauth_timestamp="1286834884"

ARRRGGGHHH!!!

Page 16: Booting up Spring Social

API Client Responsibilities

• Obtain access tokens • Securely store access tokens • Include Authorization header on all API requests • Renew/Replace expired or revoked tokens

16

Page 17: Booting up Spring Social

However…

None of that is your problem

17

Thanks to Spring Social

Page 18: Booting up Spring Social

The Spring Social Connection

18

Page 19: Booting up Spring Social

The Spring Social Project Family

19

Spring Social

Core Security Web Config

Provider Bindings

Facebook Twitter

LinkedIn GitHub

TripIt (?)

Spring for Android

Spring for Android

Community-Led Projects500px

BitBucket

DropBox

Foursquare

Instagram

last.fm

Mixcloud

SoundCloud

Vkontakte

Yammer

Alfresco

Daum

Flattr

Geeklist

Intuit/QBO

Win. Live

Nk

Tumblr

Weibo

App.net

Digg

Flickr

Google

Khan Acad.

Miso

Salesforce Viadeo Xing

Page 20: Booting up Spring Social

creates

Spring Social Components

20

Performs OAuth “dance”. !Handles requests for “/connect/{providerId} !Redirects the browser to the API’s authorization page. Exchanges the authorization code for an access token. !Looks up a ConnectionFactory for a given API provider and uses it to create a Connection. Stores the Connection in the database via a ConnectionRepository.

Looks up a ConnectionFactory by the API provider ID.

Creates Connections. !Also knows specifics regarding an API provider’s OAuth implementation.

Stores Connections in a database for future use.

Makes requests to an API on behalf of the application, ensuring that the Authorization header is on each request.

Connect Controller

Connection Factory Locator

Connection Repository

Connection Factory Connection

API Binding

stored

via

Page 21: Booting up Spring Social

ConnectController Connection Flow

21GET /connect

Page 22: Booting up Spring Social

ConnectController Connection Flow

22GET /connect/twitterPOST /connect/twitter

redirectredirect

GET /connect/twitter?oauth_token={t}&verifier={v}GET /connect/twitter

Page 23: Booting up Spring Social

What are Connections?

• Capture the relationship between a user, an API, and an access token

• Produces OAuth-ready instances of API bindings • Not to be confused with other kinds of connections in Java

• They do not need to be closed

23

Page 24: Booting up Spring Social

Social Sign-In

• ProviderSignInController • Spring MVC controller • Best suited for apps not using Spring Security !

• SocialAuthenticationFilter • Spring Security AuthenticationFilter implementation • Best suited for apps using Spring Security

24

Page 25: Booting up Spring Social

Miscellaneous

• ReconnectFilter • Catches NotAuthorizedException and OperationNotPermittedException • Redirects to ConnectController to establish a new connection

• DisconnectController (Facebook only) • Handles disconnect callbacks from Facebook • Removes a connection if user revokes access from Facebook

• RealTimeUpdateController (Facebook only) • Handles real-time update callbacks from Facebook

• GenericOAuth1ConnectionFactory and GenericOAuth2ConnectionFactory • Enables RestTemplate-based access for any API

25

Page 26: Booting up Spring Social

Building “Social” Apps with Spring Social

26

Page 27: Booting up Spring Social

Configuring Spring Social

• ConnectController • ConnectionFactoryLocator • ConnectionRepository / UserConnectionRepository • API Bindings • ProviderSignInController or SocialAuthenticationFilter • UserIdSource • ReconnectController (optional) • DisconnectController (optional) • etc • etc

27

Page 28: Booting up Spring Social

Configuring Spring Social with XML (the old way)

28

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> ! <bean id="usersConnectionRepository" class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository"> <constructor-arg ref="dataSource" /> <constructor-arg ref="connectionFactoryLocator" /> <constructor-arg ref="textEncryptor" /> </bean> <bean id="connectionFactoryLocator" class="org.springframework.social.connect.support.ConnectionFactoryRegistry"> <property name="connectionFactories"> <list> <bean class="org.springframework.social.twitter.connect.TwitterConnectionFactory"> <constructor-arg value="${twitter.consumerKey}" /> <constructor-arg value="${twitter.consumerSecret}" /> </bean> <bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory"> <constructor-arg value="${facebook.appId}" /> <constructor-arg value="${facebook.appSecret}" /> </bean> </list> </property> </bean> ! <bean class="org.springframework.social.showcase.config.ConnectionRepositoryConfig" /> <bean class="org.springframework.social.showcase.config.ApisConfig" /> </beans>

Page 29: Booting up Spring Social

Configuring Spring Social with XML (the new way)

29

<?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:facebook="http://www.springframework.org/schema/social/facebook" xmlns:twitter="http://www.springframework.org/schema/social/twitter" xmlns:social="http://www.springframework.org/schema/social" xmlns:linkedin="http://www.springframework.org/schema/social/linkedin" xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/social/facebook http://www.springframework.org/schema/social/spring-social-facebook.xsd http://www.springframework.org/schema/social/linkedin http://www.springframework.org/schema/social/spring-social-linkedin.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/social/twitter http://www.springframework.org/schema/social/spring-social-twitter.xsd http://www.springframework.org/schema/social http://www.springframework.org/schema/social/spring-social.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> !! <context:property-placeholder location="classpath:/org/springframework/social/showcase/config/application.properties" /> ! <facebook:config app-id="${facebook.clientId}" app-secret="${facebook.clientSecret}" app-namespace="socialshowcase" /> <twitter:config app-id="${twitter.consumerKey}" app-secret="${twitter.consumerSecret}"/> <linkedin:config app-id="${linkedin.consumerKey}" app-secret="${linkedin.consumerSecret}"/> ! <social:jdbc-connection-repository/> <bean id="userIdSource" class="org.springframework.social.security.AuthenticationNameUserIdSource" /> ! <bean id="connectController" class="org.springframework.social.connect.web.ConnectController" autowire="constructor"> <property name="connectInterceptors"> <list> <bean class="org.springframework.social.showcase.facebook.PostToWallAfterConnectInterceptor" /> <bean class="org.springframework.social.showcase.twitter.TweetAfterConnectInterceptor" /> </list> </property> </bean> <bean id="psc" class="org.springframework.social.connect.web.ProviderSignInController" autowire="constructor" /> <bean id="signInAdapter" class="org.springframework.social.showcase.signin.SimpleSignInAdapter" autowire="constructor" /> <bean id="disconnectController" class="org.springframework.social.facebook.web.DisconnectController" c:_0-ref="usersConnectionRepository" c:_1="${facebook.clientSecret}" /> !</beans>

Page 30: Booting up Spring Social

Configuring Spring Social with Java

30

@Configuration @EnableSocial public class SocialConfig implements SocialConfigurer { ! @Inject private DataSource dataSource; ! @Override public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) { cfConfig.addConnectionFactory(new TwitterConnectionFactory( env.getProperty("twitter.appKey"), env.getProperty("twitter.appSecret"))); } @Override public UserIdSource getUserIdSource() { return new UserIdSource() { @Override public String getUserId() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null) { throw new IllegalStateException("Unable to get a ConnectionRepository: no user"); } return authentication.getName(); }}; } … }

Page 31: Booting up Spring Social

Configuring Spring Social with Java

31

@Configuration @EnableSocial public class SocialConfig implements SocialConfigurer { … @Override public UsersConnectionRepository getUsersConnectionRepository( ConnectionFactoryLocator connectionFactoryLocator) { return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText()); } @Bean @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter(ConnectionRepository repository) { Connection<Twitter> connection = repository.findPrimaryConnection(Twitter.class); return connection != null ? connection.getApi() : null; } @Bean public ConnectController connectController( ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) { ConnectController connectController = new ConnectController(connectionFactoryLocator, connectionRepository); connectController.addInterceptor(new PostToWallAfterConnectInterceptor()); connectController.addInterceptor(new TweetAfterConnectInterceptor()); return connectController; } … }

Page 32: Booting up Spring Social

Configuring Spring Social with Java

32

@Configuration @EnableSocial public class SocialConfig implements SocialConfigurer { … ! @Bean public ProviderSignInController providerSignInController( ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository usersConnectionRepository) { ! return new ProviderSignInController( connectionFactoryLocator, usersConnectionRepository, new SimpleSignInAdapter(new HttpSessionRequestCache())); } }

Page 33: Booting up Spring Social

However…

None of that is really necessary

33

Thanks to Spring Boot

Page 34: Booting up Spring Social

The Simplest Spring Social App

34

class T{Twitter t}

The very simplest

@Controller class TW { Twitter t @RequestMapping("/") def h() { "redirect:/connect/twitter" } }

Still simple

Page 35: Booting up Spring Social

Specifying Application Credentials

35

spring.social.auto_connection_views=true spring.social.twitter.appId=yix4… spring.social.twitter.appSecret=9rX…

application.properties

spring: social: auto_connection_views: true twitter: appId: yix4… appSecret: 9rX…

application.yml

Page 36: Booting up Spring Social

Spring Social/Boot Step by Step

1. Boot’s CLI sees that Twitter is being used. • Adds Spring Social and Spring Social Twitter to classpath

2. Boot auto-config sees Spring Social on the classpath • Configures a ConnectController bean

3. Boot sees that Spring Security is not on the classpath • Configures an anonymous implementation of UserIdSource

4. Boot auto-config sees Spring Social Twitter on classpath and spring.social.twitter.appId property • Configures a TwitterConnectionFactory and a request-scoped Twitter API

binding bean 5. Boot auto-config sees spring.social.auto_connection_views property

• Configures a GenericConnectionStatusView for Twitter 36

class T{Twitter t}

Page 37: Booting up Spring Social

More Spring Boot/Spring Social Auto-Config

• Configures ProviderSignInController… • …if there is a SignInAdapter bean configured and no

ProviderSignInController bean already configured

• Configures ConnectInterceptors and DisconnectInterceptors with ConnectController…

• …if there are beans of those types declared

• Configures ProviderSignInInterceptors with ProviderSignInController…

• …if there are beans of that type declared

• Configures a UserIdSource bean based on Spring Security… • …if Spring Security is on the classpath

• Configures Spring Social’s Thymeleaf dialect… • …if Thymeleaf is on the classpath 37

Page 38: Booting up Spring Social

Demo: Spring Social Showcase

38

Page 39: Booting up Spring Social

Final thoughts

39

Page 40: Booting up Spring Social

Spring Social Today

40

Core/Web/Security 1.1.0.RELEASE

Facebook 1.1.1.RELEASE 2.0.0.M1

Twitter 1.1.0.RELEASE

LinkedIn 1.0.1.RELEASE

GitHub 1.0.0.M4

Page 41: Booting up Spring Social

What’s up next?

• Spring Boot + SocialAuthenticationFilter • Facebook API 2.0 binding release • Spring Social GitHub release and Boot-ification • Social sign-in improvements • Improved Spring for Android integration • Tutorials/guides

41

Page 42: Booting up Spring Social

Create Issues

• Core/Web: • http://jira.spring.io/browse/SOCIAL

• Facebook: • https://jira.spring.io/browse/SOCIALFB

• Twitter: • https://jira.spring.io/browse/SOCIALTW

• LinkedIn: • https://jira.spring.io/browse/SOCIALLI

• GitHub: • https://jira.spring.io/browse/SOCIALGH

42

Page 43: Booting up Spring Social

Ask and Answer Questions

• Core/Web: • http://stackoverflow.com/questions/tagged/spring-social

• Facebook: • http://stackoverflow.com/questions/tagged/spring-social-facebook

• Twitter: • http://stackoverflow.com/questions/tagged/spring-social-twitter

• LinkedIn: • http://stackoverflow.com/questions/tagged/spring-social-linkedin

• GitHub: • http://stackoverflow.com/questions/tagged/spring-social-github

43

Page 44: Booting up Spring Social

Fork/Fix/Submit Pull Request

• Core/Web: • http://github.com/spring-projects/spring-social

• Facebook: • http://github.com/spring-projects/spring-social-facebook

• Twitter: • http://github.com/spring-projects/spring-social-twitter

• LinkedIn: • http://github.com/spring-projects/spring-social-linkedin

• GitHub: • http://github.com/spring-projects/spring-social-github

44

Page 45: Booting up Spring Social

Expand Spring Social’s Reach

45

Spring Social

Core Security Web Config

Provider Bindings

Facebook Twitter

LinkedIn GitHub

TripIt (?)

Spring for Android

Spring for Android

Community-Led Projects500px

BitBucket

DropBox

Foursquare

Instagram

last.fm

Mixcloud

SoundCloud

Vkontakte

Yammer

Alfresco

Daum

Flattr

Geeklist

Intuit/QBO

Win. Live

Nk

Tumblr

Weibo

App.net

Digg

Flickr

Google

Khan Acad.

Miso

Salesforce Viadeo Xing

Your Project Here!

Page 46: Booting up Spring Social

Thank you!

46

http://projects.spring.io/spring-social/

@SpringSocial

http://facebook.com/SpringSocial