Spring Social入門–第2部分

幾周前,我寫了一篇文章,展示了我認為可以使用Spring Social編寫的最簡單的應用程序。 該應用程序讀取并顯示了Twitter用戶的公共數據,并被編寫為Spring Social和社交編碼領域的介紹。 但是,讓您的應用程序顯示用戶的公共數據只是故事的一半,而且在大多數情況下,您將需要顯示用戶的私有數據。

在此博客中,我將介紹您需要在應用程序的一兩個頁面上顯示用戶的Facebook或其他軟件即服務(SaaS)提供程序數據的情況。 這里的想法是試圖演示最小的和最簡單的操作,您可以將Spring Social添加到需要用戶登錄Facebook或其他SaaS提供商的應用程序中。

創建應用

要創建該應用程序,第一步是使用SpringSource Toolkit儀表板的模板部分創建一個基本的Spring MVC項目。 這提供了一個Web應用程序,可幫助您入門。

下一步是通過添加以下依賴項來設置pom.xml

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId><version>${org.springframework.security.crypto-version}</version>
</dependency><!-- Spring Social -->
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-core</artifactId><version>${spring-social.version}</version>
</dependency>  
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-web</artifactId><version>${spring-social.version}</version>
</dependency><!-- Facebook API -->
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-facebook</artifactId><version>${org.springframework.social-facebook-version}</version>
</dependency><!-- JdbcUserConfiguration -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${org.springframework-version}</version>
</dependency> 
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>1.3.159</version>
</dependency><!-- CGLIB, only required and used for @Configuration usage: could be removed in future release of Spring -->
<dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>2.2</version>
</dependency>

…顯然,您還需要在文件的%lt; properties />部分中添加以下內容:

<spring-social.version>1.0.2.RELEASE</spring-social.version>
<org.springframework.social-facebook-version>1.0.1.RELEASE</org.springframework.social-facebook-version>
<org.springframework.security.crypto-version>3.1.0.RELEASE</org.springframework.security.crypto-version>

您會注意到,我為spring-security-crypto添加了一個特定的pom條目:這是因為我正在使用Spring 3.0.6。 在Spring 3.1.x中,它已成為核心庫的一部分。

唯一要注意的一點是,還依賴于spring-jdbch2 。 這是因為Spring的UserConnectionRepository默認實現: JdbcUsersConnectionRepository使用它們,因此即使該應用程序不對數據庫持久化任何東西,它們也是必需的(據我所知)。

班級

社交編碼功能包括四個類(其中一個是我從Keith Donald的Spring Social Quick Start Sample代碼中摘錄的):

  • FacebookPostsController
  • 社會背景
  • Facebook配置
  • UserCookieGenerator

FacebookPostsController是應用程序的業務端,負責獲取用戶的Facebook數據并將其推入模型中以供顯示。

