博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring security实战 2-服务端从Facebook读取用户的联系人( Authorization Code)
阅读量:6002 次
发布时间:2019-06-20

本文共 7254 字,大约阅读时间需要 24 分钟。

How to do it...

  1. 模仿之前的步骤,在Facebook创建一个新项目social- authcode 。
    输入网址地址:
    还有授权成功后的,重定向的地址::8080/connect/facebook
  2. 新建一个Spring项目
    在 网址新建一个项目,加入web,thymeleaf模块。
  3. pom.xml文件加入以下依赖:

    org.springframework.boot
    spring-boot-starter-thymeleaf
    1.5.10.RELEASE
    org.springframework.boot
    spring-boot-starter-web
    1.5.10.RELEASE
    org.springframework.boot
    spring-boot-starter-test
    1.5.10.RELEASE
    test
    org.springframework.social
    spring-social-config
    1.1.6.RELEASE
    org.springframework.social
    spring-social-facebook
    2.0.3.RELEASE
    org.springframework.boot
    spring-boot-autoconfigure
    1.5.10.RELEASE
  4. 在src/main/resources文件夹创建

friends.html文件:

Friends  

Hello,User!

Your friends which also allowed social-authcode:

[id] -
[name]

5.新建FriendsController.java ,映射friends.html页面,其中ConnectionRepository存储或重定向与某个OAuth2.0 provider的连接,目前是只展示了Facebook。

//FriendsController.java@Controller@RequestMapping("/")public class FriendsController {  @Autowired  private Facebook facebook;  @Autowired  private ConnectionRepository connectionRepository;  //链接上一步的html,  @GetMapping  public String friends(Model model) {  //如果没有获取授权,则跳到申请授权页面  if (connectionRepository.findPrimaryConnection(Facebook.class)== null) {    //就返回这个链接    return "redirect:/connect/facebook";  }  //如果已拿到授权,就从facebook获取用户和联系人信息,传给friends.html  String [] fields = { "id", "email", "name" };  //获取用户信息  User userProfile = facebook.fetchObject("me", User.class, fields);  model.addAttribute("facebookProfile", userProfile);  //获取联系人信息  PagedList
friends =facebook.friendOperations().getFriends(); model.addAttribute("friends", friends); return "friends";}}

6.上述步骤通过授权码模式,完成了从Facebook获取用户信息和联系人信息的大致过程。但是,我们还需创建一些配置类,为了更好得管理这些配置类,我们新建一个名为facebook的package,这些是我们所需的配置类:

图片描述

7.创建EnhancedFacebookProperties 类,加载client_id,client_secret,还有版本号,并把这些内容写入application.properties

//EnhancedFacebookProperties.java@Component@ConfigurationProperties(prefix = "facebook")public class EnhancedFacebookProperties {private String appId;private String appSecret;private String apiVersion;// getters and setters omitted for brevity}//application.propertiesfacebook.app-id=1948923582021549facebook.app-secret=1b4b0f882b185094a903e76a661c7c7cfacebook.api-version=2.9

8.创建CustomFacebookServiceProvider 类,用于创建一个OAuth2Template 实例

//CustomFacebookServiceProvider.javapublic class CustomFacebookServiceProvider extends AbstractOAuth2ServiceProvider
{ private String appNamespace; private String apiVersion; public CustomFacebookServiceProvider(String appId, String appSecret, String apiVersion) { super(getOAuth2Template(appId, appSecret, apiVersion)); this.apiVersion = apiVersion; } private static OAuth2Template getOAuth2Template(String appId, String appSecret, String apiVersion) { String graphApiURL = "https://graph.facebook.com/v" + apiVersion + "/"; OAuth2Template template = new OAuth2Template(appId, appSecret, "https://www.facebook.com/v" +apiVersion + "/dialog/oauth", graphApiURL + "oauth/access_token"); template.setUseParametersForClientAuthentication(true); return template; } @Override public Facebook getApi(String accessToken) { FacebookTemplate template = new FacebookTemplate(accessToken,appNamespace); template.setApiVersion(apiVersion); return template; }}

9.创建CustomFacebookConnectionFactory 类

//CustomFacebookConnectionFactory public class CustomFacebookConnectionFactory extends OAuth2ConnectionFactory
{ public CustomFacebookConnectionFactory(String appId, String appSecret, String apiVersion) { super("facebook",new CustomFacebookServiceProvider(appId, appSecret, apiVersion),new FacebookAdapter()); }}

10.创建FacebookConfiguration 类:

