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.mzph.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;需要用户登录。 …