spring social_Spring Social入门–第2部分

spring social

几周前,我写了一篇文章,展示了我认为可以使用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快速入门中借用了他的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

spring social

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【luogu 1024 一元三次方程求解】二分思想

题目出自luogu 1024 一元三次方程求解 描述&#xff1a; 有形如&#xff1a;ax3bx2cxd0 这样的一个一元三次方程。给出该方程中各项的系数(a&#xff0c;b&#xff0c;c&#xff0c;d 均为实数)&#xff0c;并约定该方程存在三个不同实根(根的范围在-100至100之间)&#xff0c;…

linux c统计进程网络读写,linux网络分析、性能分析、文本格式化、文件读写操作之利器(mtr、top、jq、sponge)...

好的工具能够让我们工作更加高效&#xff0c;结合工作中的情况&#xff0c;今天分享下linux下比较好用的几个工具。网络分析工具mtrmtr是网络链路检测判断问题非常好用的工具&#xff0c;集成了tracert和ping这两个命令的功能&#xff0c;动态的输出检测结果。mtr 默认发送icmp…

局域网(校园网)内服务之间通过ssh -L互相访问

一、前言 同一个局域网内有两台linux服务器A和B&#xff0c;B上有一个服务&#xff0c;可以通过curl传输数据访问&#xff0c;现在想从A上也通过curl访问B上的服务 二、两种情况 1. 如果B服务器上使用docker: 首先建立docker容器时&#xff0c;需要做端口映射 docker run …

ubantu 中配置Flash Player

1.Flash只能在Chrome中使用它的最新版本。 2.如果你使用的是Firefox浏览器&#xff0c;那么你需要更换浏览器才能使用最新版本的Flash。如果你使用的Chrome浏览器&#xff0c;你只需要将它升级到最新版本就可以了。 转载于:https://www.cnblogs.com/saturnlee/p/7502158.html

实施注释界面

对于Java开发人员来说&#xff0c;每天都需要使用注释。 如果没有别的&#xff0c;简单的Override注释应该响起。 创建注释要复杂一些。 在运行时通过反射使用“自制”注释或创建编译时调用的注释处理器也是一种复杂性。 但是我们很少“实现”注释接口。 暗中有人暗地里为我们做…

C++入门经典-例2.13-左移运算

1&#xff1a;代码如下&#xff1a; // 2.13.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include<iostream> using namespace std; void main() {int a0x40,b;ba<<1;//左移1位cout << b << endl;//以十进制输出 } View Cod…

linux修改su的PAM配置文件,linux pam安全认证模块su命令的安全隐患

PAM安全认证1、su命令的安全隐患默认情况下&#xff0c;任何用户都允许使用su命令&#xff0c;从而有机会反复尝试其他用户(如root)的登录密码&#xff0c;带来安全风险。为了增强sum命令的使用控制&#xff0c;可以借助PAM认证模块&#xff0c;只允许极个别用户使用su命令进行…

jwebsocket传图片_Java中带有JWebSocket的WebServerSocket

jwebsocket传图片首先&#xff0c;转到http://jwebsocket.org/下载2个软件包Server and Client。 如果要查看源代码&#xff0c;请下载源代码包。 服务器 解压缩服务器程序包。 转到“ conf”文件夹 选择“ jWebSocket.xml”文件打开 编辑“ jWebSocket.xml”文件&#xff…

i3能装Linux虚拟机,使用i3wm重新安装Ubuntu

过去几天&#xff0c;我一直在Kubuntu 14.04.1 LTS(Ubuntu衍生产品)上使用i3wm&#xff0c;但体验有些不同。由于Ubuntu使用LightDM Display Manager&#xff0c;因此您可以安装i3wm并尝试与当前的窗口管理器一起使用。只需在外壳中使用以下命令安装适当的软件包&#xff1a;su…

99. 恢复二叉搜索树

99. 恢复二叉搜索树题意在BST中存在两个元素被交换了&#xff0c;现在需要把这两个元素给交换回来变成BST。解题思路将其转为数组&#xff0c;并且排好序后重新赋值给树结点&#xff1b;使用变量pre来保存访问的前一个结点&#xff0c;因为是中序遍历&#xff0c;所以前面一个结…