@Controllerpublic class FacebookPostsController {private static final Logger logger = LoggerFactory.getLogger(FacebookPostsController.class);private final SocialContext socialContext;@Autowiredpublic FacebookPostsController(SocialContext socialContext) {this.socialContext = socialContext;}@RequestMapping(value = 'posts', method = RequestMethod.GET)public String showPostsForUser(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {String nextView;if (socialContext.isSignedIn(request, response)) {List<Post> posts = retrievePosts();model.addAttribute('posts', posts);nextView = 'show-posts';} else {nextView = 'signin';}return nextView;}private List<Post> retrievePosts() {Facebook facebook = socialContext.getFacebook();FeedOperations feedOps = facebook.feedOperations();List<Post> posts = feedOps.getHomeFeed();logger.info('Retrieved ' + posts.size() + ' posts from the Facebook authenticated user');return posts;}}

如您所見,從高級角度來看,我們要實現的目標的邏輯非常簡單:

IF user is signed in THEN read Facebook data, display Facebook data 
ELSE ask user to sign in when user has signed in, go back to the beginning
END IF

FacebookPostsController將處理登錄邏輯的任務委派給SocialContext類。 您可能會猜到,我從Spring真正有用的ApplicationContext中得到了此類的想法。 這里的想法是,有一個類負責將您的應用程序粘貼到Spring Social。

public class SocialContext implements ConnectionSignUp, SignInAdapter {/*** Use a random number generator to generate IDs to avoid cookie clashes* between server restarts*/private static Random rand;/*** Manage cookies - Use cookies to remember state between calls to the* server(s)*/private final UserCookieGenerator userCookieGenerator;/** Store the user id between calls to the server */private static final ThreadLocal<String> currentUser = new ThreadLocal<String>();private final UsersConnectionRepository connectionRepository;private final Facebook facebook;public SocialContext(UsersConnectionRepository connectionRepository, UserCookieGenerator userCookieGenerator,Facebook facebook) {this.connectionRepository = connectionRepository;this.userCookieGenerator = userCookieGenerator;this.facebook = facebook;rand = new Random(Calendar.getInstance().getTimeInMillis());}@Overridepublic String signIn(String userId, Connection<?> connection, NativeWebRequest request) {userCookieGenerator.addCookie(userId, request.getNativeResponse(HttpServletResponse.class));return null;}@Overridepublic String execute(Connection<?> connection) {return Long.toString(rand.nextLong());}public boolean isSignedIn(HttpServletRequest request, HttpServletResponse response) {boolean retVal = false;String userId = userCookieGenerator.readCookieValue(request);if (isValidId(userId)) {if (isConnectedFacebookUser(userId)) {retVal = true;} else {userCookieGenerator.removeCookie(response);}}currentUser.set(userId);return retVal;}private boolean isValidId(String id) {return isNotNull(id) && (id.length() > 0);}private boolean isNotNull(Object obj) {return obj != null;}private boolean isConnectedFacebookUser(String userId) {ConnectionRepository connectionRepo = connectionRepository.createConnectionRepository(userId);Connection<Facebook> facebookConnection = connectionRepo.findPrimaryConnection(Facebook.class);return facebookConnection != null;}public String getUserId() {return currentUser.get();}public Facebook getFacebook() {return facebook;}}

SocialContext實現Spring Social的ConnectionSignUpSignInAdapter接口。 它包含三個方法isSignedIn()signIn()execute()FacebookSignsController類調用isSignedIn來實現上述邏輯,而Spring Social調用signIn()execute()

從我以前的博客中,您會記住,OAuth需要在瀏覽器,您的應用程序和SaaS提供程序之間進行多次旅行。 在進行這些操作時,應用程序需要保存多個OAuth參數的狀態,例如:client_id,redirect_uri和其他參數。 通過將OAuth對話的狀態映射到您的Webapp所控制的變量,Spring Social將所有這些復雜性從應用程序中隱藏起來。 這是userId ; 但是,不要以為它是用戶名,因為用戶從未看到過它,它只是一個唯一標識符,該標識符將許多HTTP請求鏈接到Spring Social核心中的SaaS提供程序連接(例如Facebook)。

由于其簡單性,我遵循了Keith Donald的想法,即使用cookie在瀏覽器和服務器之間傳遞用戶ID來保持狀態。 我還從Spring Social Quick Start中借用了他的UserCookieGenerator類來幫助我。

isSignedIn(...)方法使用UserCookieGenerator來確定HttpServletRequest對象是否包含包含有效用戶ID的cookie。 如果這樣做的話,它還會找出Spring Social的UsersConnectionRepository是否包含鏈接到相同用戶ID的ConnectionRepository 。 如果這兩個測試都返回true,則應用程序將請求并顯示用戶的Facebook數據。 如果兩個測試之一返回false,則將要求用戶登錄。

SocialContext是專門為該示例編寫的,并且包含足夠的功能來演示我在此博客中所討論的內容。 這意味著它目前有點粗糙并且可以使用,盡管可以對其進行改進以涵蓋與任何/許多提供程序的連接,然后在不同的應用程序中重復使用。

最后要提到的類是FacebookConfig ,它大致基于Spring Social示例代碼。 此代碼與示例代碼之間有兩個主要區別,其中第一點是FacebookConfig類實現了InitializingBean接口。 這樣,可以將usersConnectionRepositiory變量注入到socialContext中, 然后可以將socialContext作為其ConnectionSignUp實現注入到usersConnectionRepositiory中。 第二個區別是我正在實現providerSignInController(...)方法,以提供正確配置的ProviderSignInController對象,Spring Social將使用該對象登錄Facebook。 我在此處所做的默認更改的唯一更改是將ProviderSignInControllerpostSignInUrl屬性設置為“ / posts ”。 這是頁面的URL,將包含用戶Facebook數據,并在用戶登錄完成后被調用。

@Configurationpublic class FacebookConfig implements InitializingBean {private static final Logger logger = LoggerFactory.getLogger(FacebookConfig.class);private static final String appId = '439291719425239';private static final String appSecret = '65646c3846ab46f0b44d73bb26087f06';private SocialContext socialContext;private UsersConnectionRepository usersConnectionRepositiory;@Injectprivate DataSource dataSource;/*** Point to note: the name of the bean is either the name of the method* 'socialContext' or can be set by an attribute* * @Bean(name='myBean')*/@Beanpublic SocialContext socialContext() {return socialContext;}@Beanpublic ConnectionFactoryLocator connectionFactoryLocator() {logger.info('getting connectionFactoryLocator');ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));return registry;}/*** Singleton data access object providing access to connections across all* users.*/@Beanpublic UsersConnectionRepository usersConnectionRepository() {return usersConnectionRepositiory;}/*** Request-scoped data access object providing access to the current user's* connections.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public ConnectionRepository connectionRepository() {String userId = socialContext.getUserId();logger.info('Createung ConnectionRepository for user: ' + userId);return usersConnectionRepository().createConnectionRepository(userId);}/*** A proxy to a request-scoped object representing the current user's* primary Facebook account.* * @throws NotConnectedException*             if the user is not connected to facebook.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public Facebook facebook() {return connectionRepository().getPrimaryConnection(Facebook.class).getApi();}/*** Create the ProviderSignInController that handles the OAuth2 stuff and* tell it to redirect back to /posts once sign in has completed*/@Beanpublic ProviderSignInController providerSignInController() {ProviderSignInController providerSigninController = new ProviderSignInController(connectionFactoryLocator(),usersConnectionRepository(), socialContext);providerSigninController.setPostSignInUrl('/posts');return providerSigninController;}@Overridepublic void afterPropertiesSet() throws Exception {JdbcUsersConnectionRepository usersConnectionRepositiory = new JdbcUsersConnectionRepository(dataSource,connectionFactoryLocator(), Encryptors.noOpText());socialContext = new SocialContext(usersConnectionRepositiory, new UserCookieGenerator(), facebook());usersConnectionRepositiory.setConnectionSignUp(socialContext);this.usersConnectionRepositiory = usersConnectionRepositiory;}}

