spring security oauth2 0 官方例子详解

  • A+
所属分类:Java

---
title: Spring Security OAuth2.0 官方例子详解
date: 2019-01-04 16:16:47
categories: Spring Security
tags:
- format
- debug
- 详解
- token
- redirect_uri
- 授权
- xml
- properties
- 官方
- security
- oauth2.0
- 例子
- 单点登录
- Sparklr
- tonr
- photos
- 相片
- authorize
- SparklrController
- RequestMapping
- sparklrService
- getSparklrPhotoIds
- SparklrServiceImpl
- getForObject
- sparklrRestTemplate
- RestTemplate
- RestOperations
- execute
- OAuth2RestTemplate
- accessToken
- 令牌
- getAccessToken
- AuthorizationCodeAccessTokenProvider
- UserRedirectRequiredException
- OAuth2ClientContextFilter
- sendRedirect
- client_id
- respondse_type
- AuthorizationEndpoint
---

这几天需要用到单点登录,准备学习下Spring Security OAuth2.0

官方例子:https://github.com/spring-projects/spring-security-oauth

按照步骤项目跑进来后没什么问题,但是动作的过程不是太清楚,于是开始读代码。但是发现看了几遍还是一脸懵。。google后发现很少有文章写这个例子的解析,有也是泛泛而谈。

对着一些网上的解析和自己debug,终于对整个过程有了一个大致的认识。

项目跑起来后,访问http://localhost:8080/tonr2即可进入tonr的登录界面,点击login后就登录进了tonr系统,这时我们点View my Sparklr photos链接时,会到sparklr的登录界面,登录后会让我们授权,然后会返回sparklr的相片详细画面。

结合代码,具体的过程是这样的。

当我们点击View my Sparklr photos链接时,链接的地址是"/sparklr/photos"。

当tonr系统接收后这个请求时,会进入到SparklrController.java的photos方法里,因为该方法匹配了@RequestMapping("/sparklr/photos"),在此方法里会调用sparklrService.getSparklrPhotoIds()函数。

getSparklrPhotoIds()方法的实现在SparklrServiceImpl.java里。tonr里最核心的代码就是此类的getSparklrPhotoIds方法。

sparklrRestTemplate.getForObject(
URI.create(sparklrPhotoListURL), byte[].class)

这里的sparklrPhotoListURL实际上就是这个地址http://localhost:8080/sparklr2/photos?format=xml

这个地址实际上是请求sparklr系统里获取相片详细。

这个地址在哪定义的?tonr工程里的sparklr.properties文件里定义了几个需要用到的地址,除了上面这个外还包括/oauth/authorize和/oauth/token等等。

上面这行代码会调用RestTemplate类的getForObject方法。(这里需要注意:sparklrRestTemplate的类型为RestOperationsRestOperations是一个接口,而RestTemplateRestOperations的实现类)

getForObject方法的最后会调用execute方法,execute方法实际上调用的是doExecute方法。

(这里我没有搞懂:应该执行RestTemplate里doExecute方法才对啊但是根据实际debug的结果,居然是进了OAuth2RestTemplate.java类的doExecute方法里OAuth2RestTemplate类是RestTemplate的子类。估计是用了反射吧。)

好吧,下面来看OAuth2RestTemplatedoExecute方法里都做了些什么。

首先第一行代码

OAuth2AccessToken accessToken = context.getAccessToken();

会去DefaultOAuth2ClientContext取得一个accessToken,那么这个accessToken是什么呢?

简单来说,accessToken就是令牌,当用户登录了sparklr系统并授权后就会生成一个accessToken,再之后tonr凭这个accessToken就可以拿到sparklr里的相片。

好了,第一次accessToken肯定是为null的,接下来代码会直接执行父类RestTemplate的doexcute方法。

RestTemplate的doexcute方法里会执行createRequest方法,如上面一样,会执行OAuth2RestTemplate类里的createRequest方法。(不太懂)

OAuth2AccessToken accessToken = getAccessToken();

看到上面的代码了吧?getAccessToken就是取得token的核心代码。

但是spring在这个方法里又嵌套了很多层,并没有所有代码都写在这个方法里。相信看过Spring源码的同学一定对这种方式不陌生。

getAccessToken里又调用了acquireAccessToken方法。而acquireAccessToken里又调用了obtainAccessToken方法。

这里要注意的是,obtainAccessToken方法实现执行的是

AuthorizationCodeAccessTokenProvider类里的方法。

这个方法里有一个判断,如下:

if (request.getAuthorizationCode() == null) {
      if (request.getStateKey() == null) {
        throw getRedirectForAuthorization(resource, request);
      }
      obtainAuthorizationCode(resource, request);
    }

第一次进来这两个if肯定都满足,执行getRedirectForAuthorization方法,到方法里去看,会发现实际抛出的是UserRedirectRequiredException异常。

这个异常会被

ZPY

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: