SpringCloud(part12)Spring OAuth2--概念详解

1.应用场景

我们假设你有一个“云笔记”产品,并提供了“云笔记服务”和“云相册服务”,此时用户需要在不同的设备(PC、Android、iPhone、TV、Watch)上去访问这些“资源”(笔记,图片)

那么用户如何才能访问属于自己的那部分资源呢?此时传统的做法就是提供自己的账号和密码给我们的“云笔记”,登录成功后就可以获取资源了。但这样的做法会有以下几个问题:

  • “云笔记服务”和“云相册服务”会分别部署,难道我们要分别登录吗?
  • 如果有第三方应用程序想要接入我们的“云笔记”,难道需要用户提供账号和密码给第三方应用程序,让他记录后再访问我们的资源吗?
  • 用户如何限制第三方应用程序在我们“云笔记”的授权范围和使用期限?难道把所有资料都永久暴露给它吗?
  • 如果用户修改了密码收回了权限,那么所有第三方应用程序会全部失效。
  • 只要有一个接入的第三方应用程序遭到破解,那么用户的密码就会泄露,后果不堪设想。

为了解决如上问题,oAuth 应用而生。

2.名词解释

  • 第三方应用程序(Third-party application): 又称之为客户端(client),比如上节中提到的设备(PC、Android、iPhone、TV、Watch),我们会在这些设备中安装我们自己研发的 APP。又比如我们的产品想要使用 QQ、微信等第三方登录。对我们的产品来说,QQ、微信登录是第三方登录系统。我们又需要第三方登录系统的资源(头像、昵称等)。对于 QQ、微信等系统我们又是第三方应用程序。
  • HTTP 服务提供商(HTTP service): 我们的云笔记产品以及 QQ、微信等都可以称之为“服务提供商”。
  • 资源所有者(Resource Owner): 又称之为用户(user)。
  • 用户代理(User Agent): 比如浏览器,代替用户去访问这些资源。
  • 认证服务器(Authorization server): 即服务提供商专门用来处理认证的服务器,简单点说就是登录功能(验证用户的账号密码是否正确以及分配相应的权限)
  • 资源服务器(Resource server): 即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。简单点说就是资源的访问入口,比如上节中提到的“云笔记服务”和“云相册服务”都可以称之为资源服务器。

3. 交互过程

4.如何使用Spring OAuth2

Spring OAuth2被分为两个部分,分别是 OAuth2 Provider 和OAuth2 Client。

  • OAuth2 Provider

OAuth2 Provider负责公开被OAuth2保护起来的资源。OAuth2 Provider需要配置代表用户的OAuth2客户端信息,被用户允许的客户端可以访问被OAuth2保护起来的资源。OAuth2 Provider通过管理和验证OAuth2令牌来控制客户端是否有权限访问被保护的资源,另外OAuth2 Provider还必须为用户提供认证APi接口。根据认证的API接口,用户提供用户名和密码来确认用户是否被OAuth2授权。

授权节点:/oauth/authorize

获取token节点:/oauth/token

  • OAuth2 Client

5.令牌的访问和刷新

Access Token

我们是通过di和令牌来访问资源的,但是不能让令牌长时间有效。否则别人知道了令牌就能够直接爬虫。

http://www.funtl.com/user/1?access_token=

Refresh Token

Refresh Token 的作用是用来刷新 Access Token。认证服务器提供一个刷新接口,例如:

http://www.funtl.com/refresh?refresh_token=&client_id=

传入 refresh_tokenclient_id,认证服务器验证通过后,返回一个新的 Access Token。为了安全,oAuth2.0 引入了两个措施:

  • oAuth2.0 要求,Refresh Token 一定是保存在客户端的服务器上 ,而绝不能存放在狭义的客户端(例如 App、PC 端软件)上。调用 refresh 接口的时候,一定是从服务器到服务器的访问。
  • oAuth2.0 引入了 client_secret 机制。即每一个 client_id 都对应一个 client_secret。这个 client_secret 会在客户端申请 client_id 时,随 client_id 一起分配给客户端。客户端必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 Access Token 时,需要验证这个 client_secret

实际上的刷新接口类似于:

http://www.funtl.com/refresh?refresh_token=&client_id=&client_secret=

以上就是 Refresh Token 机制。Refresh Token 的有效期非常长,会在用户授权时,随 Access Token 一起重定向到回调 URL,传递给客户端。

2.授权方式

客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。oAuth 2.0 定义了四种授权方式。

  • implicit:简化模式,不推荐使用
  • authorization code:授权码模式
  • resource owner password credentials:密码模式
  • client credentials:客户端模式

# 简化模式

简化模式适用于纯静态页面应用。所谓纯静态页面应用,也就是应用没有在服务器上执行代码的权限(通常是把代码托管在别人的服务器上),只有前端 JS 代码的控制权。

这种场景下,应用是没有持久化存储的能力的。因此,按照 oAuth2.0 的规定,这种应用是拿不到 Refresh Token 的。其整个授权流程如下:

该模式下,access_token 容易泄露且不可刷新

# 授权码模式

授权码模式适用于有自己的服务器的应用,它是一个一次性的临时凭证,用来换取 access_tokenrefresh_token。认证服务器提供了一个类似这样的接口:

https://www.funtl.com/exchange?code=&client_id=&client_secret=

需要传入 codeclient_id 以及 client_secret。验证通过后,返回 access_tokenrefresh_token。一旦换取成功,code 立即作废,不能再使用第二次。流程图如下:

这个 code 的作用是保护 token 的安全性。上一节说到,简单模式下,token 是不安全的。这是因为在第 4 步当中直接把 token 返回给应用。而这一步容易被拦截、窃听。引入了 code 之后,即使攻击者能够窃取到 code,但是由于他无法获得应用保存在服务器的 client_secret,因此也无法通过 code 换取 token。而第 5 步,为什么不容易被拦截、窃听呢?这是因为,首先,这是一个从服务器到服务器的访问,黑客比较难捕捉到;其次,这个请求通常要求是 https 的实现。即使能窃听到数据包也无法解析出内容。

有了这个 code,token 的安全性大大提高。因此,oAuth2.0 鼓励使用这种方式进行授权,而简单模式则是在不得已情况下才会使用。

# 密码模式

密码模式中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向 "服务商提供商" 索要授权。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分。

一个典型的例子是同一个企业内部的不同产品要使用本企业的 oAuth2.0 体系。在有些情况下,产品希望能够定制化授权页面。由于是同个企业,不需要向用户展示“xxx将获取以下权限”等字样并询问用户的授权意向,而只需进行用户的身份认证即可。这个时候,由具体的产品团队开发定制化的授权界面,接收用户输入账号密码,并直接传递给鉴权服务器进行授权即可。

有一点需要特别注意的是,在第 2 步中,认证服务器需要对客户端的身份进行验证,确保是受信任的客户端。

# 客户端模式

如果信任关系再进一步,或者调用者是一个后端的模块,没有用户界面的时候,可以使用客户端模式。鉴权服务器直接对客户端进行身份验证,验证通过后,返回 token。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值