Spring Authorization Server (一)相关概念介绍
标签: Spring Authorization Server (一)相关概念介绍 架构博客 51CTO博客
2023-07-17 18:24:09 729浏览
本篇是Spring Authorization Server系列的开篇,主要是先介绍Spring Authorization Server相关的一些概念。
Spring Authorization Server是什么?
Spring Authorization Server是一个框架,它提供了OAuth 2.1和OpenID Connect 1.0规范以及其他相关规范的实现。它建立在Spring Security之上(如果对Spring Security不了解的,可以阅读本人写的《Spring Security+JWT 之心诚则灵》),为构建OpenID Connect 1.0身份提供者和OAuth2授权服务器产品提供了一个安全、轻量级和可定制的基础。说白了,Spring Authorization Server就是一个认证服务器。
为什么有Spring Authorization Server?
因为随着网络和设备的发展,原先的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作为单独目录。
下面是Spring Security OAuth的公告
OAuth 2.0介绍
OAuth 2.0是一种认证授权协议标准,有客户端模式(client_credentials)、密码模式(password)、简化模式(implicit)、授权码模式(authorization_code)、token刷新模式(refresh_token)。介绍OAuth 2.0前,先介绍一下OAuth 2.0的几种角色。
客户端(client):使用认证服务器作为认证渠道的平台,一般指的是第三方应用。例如,微信提供OAuth 2.0认证平台,我们的APP支持微信登录,那么我们的APP对于微信服务来说就是客户端。又例如,我们是政府某一平台的服务,我们平台维护的数据代表着足够高的权威,那么其他政府部门或合作方,需要从我们的平台中查询数据,或者利用我们平台的认证进行登录,那么其他部门或合作方的应用就是客户端。
资源服务器(resource server):简单的说,就是提供接口给客户端访问的服务器,访问资源服务器上受保护的接口,则需要带上令牌(token)。例如分布式微服务中的用户服务、订单服务等部署的服务器都属于资源服务器。
资源所有者(resource owner):拥有该资源的主体对象,一般指用户。客户端向资源服务器请求获取用户数据时,资源所有者参与确认授权或拒绝操作。
认证服务器(authorization server):对客户端和用户进行身份认证、授权的服务器,认证授权成功,则颁发令牌(token)。
客户端模式
官网交互图如下。
客户端模式是安全级别最低而且要求认证服务器对客户高度信任的模式,因为客户端向认证服务器请求认证授权的过程中,至始至终都没有用户的参与,未经过用户允许,客户端凭提供自己在认证服务器注册的信息即可在认证服务器完成认证授权,而客户端获得认证授权以后,则拥有从资源服务器操作用户数据的权限,这种模式一般应用于公司内部系统或者有着高度保密责任的合作伙伴之间的对接。客户端模式的时序图如下。
1:客户端首先在认证服务器注册好客户端信息。
2:认证服务器存储维护客户端信息。
3:客户端带上client_id、client_secret、grant_type(写死client_credentials)等参数向认证服务器发起获取token请求。
4:认证服务器校验客户端信息,校验通过,则发放令牌(access_token),校验失败,则返回异常信息。
5:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。
密码模式
官网交互图如下。
密码模式是一种安全级别较低而且要求资源拥有者(用户)完全信任客户端的模式,该模式可以理解为在客户端模式的基础上增加了对用户的账号、密码在认证服务器进行校验的操作,是客户端代理用户的操作。在OAuth 2.1中,密码模式已经被废除,在第三方平台上,使用密码模式,对于用户来说是一种非常不安全的行为,假设某平台客户端支持QQ登录,用户使用自己QQ的账号、密码在该平台上输入进行登录,则该平台将拥有用户QQ的账号、密码,对于用户来说,将自己QQ的账号、密码提供给第三方平台,这种行为是非常不安全的。密码模式一般适合应用在自己公司内部使用的系统和自己公司的app产品,例如一些ERP、CRM、WMS系统,因为都是自己公司的产品,这种情况下就不存在用户提供账号、密码给第三方客户端进行代理登录的情形了。密码模式的时序图如下。
1:客户端首先在认证服务器注册好客户端信息。
2:认证服务器存储维护客户端信息。
3:用户提供认证平台的账号、密码给客户端(这里的客户端可以是浏览器、APP、第三方应用的服务器)。
4:客户端带上client_id、client_secret、grant_type(写死password)、username、password等参数向认证服务器发起获取token请求。
5:认证服务器校验客户端信息,校验失败,则返回异常信息,校验通过,则往下继续校验用户验账号、密码。
6:认证服务器校验用户账号、密码,校验通过,则发放令牌(access_token),校验失败,则返回异常信息。
7:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。
授权码模式
官网交互图如下。
授权码模式是OAuth 2.0协议中安全级别最高的一种认证模式,他与密码模式一样,都需要使用到用户的账号信息在认证平台的登录操作,但有所不同的是,密码模式是要求用户直接将自己在认证平台的账号、密码提供给第三方应用(客户端),由第三方平台进行代理用户在认证平台的登录操作;而授权码模式则是用户在认证平台提供的界面进行登录,然后通过用户确认授权后才将一次性授权码提供给第三方应用,第三方应用拿到一次性授权码以后才去认证平台获取token。授权码模式的时序图如下。
1:客户端首先在认证服务器注册好客户端信息。
2:认证服务器存储维护客户端信息。
3:用户在客户端上发起登录。
4:向认证服务器发起认证授权请求,例如http://localhost:9000/auth/oauth/authorize?client_id=xxx&response_type=code&scope=message.read&redirect_uri=http://www.baidu.com,注意,此时参数不需要client_secret。
5:认证服务器带上客户端参数,将操作引导至用户授权确认页面,用户在该页面进行授权确认操作。
6:用户在授权页面选择授权范围,点击确认提交,则带上客户端参数和用户授权范围向认证服务器获取授权码。注意,此处操作已经脱离了客户端。
7:认证服务器校验客户端信息和授权范围(因为客户端在认证平台注册的时候,注册信息包含授权范围,如果用户选择的授权范围不在注册信息包含的范围内,则将因权限不足返回失败)。
8:校验通过,将授权码拼接到客户端注册的回调地址返回给客户端。
9:客户端拿到认证服务器返回的授权码后,带上客户端信息和授权码向认证服务器换取令牌(access_token)。
10:认证服务器校验授权码是否有效,如果有效,则返回令牌(access_token);如果无效,则返回异常信息。
11:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。
简化模式
官网交互图如下。
简化模式(也叫隐式模式)是相对于授权码模式而言的,对授权码模式的交互做了一下简化,省去了客户端使用授权码去认证服务器换取令牌(access_token)的操作,即用户在代理页面选择授权范围提交授权确认后,认证服务器通过客户端注册的回调地址直接就给客户端返回令牌(access_token)了。简化模式时序图如下。
1:客户端首先在认证服务器注册好客户端信息。
2:认证服务器存储维护客户端信息。
3:用户在客户端上发起登录。
4:向认证服务器发起认证授权请求,例如http://localhost:9000/auth/oauth/authorize?client_id=xxx&response_type=token&scope=message.read&redirect_uri=http://www.baidu.com,注意,此时参数不需要client_secret。
5:认证服务器带上客户端参数,将操作引导至用户授权确认页面,用户在该页面进行授权确认操作。
6:用户在授权页面选择授权范围,点击确认提交,则带上客户端参数和用户授权范围向认证服务器获取令牌(access_token)。注意,此处操作已经脱离了客户端。
7:认证服务器校验代理页面提交的参数信息,校验通过,则将令牌(access_token)拼接到客户端注册的回调地址返回给客户端;校验失败,则返回异常信息。
8:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。
token刷新模式
官网交互图如下。
token刷新模式是对access_token过期的一种补办操作,这种补办操作,减少了用户重新操作登录的流程。OAuth 2.0在给客户端颁发access_token的时候,同时也给客户端发放了refresh_token,而refresh_token的有效期要远大于access_token的有效期。当客户端带着已过期的access_token去访问资源服务器中受保护的资源时,将会访问失败,此时就需要客户端使用refresh_token去获取新的access_token。客户端端获取到新的access_token后,就可以带上他去访问资源服务器中受保护的资源了。token刷新模式时序图如下。
1:客户端向认证服务器请求认证授权。
2:认证服务器存返回access_token、refresh_token、授权范围、过期时间。
3:access_token过期后,客户端仍旧带着过期的access_token去请求资源服务器中受保护的资源。
4:资源服务器提示客户端,这是非法的access_token。
5:客户端使用refresh_token向认证服务器获取新的access_token。
6:认证服务器校验refresh_token的有效性,校验通过,则给客户端颁发新的access_token;校验失败,则返回异常信息。
7:客户端成功获取到新的access_token后,就可以带着新的access_token去访问资源服务器了。
OAuth 2.1介绍
OAuth 2.1去掉了OAuth2.0中的密码模式、简化模式,增加了设备授权码模式,同时也对授权码模式增加了PKCE扩展,下面对OAuth 2.1中的认证授权模式进行一些讲解。
客户端模式
OAuth2.0的客户端模式在OAuth 2.1中被保留了下来,客户端模式更形象的理解,应该叫“合作方模式”更为贴切,因为整个数据交互过程中,至始至终都只有服务器提供方和服务调用方,全程都未有用户的参与。客户端模式交互过程,见上文OAuth2.0客户端模式的讲解。
授权码模式
授权码模式交互过程,见上文OAuth2.0授权码模式的讲解。这里要说的是授权码模式如何拓展PKCE。
在授权码模式的交互工程中,有一个环节比较薄弱,这个环节就是用户在代理页面确认授权的时候,容易受到恶意程序的攻击,从而导致授权码被恶意程序窃取,进而通过授权码窃取令牌,当然这个前提也需要恶意程序已经植入到你的PC或手机当中。首先,来看一下官网中描述的恶意程序拦截攻击授权码的交互图。
(1)客户端向认证服务器发起获取授权码请求时,跳转至授权确认页面,用户通过用浏览器在授权页面进行授权确认。
(2)授权页面向认证服务器提交客户端参数和授权范围。
(3)认证服务器将授权码拼接在客户端注册的回调地址中返回给客户端。
(4)在步骤(3)认证服务器返回授权码的过程中,如果恶意程序截取到授权码,那么他接下来就可以继续操作步骤(5)、步骤(6)了。
为了减轻这种攻击,官方增加PKCE扩展,先来看一下官方的交互图。
上面交互,官网解释如下。
A. The client creates and records a secret named the "code_verifier" and derives a transformed version "t(code_verifier)" (referred to as the "code_challenge"), which is sent in the OAuth 2.0 Authorization Request along with the transformation method "t_m".
B. The Authorization Endpoint responds as usual but records "t(code_verifier)" and the transformation method.
C. The client then sends the authorization code in the Access Token Request as usual but includes the "code_verifier" secret generated at (A).
D. The authorization server transforms "code_verifier" and compares it to "t(code_verifier)" from (B). Access is denied if they are not equal.
An attacker who intercepts the authorization code at (B) is unable to redeem it for an access token, as they are not in possession of the "code_verifier" secret.
本人用大白话再解释一遍。
A. 客户端通过“/oauth2/authorize”地址向认证服务器发起获取授权码请求的时候增加两个参数,即code_challenge和code_challenge_method,其中,code_challenge_method是加密方法(例如:S256或plain),code_challenge是使用code_challenge_method加密方法加密后的值。
B. 认证服务器给客户端返回授权码,同时记录下code_challenge、code_challenge_method的值。
C. 客户端使用code向认证服务器获取Access Token的时候,带上code_verifier参数,其值为步骤A加密前的初始值。
D. 认证服务器收到步骤C的请求时,将code_verifier的值使用code_challenge_method的方法进行加密,然后将加密后的值与步骤A中的code_challenge进行比较,看看是否一致。
上面交互过程中,恶意程序如果在B处截获授权码后,使用授权码向认证服务器换取Access Token,但由于恶意程序没有code_verifier的值,因此在认证服务器无法校验通过,从而获取Access Token失败。
对于如何创建code_challenge的值,官网给出了下面两种对应的方法。
plain code_challenge = code_verifier
S256 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
设备授权码模式
设备授权码模式,是一种为解决不便在当前设备上进行文本输入而提供的一种认证授权模式,例如:智能电视、媒体控制台、数字相框、打印机等。大家也可以脑补一下一些扫码登录的情形。使用设备授权码模式,有以下要求。
(1) 该设备已连接到互联网。
(2) 设备能够支持发出HTTPS请求。
(3) 设备能够显示或以其他通信方式将URI和Code发给用户。
(4) 用户有辅助设备(如个人电脑或智能手机),他们可以从中处理请求。
设备授权码登录官网交互图如下。
(A)客户端带上包含客户端信息的参数向认证服务器(地址:/oauth2/device_authorization)发起授权访问。
(B)认证服务器给客户端返回设备码、用户码及需要用户验证用户码的URI。
(C)客户端指示用户需要在另一设备进行访问授权的URI和用户码。
(D)用户根据URI打开页面,输入用户码和确认授权,向认证服务器发起认证请求。
(E)客户端在完成步骤(C)之后就开始带上客户端信息和设备码向认证服务器轮询获取令牌信息。
(F)认证服务器收到客户端使用设备码获取令牌信息的请求后,检查用户是否已提交授权确认,如果用户已提交授权确认,则返回令牌信息。
token刷新模式
见上文OAuth2.0 token刷新模式的讲解。
拓展授权模式
OAuth2.1也提供拓展授权模式的操作实现。虽然OAuth2.1移除了密码模式(password),但是通过拓展授权模式可以实现密码模式。在实际应用中,客户端、认证服务器、资源服务器往往都是同一家公司的产品,那么这个时候,使用账号、密码进行登录的情形也比较常见,此时就需要通过拓展授权模式来实现账号、密码登录了。自定义授权模式官网文档地址为:https://docs.spring.io/spring-authorization-server/docs/current/reference/html/guides/how-to-ext-grant-type.html。
OpenID Connect 1.0
OpenID Connect 1.0是OAuth 2.0协议之上的一个简单的身份层。其实就是客户端向认证服务器请求认证授权的时候,多返回一个id_token,该id_token是一串使用jwt加密过的字符串,如下如所示。
OpenID Connect 1.0的交互过程如下。
OP:OpenID Provider,即 OAuth 2.0 中的认证服务器。
RP:Relying Part,即 OAuth 2.0 中的客户端。
关于OpenID Connect 1.0,详细见:https://openid.net/specs/openid-connect-core-1_0.html
总结
本篇主要是对Spring Authorization Server的一些概念和相关的交互流程做了一下简单的介绍,先为后续的篇章做一些理论基础的铺垫,接下来的一章,我们就进入了实操环节讲解。
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论