申請流程

如果您運行此應用程序2,首先會看到一個主屏幕,其中包含一個簡單的鏈接,邀請您顯示帖子。 首次單擊此鏈接時,您將重定向/ signin頁面。 按下“登錄”按鈕,指示ProviderSignInController與Facebook聯系。 身份驗證完成后, ProviderSignInController會將應用程序定向回/ posts頁面,這一次它將顯示Facebook數據。

組態

為了完整起見,我認為我應該提到XML配置,盡管它沒有太多,因為我在FacebookConfig類上使用Spring注釋@Configuration 。 我已經從Spring Social導入了“ data.xml ”,以便JdbcUsersConnectionRepository可以工作并添加了

<context:component-scan base-package='com.captaindebug.social' />

…用于自動接線。

摘要

盡管此示例應用程序基于將應用程序連接到用戶的Facebook數據的基礎,但可以輕松地對其進行修改以使用任何Spring Social客戶端模塊。 如果您喜歡挑戰,請嘗試使用所有中文版本的Sina-Weibo,這是一個挑戰,但是Google Translate確實很有用。

1個Spring社交和其他OAuth博客:

  1. Spring Social入門
  2. Facebook和Twitter:幕后花絮
  3. OAuth管理步驟
  4. OAuth 2.0 Webapp流程概述

2該代碼可在Github上找到:https://github.com/roghughe/captaindebug.git

