Spring Social 服务提供者框架简介

工程 | Craig Walls | 2011年3月2日 | ...

在我的上一篇文章中,我向大家介绍了 Spring Social 对流行的软件即服务 (SaaS) API(例如 Twitter、Facebook、LinkedIn 和 TripIt)的 Java 绑定。除了提供用于常见 API 操作的简单、强类型 Java 方法外,这些绑定还确保每个 HTTP 请求都包含授权您的应用程序代表用户调用 API 所需的凭据。

我的第一篇文章没有涉及的是:我们如何管理代表用户调用服务 API 所需的凭据?我很高兴地说,我们现在有了这个问题的答案。

本周早些时候,我们宣布发布 Spring Social 项目的第二个里程碑版本。Spring Social 1.0.0.M2 中最显著的新功能是引入了服务提供者“连接”框架。今天,我想向大家介绍这个框架,并向大家展示如何使用它来管理与 SaaS 提供者的“连接”。

本文中的示例来自Spring Social Showcase。要继续学习,请克隆存储库并按照自述文件构建和部署示例应用程序。

获取 Spring Social

随着 M2 版本的发布,Spring Social 已拆分为多个模块

  • spring-social-core - 服务提供者框架、OAuth 支持和核心类。
  • spring-social-web - 连接控制器和支持类型。
  • spring-social-facebook - 用于连接 Facebook 并支持通过 Facebook 登录应用程序的服务提供者实现。
  • spring-social-twitter - 用于连接 Twitter 并支持通过 Twitter 登录应用程序的服务提供者实现。
  • spring-social-linkedin - 用于连接 LinkedIn 的服务提供者实现。
  • spring-social-tripit - 用于连接 TripIt 的服务提供者实现。
  • spring-social-github - 用于连接 GitHub 的服务提供者实现。
  • spring-social-gowalla - 用于连接 Gowalla 的服务提供者实现。
  • spring-social-test - 用于测试服务提供者实现和 API 绑定的支持。

根据您的需求,您不一定需要所有这些模块。至少,您需要核心模块。您可以使用以下条目将其添加到 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 连接了。

连接 Twitter

为了帮助理解 Spring Social 的服务提供者“连接”框架带来的优势,让我们快速浏览一下展示应用程序。

登录展示示例后,您首先会看到展示支持连接的服务提供者列表:Twitter、Facebook 和 TripIt。它们都应该显示您的帐户尚未连接到任何一个。

如果您点击 Twitter 链接,您将被重定向到连接状态页面,并有机会“连接到 Twitter”。您还会看到一个复选框,如果选中,则在连接到 Twitter 后会发布一条关于 Spring Social Showcase 的推文。

点击“连接到 Twitter”按钮后(您可以决定是否选中“发布推文...”复选框),您将被重定向到 Twitter 的授权页面,该页面应如下所示

如果您已登录 Twitter,则不会显示用户名和密码字段。但在任何情况下,您都将有机会拒绝或允许展示示例访问和更新您在 Twitter 上的数据。当您点击“允许”按钮授予权限时,Twitter 将重定向回展示应用程序,并将创建展示帐户和您的 Twitter 个人资料之间的连接。您将看到一个连接状态页面,这次指示存在连接。

此时,您可以选择断开与 Twitter 的连接。但现在,返回主页,您将看到您现在已连接到 Twitter。

如果您点击“Twitter”链接(连接可用),您将转到 Twitter 展示页面,该页面显示您的个人资料图片、Twitter 显示名称和 Twitter 屏幕名称等内容。您也可以从此处选择连接另一个 Twitter 帐户(您可以将多个提供程序帐户连接到单个应用程序帐户)、断开与 Twitter 的连接或发布推文。

服务提供者“连接”框架

