Spring Authorization Server

2024-09-13  本文已影响0人  轻轻敲醒沉睡的心灵

Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 身份提供者和OAuth2授权服务器产品提供了一个安全、轻量级和可定制的基础。说白了,Spring Authorization Server 就是一个认证(授权)服务器。
官方文档

1. 发展

因为随着网络和设备的发展,原先的 OAuth 2.0 已经不能满足现今的需求了,OAuth 社区对 OAuth 2.0 中的几种授权模式进行了取舍和优化,并增加一些新的特性, 于是推出了 OAuth 2.1,而原先的 Spring Security OAuth 2.0 使用的是 OAuth 2.0 协议,为满足新的变化,Spring Security 团队重新写了一套叫 Spring Authorization Server 的认证授权框架来替换原先的 Spring Security OAuth 2.0。从官网中可以看到,原先的 Spring Security OAuth 2.0 已从 Spring Security 目录下被移除,接着是多出 Spring Authorization Server 作为单独项目。

2. OAuth2

2.1 OAuth2是什么
2.2 OAuth2的角色

OAuth 2协议包含以下角色:

  1. 资源所有者(Resource Owner):即用户,资源的拥有人,想要通过客户应用访问资源服务器上的资源。
  2. 客户应用(Client):通常是一个Web或者无线应用,它需要访问用户的受保护资源。
  3. 资源服务器(Resource Server):存储受保护资源的服务器或定义了可以访问到资源的API,接收并验证客户端的访问令牌,以决定是否授权访问资源。
  4. 授权服务器(Authorization Server):负责验证资源所有者的身份并向客户端颁发访问令牌。
2.3 OAuth2的使用场景

1. 开放系统间授权

2.4 OAuth2的四种授权模式

注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

2.4.1 授权码模式

授权码(authorization code),指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用,最复杂,也是最安全的,它适用于那些有后端的 Web 应用,一般是2家不同企业对接。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

授权码模式
// 第一步:A前端请求B授权码
https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read
// 第二步:B返回授权码到A的前台地址
https://a.com/callback?code=AUTHORIZATION_CODE
// 第三步:A前端发送code到A后台,A后台去B请求令牌
https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL
// 第四步:B返回令牌数据
{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read"
}
2.4.2 简化模式

有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。


隐藏式

这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

// 第一步:A 提供一个链接,要求用户跳转到 B 网站,授权用户数据给 A 网站使用
https://b.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read
// 第二步:用户跳转到 B 网站,登录后同意给予 A 网站授权。这时,B 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。
https://a.com/callback#token=ACCESS_TOKEN
// 注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
2.4.3 密码模式

密码模式一般是企业内部应用使用的,比如前台登陆,应该使用这个最多了,我们在开发自己的系统时,也是用的这个。
区别于 简化模式,密码模式 需要带 账号和密码,还有需要将client ID和client security放入请求头:
第一步:用账号密码直接请求token

// header
Authorization: Basic Base64.encode(client ID:client security)
// 请求
https://b.com/oauth/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  scope=read

第二步: 拿到token

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":7200,
  "refresh_token":"REFRESH_TOKEN"
}
2.4.4 客户端模式

凭证式(client credentials):也叫客户端模式,适用于没有前端的命令行应用,即在命令行下请求令牌。
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。由于不涉及用户,一般是服务器对服务器。

另外,当有refresh_token时,我们可以用refresh_token定时更新token,防止过期。

3. Spring Authorization Server模式

上面说了,Spring Authorization Server 提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。与2.0相比,有一些不同:

3.1 客户端模式

OAuth2.0 的客户端模式在 OAuth 2.1 中被保留了下来,客户端模式更形象的理解,应该叫“合作方模式”更为贴切,因为整个数据交互过程中,至始至终都只有服务器提供方和服务调用方,全程都未有用户的参与。客户端模式交互过程,见上文 OAuth2.0 客户端模式的讲解。

3.2 授权码模式

授权码模式交互过程,见上文 OAuth2.0 授权码模式的讲解。这里要说的是授权码模式如何拓展 PKCE。
在授权码模式的交互工程中,有一个环节比较薄弱,这个环节就是认证服务器返回授权码的过程中,如果恶意程序截取到授权码,那么恶意程序就可以进而通过授权码窃取令牌了。为了减轻这种攻击,官方增加PKCE扩展,先来看一下官方的交互图。


image.png
3.3 设备授权码模式

设备授权码模式,是一种为解决不便在当前设备上进行文本输入而提供的一种认证授权模式,例如:智能电视、媒体控制台、数字相框、打印机等。大家也可以脑补一下一些扫码登录的情形。使用设备授权码模式,有以下要求。
(1) 该设备已连接到互联网。
(2) 设备能够支持发出 HTTPS 请求。
(3) 设备能够显示或以其他通信方式将 URI 和 Code 发给用户。
(4) 用户有辅助设备(如个人电脑或智能手机),他们可以从中处理请求。
设备授权码登录官网交互图如下。


image.png
3.4 拓展授权模式

OAuth2.1 也提供拓展授权模式的操作实现。虽然 OAuth2.1 移除了密码模式(password),但是通过拓展授权模式可以实现密码模式。在实际应用中,客户端、认证服务器、资源服务器往往都是同一家公司的产品,那么这个时候,使用账号、密码进行登录的情形也比较常见,此时就需要通过拓展授权模式来实现账号、密码登录了。可以查看自定义授权模式官网文档地址

4. OpenID Connect 1.0

OpenID Connect 1.0 是 OAuth 2.0 协议之上的一个简单的身份层。其实就是客户端向认证服务器请求认证授权的时候,多返回一个 id_token,该 id_token 是一串使用 jwt 加密过的字符串。
ID Token(身份令牌)和 Access Token(访问令牌)是两个不同的令牌,它们在身份验证和访问控制的流程中发挥不同的作用。我现在只使用Access Token(访问令牌)

上一篇 下一篇

猜你喜欢

热点阅读