领先一步
VMware 提供培训和认证,助您加速发展。
了解更多在我的上一篇文章中,我向您介绍了 Spring Social 的 Java 绑定,用于连接 Twitter、Facebook、LinkedIn 和 TripIt 等流行的软件即服务 (SaaS) API。除了为常见的 API 操作提供简单、强类型的 Java 方法外,这些绑定还确保每个 HTTP 请求都包含授权您的应用程序代表用户调用 API 所需的凭据。
我的第一篇文章没有涉及的问题是:我们如何管理代表用户调用服务 API 所需的凭据? 我很高兴地告诉大家,我们现在已经有了这个问题的答案。
本周早些时候,我们宣布发布 Spring Social 项目的第二个里程碑版本。Spring Social 1.0.0.M2 中最重要的新特性是引入了一个服务提供商“连接”(Connect) 框架。今天,我想向您介绍这个框架,并展示如何使用它来管理与 SaaS 提供商的“连接”。
本文中的示例来自 Spring Social Showcase。要跟着操作,请克隆存储库并按照 README 构建和部署示例应用程序。
在 M2 版本中,Spring Social 被分成了几个模块
根据您的需求,您不一定需要所有这些模块。至少,您需要核心模块。您可以使用以下条目将其添加到 Maven 构建的项目中
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-core</artifactId>
<version>1.0.0.M2</version>
</dependency>
如果您可能在 Web 应用程序中使用 Spring Social,您还需要 Web 模块
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-web</artifactId>
<version>1.0.0.M2</version>
</dependency>
然后,您需要添加一个或多个提供商模块。在我们的示例中,我们将讨论向应用程序添加 Twitter 连接功能,因此我们需要 twitter 模块
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-twitter</artifactId>
<version>1.0.0.M2</version>
</dependency>
由于我们基于 Spring Social 的里程碑版本进行构建,因此我们需要将 Spring 的里程碑仓库添加到 pom.xml 文件中
<repository>
<id>org.springframework.maven.milestone</id>
<name>Spring Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
请注意,尽管 Spring Social 1.0.0.M2 对 Spring Framework 3.1 有编译时依赖,但 Spring Social 在 Spring Framework 3.0.x 下也能正常工作。
在构建中解决了依赖问题后,我们就可以向应用程序添加 Twitter 连接功能了。
为了帮助理解 Spring Social 的服务提供商“连接”框架带来了什么,让我们快速浏览一下 showcase 应用程序。
登录 showcase 示例后,您首先会看到 showcase 支持连接的服务提供商列表:Twitter、Facebook 和 TripIt。它们都应该显示您的帐户尚未连接到任何一个。
如果您点击 Twitter 链接,您将被重定向到连接状态页面,并有机会“连接 Twitter”。您还会看到一个复选框,如果选中,连接到 Twitter 后将发布一条关于 Spring Social Showcase 的推文。
点击“连接 Twitter”按钮(您可以自己决定是否选中“发布推文...”复选框)后,您将被重定向到 Twitter 的授权页面,该页面应如下所示
如果您已经登录 Twitter,则不会显示用户名和密码字段。但在任何一种情况下,您都有机会拒绝或允许 showcase 示例访问和更新您在 Twitter 上的数据。当您点击“允许”按钮授予权限后,Twitter 将重定向回 showcase 应用程序,并在 showcase 帐户和您的 Twitter 个人资料之间创建一个连接。您将看到一个连接状态页面,这次表明存在连接。
此时,如果您愿意,可以选择断开与 Twitter 的连接。但现在,返回主页,您会看到您现在已连接到 Twitter。
如果您点击“Twitter”链接,并且连接可用,您将被带到 Twitter Showcase 页面,该页面显示您的个人资料图片、Twitter 显示名称和 Twitter 屏幕名称等信息。您也可以选择在此处连接另一个 Twitter 帐户(您可以将多个提供商帐户连接到单个应用程序帐户)、断开与 Twitter 的连接或发布推文。
当您首次在 showcase 示例中点击“Twitter”链接时,您看到的是 Twitter 的连接状态页面。此页面由 Spring Social 的 ConnectController
提供服务。ConnectController
是一个 Spring MVC 控制器,负责处理授权过程。对于 Twitter,这是一个 OAuth 1 授权流程。对于 OAuth 1,ConnectController
支持以下流程
ConnectController
还支持 OAuth 2 的授权流程。当针对 Facebook 等基于 OAuth 2 的提供商进行授权时,ConnectController
的流程略有不同
ConnectController
可以在 Spring MVC 应用程序中进行配置,只需添加以下 <bean>
元素即可
<bean class="org.springframework.social.web.connect.ConnectController">
<constructor-arg value="${application.url}" />
</bean>
然而,如果您查看 ConnectController
在 showcase 示例中的配置方式,您会发现它有一个 interceptors
属性,注入了一个拦截器 bean 列表。连接拦截器允许您向连接流程注入自定义功能。其中一个拦截器 TweetAfterConnectInterceptor
负责在您连接 Twitter 后发布推文。(有关连接拦截器的更多信息,请参阅参考文档。)
当请求发送到 ConnectController
时,它会与服务提供商类一起处理与服务的后台交互。对于 Twitter,该提供商类是 TwitterServiceProvider
,并在 Spring 中配置如下
<bean class="org.springframework.social.twitter.connect.TwitterServiceProvider">
<constructor-arg value="${twitter.appId}" />
<constructor-arg value="${twitter.appSecret}" />
<constructor-arg ref="connectionRepository" />
</bean>
TwitterServiceProvider
,像所有 Spring 的服务提供商实现一样,使用以下参数构造
当您向服务提供商注册应用程序时,您会获得应用程序的消费者密钥和密钥。要向 Twitter 注册应用程序,请访问 https://dev.twitter.com/apps/new 并填写表格。完成后,Twitter 会返回一个页面显示您的应用程序详细信息,包括消费者密钥和消费者密钥。
在这种情况下,应用程序的 Twitter 应用程序 ID 和密钥被表示为占位符变量,由 property placeholder configurer 解析。建议您将这些详细信息外部化,因为您的生产部署可能与测试和开发环境具有不同的 ID/密钥对。
Spring 的每个服务提供商类都有一个提供商 ID(从其 getId()
方法返回,并且与其 Spring bean ID 不同)。ConnectController
将使用 URL 路径中指定的该 ID 来选择在创建连接时使用的服务提供商。对于 TwitterServiceProvider
,提供商 ID 是“twitter”。将此 ID 映射到 ConnectController
的请求映射,我们得到以下流程
一旦建立连接,将其存储起来以备将来使用非常重要,这样您就不必反复要求用户重新授权您的应用程序。因此,TwitterServiceProvider
依赖于 connection repository 来持久化连接信息。Spring Social 提供了 JdbcConnectionRepository
,它将连接详细信息持久化到关系数据库中。JdbcConnectionRepository
bean 的配置如下
<bean id="connectionRepository" class="org.springframework.social.connect.jdbc.JdbcConnectionRepository">
<constructor-arg ref="dataSource" />
<constructor-arg ref="textEncryptor" />
</bean>
JdbcConnectionRepository
依赖于一个数据源来访问数据库,以及 Spring Security 3.1 的 TextEncryptor
接口实例。它使用文本加密器在将连接凭据(例如,访问令牌和密钥)存储到数据库中时对其进行加密。作为示例应用程序,Spring Security 的加密需求相当轻量,因此它配置了一个无操作的文本加密器
<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
factory-method="noOpText" />
(对于生产级别的加密,请考虑 Spring Security 的 Encryptors 静态工厂类提供的其他加密器之一。)
当您首次登录 Spring Social Showcase 时,它会显示一个服务提供商列表,并表明您尚未连接到其中任何一个。完成与 Twitter 的连接过程并返回该页面后,它显示已建立连接。
showcase 应用程序的 HomeController
通过调用其 isConnected()
方法来确定与每个提供商的连接状态
for (ServiceProvider<?> serviceProvider : serviceProviders) {
boolean connected = serviceProvider.isConnected(currentUser.getName());
model.addAttribute(serviceProvider.getId() + "_status", connected ? "Yes" : "No");
}
如果给定帐户与服务提供商之间存在一个或多个连接,isConnected()
方法将返回 true。
您还可以通过调用提供商的 getConnections()
方法来请求连接列表
List<ServiceProviderConnection<TwitterApi>> connections = twitterProvider.getConnections(currentUser.getName());
从这些连接中的任何一个,您可以检索服务 API。例如,从第一个连接获取 TwitterApi
的实例
TwitterApi twitter = connections.get(0).getServiceApi();
通过该 TwitterApi
对象,您可以与 Twitter 进行交互,获取时间线条目、发布推文或执行 TwitterApi
接口中定义的任何其他操作。
这里需要注意的关键一点是,应用程序代码在任何时候都不需要直接处理访问令牌和密钥来与服务交互。服务提供商框架在后台处理这些细节。
Spring Social 1.0.0.M2 提供了一个服务提供商框架,极大地简化了应用程序代表用户获取服务访问授权以及将用户的本地应用程序帐户连接到其在提供商上的帐户的角色。向 Spring 应用程序添加连接功能涉及在 Spring 应用程序上下文中将服务提供商配置为 bean,并使用 Spring Social 的 ConnectController
处理授权过程。参考文档提供了更多关于使用 Spring Social 服务提供商框架的信息。
尽管 Spring Social 1.0.0.M2 仅提供 6 个提供商(Facebook、Twitter、LinkedIn、TripIt、GitHub 和 Gowalla)的服务提供商实现,但该框架易于扩展。在后续文章中,我将向您展示如何编写自定义服务提供商实现,使您能够使用 Spring Social 的连接支持连接到您需要的任何提供商。