@Configuration@EnableSocial@EnableConfigurationProperties(FacebookProperties.class)public class FacebookConfiguration extends SocialAutoConfigurerAdapter {  @Autowired  private EnhancedFacebookProperties properties;  @Override  protected ConnectionFactory
createConnectionFactory() { return new CustomFacebookConnectionFactory(this.properties.getAppId(), this.properties.getAppSecret(), this.properties.getApiVersion()); } //提供Facebook 实例 @Bean @ConditionalOnMissingBean(Facebook.class) @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) public Facebook facebook(ConnectionRepository repository) { Connection
connection = repository.findPrimaryConnection(Facebook.class); return connection != null ? connection.getApi() : null; } //当我们使用spring social的时候,我们会使用ConnectController 类来处理重定向的问题。默认情况下,spring social会根据request URL ,自动构造redirect URL,因为这个应用程序可能藏在代理下,provider没办法识别url,因此,我们在这里手动输入 @Bean public ConnectController connectController(ConnectionFactoryLocator factoryLocator, ConnectionRepository repository) { ConnectController controller = new ConnectController(factoryLocator, repository); controller.setApplicationUrl("https://localhost:8080"); return controller; }}

11.在之前构造的FriendsController,已经完成了几乎所有的OAuth2 验证流程,但是我们还需要编写两个html文件来完成两个页面的加载,这两个页面是我们需要提供{provider}Connect 和{provider}Connected ,在本例中,是Facebook。因而,在templates/connect/文件夹新建2个文件:facebookConnect.html,facebookConnected.html,并填入以下代码:

图片描述

//facebookConnected.htmlSocial Authcode  

Connected to Facebook

Click here to see your friends.

//facebookConnect.htmlSocial Authcode

Connect to Facebook to see your contacts

Click the button to share your contacts with
social-authcode

How it works…

这一章展示了,怎样去注册应用,怎样通过Authorization Code type(授权码) 模式,来连接facebook.由于是server端的连接,比起client端的连接方式(implict grant type)更加安全。我们使用Spring Social来完成social-authcode和Facebook的会话。Spring Social提供ConnectController类来开启会话流程,处理返回数据,因而,我们也要提供页面来接收这些数据。为了

There's more…

当我们在Facebook注册了应用后,将redirect url配置为:8080/connect,为什么不使用:8080/callback?因为ConnectController可以处理/connect的endpoint,如果你不想使用Spring Social,你将要自己来验证授权码.

尽管,我们使用了Spring Social Facebook,我们依然创建了一些以“Custom”开头的类。通过这些类,我们可以定制化OAuth2Template和FacebookTemplate 实例的构建,这很重要,因为当前的FacebookTemplate 版本,可以支持这样的定制。

此外,在客户端和OAuth 2.0 Provider 的交互过程中,我们没有使用TLS/SSL,注册地址我们使用的是HTTP而非HTTPS,书中的例子是为了简单展示,才简化过程。但是在生产环境中,请使用HTTPs来保护数据。

另一件有价值的事,是使用关系数据库管理系统,来持久化你与Provider的连接,我们之前将连接保存在内存中,这意味着,一旦我们重启服务,连接就会丢失。如果你想使用数据库,那么你可能需要定义一个bean“JdbcUsersConnectionRepository ”,并且在数据库,通过如下命令构建表:

create table UserConnection (userId varchar(255) not null,providerId varchar(255) not null,providerUserId varchar(255),rank int not null,displayName varchar(255),profileUrl varchar(512),imageUrl varchar(512),accessToken varchar(512) not null,secret varchar(512),refreshToken varchar(512),expireTime bigint,primary key (userId, providerId, providerUserId));create unique index UserConnectionRank on UserConnection(userId,providerId, rank);

转载地址:http://rxdmx.baihongyu.com/

你可能感兴趣的文章
利用 CocoaPod 和 Git 管理组件中的一些细节梳理
查看>>
聊聊storm trident spout的_maxTransactionActive
查看>>
面向Vue新人:写一个简单的倒计时按钮
查看>>
关于手势处理
查看>>
super
查看>>
5G美洲白皮书:5G开源的现状(pdf)
查看>>
世界移动通信大会
查看>>
基于Spring Security Role过滤Jackson JSON输出内容
查看>>
从设计者的角度看 React
查看>>
js常见问题
查看>>
CentOS6系统编译部署LAMP(Linux, Apache, MySQL, PHP)环境
查看>>
海量大数据大屏分析展示一步到位:DataWorks数据服务对接DataV最佳实践
查看>>
PAT A1043
查看>>
JavaScript之手写Promise
查看>>
PHP_SELF变量解析和重复路径解决
查看>>
git 命令行使用(基础篇)
查看>>
Vue笔记(五)——Token&生命周期
查看>>
《前端十年心路-我把一切告诉你》的书稿大纲&问题收集
查看>>
CSS居中总结大全
查看>>
Elasticsearch 参考指南(安装X-Pack)
查看>>