參考: Captain Debug的Blog博客中的JCG合作伙伴 Roger Hughes的Spring Social入門-第2部分 。


翻譯自: https://www.javacodegeeks.com/2012/07/getting-started-with-spring-social-part.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372080.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux靜默刪除文件夾,Linux常用命令10 - unzip

zip 是最廣泛使用的歸檔文件, 除了linux&#xff0c;windows也是非常的廣泛。&#xff0c;支持無損數據壓縮。 zip 文件是包含一個或多個壓縮文件或目錄的數據容器。接下來&#xff0c;我將解釋如何使用 unzip 命令通過命令行解壓縮 Linux 系統中的文件。 還有與之對應就是 zip…

Git學習筆記(一) 安裝及版本庫介紹

安裝Git 最早Git是在Linux上開發的&#xff0c;很長一段時間內&#xff0c;Git也只能在Linux和Unix系統上跑。不過&#xff0c;慢慢地有人把它移植到了Windows上。現在&#xff0c;Git可以在Linux、Unix、Mac和Windows這幾大平臺上正常運行了。 在Linux上安裝Git 首先&#xff…

python基礎:迭代器、生成器(yield)詳細解讀

1. 迭代器 迭代器是訪問集合元素的一種方式。迭代器對象從集合的第一個元素開始訪問&#xff0c;知道所有的元素被訪問完結束。迭代器只能往前不會后退&#xff0c;不過這也沒什么&#xff0c;因為人們很少在迭代途中往后退。 1.1 使用迭代器的優點 對于原生支持隨機訪問的數據…

LazyInitializationException的四種解決方案–第2部分

本文從教程??的第1部分繼續。 使用PersistenceContextType.EXTENDED的有狀態EJB加載收集 該方法只能應用于與Full JEE環境兼容的應用程序&#xff1a;將EJB與PersistenceContextType.EXTENDED一起使用。 檢查下面的代碼&#xff0c;DAO的樣子&#xff1a; package com.ejb…

Linux將硬盤轉化為pv,Linux擴展硬盤 物理卷(PV) 卷組(VG) 邏輯卷(LV)

1、給虛擬機添加兩塊新的sata虛擬硬盤&#xff0c;容量8G和10G# fdisk -l 命令2、分別在這兩個硬盤上建立pvPvcreate /dev/sdb 創建一個物理卷/dev/sdb 磁盤名是 fdisk -l 查詢出來的Pvscan 查看當前所有物理卷Pvdisplay 查看當前所有物理卷的詳情3、創建VG&#xff0c;使得…

ubuntu 16.10 shu rufa meiy ou l e geng xi zhi hou

轉載于:https://www.cnblogs.com/ganmk--jy/p/6035894.html

ZOJ Monthly, November 2012

A.ZOJ 3666 Alice and Bob 組合博弈&#xff0c;SG函數應用#include<vector> #include<cstdio> #include<cstring> #include<algorithm>using namespace std;const int maxn 10000 100; int SG[maxn]; vector<int> g[maxn];int mex(int u) { /…

使用Aspect和Spring Profile進行電子郵件過濾

在Web應用程序開發期間&#xff0c;經常需要發送電子郵件。 但是&#xff0c;有時數據庫中會包含來自生產的數據&#xff0c;并且存在在電子郵件測試執行期間向真實客戶發送電子郵件的風險。 這篇文章將解釋如何避免在沒有在發送電子郵件功能中明確編寫代碼的情況下避免這種情…

紅旗linux 進不去圖形界面,進不了紅旗Linux6.0的圖形界面請高手幫忙

習生 于 2008-11-02 11:08:42發表:引用:原帖由 zhaoruiqi 于 2008-11-2 10:03 發表 我的也是進不了圖形界面&#xff0c;用文本安裝后進系統也一樣正常按rtl的方法對xorg.conf進行修改,已經能進入圖形界面。你看看樓上rtl的回復的能否對你有幫助。zhaoruiqi 于 2008-11-02 10:0…

總結繼承的幾種方式