当您第一次点击展示示例中的“Twitter”链接时,您会看到 Twitter 的状态连接页面。此页面由 Spring Social 的ConnectController提供。ConnectController是一个 Spring MVC 控制器,它处理授权过程。对于 Twitter,这是一个 OAuth 1 授权流程。对于 OAuth 1,ConnectController支持以下流程

  • GET /connect/{provider ID} - 显示包含连接状态的页面。
  • POST /connect/{provider ID} - 启动连接流程,向提供者请求请求令牌,并重定向到提供者的授权页面。
  • GET /connect/{provider ID}?oauth_token={request token}&oauth_verifier={verifier} - 处理授权后的回调,将请求令牌和验证器交换为访问令牌,并创建连接。
  • DELETE /connect/{provider ID} - 断开与提供者的连接。

ConnectController还支持 OAuth 2 的授权流程。当针对基于 OAuth 2 的提供者(如 Facebook)进行授权时,ConnectController的流程略有不同

  • GET /connect/{provider ID} - 显示连接状态页面
  • POST /connect/{provider ID} - 使用提供者启动授权,重定向到提供者的登录和/或授权页面。
  • GET /connect/{provider ID}?code={code} - 处理来自提供者的授权回调,将代码交换为访问令牌,并创建连接。
  • DELETE /connect/{provider ID} - 断开与提供者的连接

ConnectController可以在 Spring MVC 应用程序中配置,只需添加以下<bean>元素即可


<bean class="org.springframework.social.web.connect.ConnectController">
    <constructor-arg value="${application.url}" />
</bean>

但是,如果您查看在展示示例中如何配置ConnectController,您会发现它具有一个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 的所有服务提供者实现一样,都是使用以下参数构建的

  • 应用程序的 ID 或消费者密钥。
  • 应用程序的密钥或消费者密钥。
  • 对用于持久保存连接详细信息的连接存储库 bean 的引用。

在您向服务提供者注册应用程序时,您可以获得应用程序的消费者密钥和密钥。要向 Twitter 注册应用程序,请访问https://dev.twitter.com/apps/new并填写表格。完成后,Twitter 将响应一个页面,显示有关您的应用程序的详细信息,包括消费者密钥和消费者密钥。

在这种情况下,应用程序的 Twitter 应用程序 ID 和密钥表示为占位符变量,由属性占位符配置器解析。建议您将这些详细信息外部化,因为您的生产部署与测试和开发环境的 ID/密钥对可能不同。

Spring 的每个服务提供者类都有一个提供者 ID(从其getId()方法返回,与它的 Spring bean ID 不同)。ConnectController将使用该 ID(在 URL 路径中指定)来选择在创建连接时将使用的服务提供者。对于TwitterServiceProvider,提供者 ID 为“twitter”。将此 ID 映射到ConnectController的请求映射,我们得到以下流程

  • GET /connect/twitter - 显示用户与 Twitter 的连接状态。
  • POST /connect/twitter - 从 Twitter 检索请求令牌,然后重定向到 Twitter 的授权页面。当您点击“连接到 Twitter”按钮时,流程就是转到这里的。
  • GET /connect/twitter?oauth_token={request token}&oauth_verifier={verifier} - 处理授权后的回调,将请求令牌和验证器交换为访问令牌,并创建连接。
  • DELETE /connect/twitter - 断开与 Twitter 的连接。当您点击“断开连接”按钮时,就会发生这种情况。

建立连接后,务必将其存储起来以备将来使用,这样您就不必反复要求用户重新授权您的应用程序。因此,TwitterServiceProvider依赖于连接存储库来持久保存连接信息。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 的连接过程并返回该页面后,它显示已建立连接。

展示应用程序的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的连接支持。

与往常一样,我们非常乐意听取您的反馈。我们鼓励您在论坛中与我们合作,或通过在问题跟踪中提交增强请求。

获取Spring新闻通讯

通过Spring新闻通讯保持联系

订阅

领先一步

VMware提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看Spring社区中所有即将举行的活动。

查看全部