用Hamcrest验证DateTime和日期

自从我开始涉足自动化测试和练习TDD以来&#xff0c;验证日期值很痛苦。 幸运的是&#xff0c;这里有一个不错的库&#xff0c;可用于遗留Date和新的Java 8 DateTime API &#xff0c;从而解决了这一难题。 如果您属于Java开发社区中较健康的部分&#xff0c;并且每天练习单元…

linux找回rm的文件夹,Linux rm 文件恢复

Linux下删除命令 rm 大家肯定是熟悉得不能再熟悉了&#xff0c;然后有时候却阴沟里翻船不小心删除了某些重要的文件&#xff0c;想死的心都有了。。。。现在我们就来看看被误删除的文件要如何恢复&#xff1f;Linux文件系统Linux的文件系统(如ext3、ext4)由三部分组成&#xff…

linux xargs命令,xargs 命令教程

xargs是 Unix 系统的一个很有用的命令&#xff0c;但是常常被忽视&#xff0c;很多人不了解它的用法。本文介绍如何使用这个命令。一、标准输入与管道命令Unix 命令都带有参数&#xff0c;有些命令可以接受"标准输入"(stdin)作为参数。$ cat /etc/passwd | grep root…

java 职责链模式_Java中的责任链模式

java 职责链模式当应有几个处理器来执行某项操作并为这些处理器定义特定顺序时&#xff0c;就需要采用责任链设计模式。 在运行时处理器顺序的可变性也很重要。模式的UML表示如下&#xff1a; 处理程序定义处理器对象的一般结构。 这里的“ HandleRequest”是抽象处理器方法。 …

ArcMap 导入Excel坐标数据

1 准备Excel坐标数据集合 2 ArcMap加入Excel数据 将excel文件放入arcmap工作区的物理路径下在工作区的根图层上点键&#xff0c;选择添加数据&#xff0c;找到excel文件并选择相应的工作薄完成后&#xff0c;excel工作薄即导入工作区左边的图层下。3 ArcMap加入图层文件 在S…

linux6如何分区,CentOS6.9安装 硬盘分区方案与分区步骤

Linux默认可分为3个分区&#xff0c;分别是boot分区、swap分区和根分区&#xff1a;1、swap&#xff1a;交换分区&#xff0c;实现虚拟内存&#xff0c;建议大小是物理内存的1~2倍。2、/boot&#xff1a;用来存放与系统启动有关的程序&#xff0c;比如启动引导装载程序等&#…

实施自定义JMeter采样器

随着我们采用不同的体系结构和实现方式&#xff0c;对通用压力测试工具的需求不断增长。 Apache Jmeter是进行负载测试时最著名的工具之一。 它支持许多协议&#xff0c;例如ftp http tcp&#xff0c;并且可以轻松地用于分布式测试。 Jmeter还为您提供了一种创建自定义采样器…

hdu 6194 后缀数组

题意&#xff1a;一个字符串&#xff0c;查询恰好出现k次的子串的数目 思路&#xff1a;后缀数组在height上进行操作。我们直接枚举长度为k的区间求min值&#xff0c;但是要注意的是直接这么算是会重复的&#xff0c;同时也可能超过k次&#xff0c;这样我们就需要把枚举的前一个…

linux grep命令 例子,14个grep命令使用例子

所有的类linux系统都会提供一个名为grep(global regular expression print&#xff0c;全局正则表达式输出)的搜索工具。grep命令在对一个或多个文件的内容进行基于模式的搜索的情况下是非常有用的。模式可以是单个字符、多个字符、单个单词、或者是一个句子。当命令匹配到执行…

JSP动作元素

https://www.w3cschool.cn/jsp/jsp-actions.html JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。 动作是第三种类型的语法元素&#xff0c;它们被转换成java代码来执行操作。如访问一个java对象或调用方法 利用JSP动作可以动态地插入文件、重用JavaBean组件…