簡單總結繼承的幾種方式 JavaScript作為一門弱類型的語言&#xff0c;本著精簡的原則&#xff0c;它取消了類的概念&#xff0c;只有對象的概念&#xff0c; 更是有萬物皆對象的說法。在基于類的面向對象方式中&#xff0c;對象&#xff08;object&#xff09;依靠類&#xff0…

Oracle SQL精妙SQL語句講解(二)

- 如果存在就更新&#xff0c;不存在就插入用一個語句實現 DROP TABLE t_mg; CREATE TABLE t_mg(code VARCHAR2(10), NAME VARCHAR2(10)); SELECT * FROM t_mg; MERGE INTO t_mg a USING (SELECT the code code, the name NAME FROM dual) b ON (a.code b.code) WHEN M…

Spring Security –在一個應用程序中有兩個安全領域

這篇博客文章主要是關于Spring Security配置的。 更具體地說&#xff0c;它打算顯示如何在一個Web應用程序中配置兩個不同的安全領域。 第一安全領域是針對瀏覽器客戶端的。 它使我們能夠在登錄頁面中登錄并訪問受保護的資源。 第二安全領域旨在處理來自android應用程序的REST…

基于Activiti工作流引擎實現的請假審核流程

概要 本文檔介紹的是某商用中集成的Activiti工作流的部署及使用&#xff0c;該框架用的Activiti版本為5.19.0。本文檔中主要以一個請假流程為例子進行說明&#xff0c;該例子的流程圖如下&#xff1a; 這是一個可以正常運作的工作流業務了&#xff0c;但是它也有不足的地方&…

linux編譯ffmpeg成so,「ffmpeg」一 mac 環境下編譯ffmpeg,生成so庫文件

1.下載ffmpeg源碼,官網&#xff0c;我這里直接采用git 方式下載&#xff1a;下載ffmpeg.png終端輸入git命令&#xff1a;靜靜等待~最后下載的版本為3.4.6 。image.png這里注意一下&#xff0c;剛開始我用的ndk版本是ndk-17b&#xff0c;在編譯該版本的ffmpeg時始終失敗&#xf…

4Web Service中的幾個重要術語

4.1WSDL: web service definition language 直譯:Webservice定義語言 1.對應一種類型的文件.wsdl 2.定義了webservice的服務端與客戶端應用交互傳遞請求和響應數據的格式和方式 3.一個webservice對應一個唯一的esdl文檔 4.2SOAP: simple object access protocal 直譯:簡單對象訪…

云端:亞馬遜,谷歌應用引擎,Windows Azure,Heroku,Jelastic

您想在云端嗎&#xff1f; 您有很多選擇。 我已經評估或使用了許多方法&#xff0c;因此這里有幾句話。 &#xff08;當我使用Java時&#xff0c;我將包括一些與Java相關的注釋&#xff0c;但大多數情況適用于所有&#xff08;受支持的&#xff09;語言。&#xff09; 但是在深…

JS-字符串操作-替換

<!DOCTYPE HTML><html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8"><title>無標題文檔</title><style>p { border:10px solid #ccc; background:#FFC; width:400px; padding:20px;…

linux下kegg注釋軟件,KEGG數據中全部代謝反應和代謝物注釋信息的下載

# 加載函數與R包 -----------------------------------------------------------------library(KEGGREST)library(plyr)source("./RbioRXN-master/RbioRXN-master/R/get.kegg.all.R")source("./RbioRXN-master/RbioRXN-master/R/get.kegg.byId.R")## KEGG數…

java常見異常

算術異常類&#xff1a;ArithmeticExecption空指針異常類&#xff1a;NullPointerException 類型強制轉換異常&#xff1a;ClassCastException 數組負下標異常&#xff1a;NegativeArrayException 數組下標越界異常&#xff1a;ArrayIndexOutOfBoundsException 違背安全原則異常…

Spring Security 3 Ajax登錄–訪問受保護的資源

我看過一些有關Spring Security 3 Ajax登錄的博客&#xff0c;但是我找不到解決如何調用基于Ajax的登錄的博客&#xff0c;匿名用戶正在Ajax中訪問受保護的資源。 問題 – Web應用程序允許匿名訪問某些部分&#xff0c;并且某些部分是受保護的資源&#xff0c;需要用戶登錄。 …