• 周四. 4月 25th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Auth2.0

admin

11月 28, 2021

https://oauth.net/2/

一、授权码许可(Authorization Code)

1、授权许可流程

2、 授权这个大动作的前提,肯定是小兔要去平台那里“备案”,也就是注册。注册完后,京东商家开放平台就会给小兔软件 app_idapp_secret 等信息,以方便后面授权时的各种身份校验。 

 3、授权码

OAuth 2.0 规范建议授权码 code 值有效期为 10 分钟,并且一个授权码 code 只能被使用一次。不过根据经验呢,在生产环境中 code 的有效期一般不会超过 5 分钟。

确认过授权码 code 值有效以后,应该立刻从存储中删除当前的 code 值,以防止第三方软件恶意使用一个失窃的授权码 code 值来请求授权服务。

OAuth 2.0 规范中并没有明确规定,但必须符合三个原则:唯一性、不连续性、不可猜性。

我们需要将访问令牌 access_token 值存储起来,并将其与第三方软件的应用标识 app_id 和资源拥有者标识 user 进行关系映射。也就是说,一个访问令牌 access_token 表示某一个用户给某一个第三方软件进行授权。

4、JWT  结构化令牌  https://jwt.io/

WT 这种结构化体可以分为 HEADER(头部)、PAYLOAD(数据体)和 SIGNATURE(签名)三部分。

header.payload.signature

目前 OAuth 2.0 的令牌只支持一种类型,那就是 bearer 令牌

二、其他许可类型

授权码许可(Authorization Code)类型,是 OAuth 2.0 中最经典、最完备、最安全、应用最广泛的许可类型。除了授权码许可类型外,OAuth 2.0 针对不同的使用场景,还有 3 种基础的许可类型,分别是隐式许可(Implicit)客户端凭据许可(Client Credentials)资源拥有者凭据许可(Resource Owner Password Credentials)。相对而言,这 3 种授权许可类型的流程,在流程复杂度和安全性上都有所减弱。

  1、资源拥有者凭据许可

官方软件,索要用户名和密码,grant_type=password

2、客户端凭据许可

  

如果没有明确的资源拥有者,换句话说就是,小兔软件访问了一个不需要用户小明授权的数据,比如获取京东 LOGO 的图片地址,这个 LOGO 信息不属于任何一个第三方用户,再比如其它类型的第三方软件来访问平台提供的省份信息,省份信息也不属于任何一个第三方用户。

grant_type = client_credentials  

3、隐式许可

三、PKCE 协议

First,App 自己要生成一个随机的、长度在 43~128 字符之间的、参数为 code_verifier 的字符串验证码;

Second,我们再利用这个 code_verifier,来生成一个被称为“挑战码”的参数code_challenge。

   Two ways for code_challenge。 

      1、 code_challenge_method=plain,此时 code_verifier 的值就是 code_challenge 的值;

      2、 code_challenge_method=S256,就是将 code_verifier 值进行 ASCII 编码之后再进行哈希,然后再将哈希之后的值进行 BASE64-URL 编码。

        code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

四、OpenID Connect(简称 OIDC

OIDC 是身份认证协议,且是基于 OAuth 2.0 来执行用户身份认证的互通协议。

OIDC= 授权协议 + 身份认证;

基于授权码流程的 OIDC 协议流程,跟 OAuth 2.0 中的授权码许可的流程几乎完全一致,唯一的区别就是多返回了一个 ID_TOKEN,我们称之为

ID 令牌 。

ID 令牌是一个 JWT 格式的令牌。

五、安全攻击CSRF、XSS、水平越权

1、CSRF

恶意软件让浏览器向已完成用户身份认证的网站发起请求,并执行有害的操作,就是跨站请求伪造攻击。

这个攻击过程本质上就是,软件 A(攻击者)用自己的授权码 codeA 的值,通过 CSRF 攻击,“替换”了软件 B 的授权码的值。

  那如何避免CSRF攻击呢?方法也很简单,实际上 OAuth 2.0 中也有这样的建议,就是使用 state 参数,它是一个随机值的参数。

XSS 攻击的主要手段是将恶意脚本注入到请求的输入中,攻击者可以通过注入的恶意脚本来进行攻击行为,比如搜集数据等。

XSS攻击原理分析与防御技术

水平越权是指,在请求受保护资源服务数据的时候,服务端应用程序未校验这条数据是否归属于当前授权的请求用户。

OAuth 2.0 专有的安全攻击:授权码失窃、重定向 URI 被篡改。

六、基于OAuth 2.0/JWT的微服务参考架构

公司的微服务架构,大致可以分为 Nginx 反向代理层、Web 应用层、Gateway 网关层、BEF 层和领域服务层,还包括一个 IDP 服务。

1、Nginx 反向代理层

首先,Nginx 集群是整个平台的流量入口。Nginx 是 7 层 HTTP 反向代理,主要功能是实现反向路由,也就是将外部流量根据 HOST 主机头或者 PATH,路由到不同的后端,比方说路由到 Web 应用,或者直接到网关 Gateway。在 Kubernetes 体系中,Nginx 是和 Ingress Controller(入口控制器)配合工作的(总称为 Nginx Ingress),Ingress Controller 支持通过 Ingress Rules,配置 Nginx 的路由规则。

 2、Web 应用层

html/css/js

3、Gateway 网关层

这一层是微服务调用流量的入口。网关的主要职责是反向路由,也就是将前端请求根据 HOST 主机头、或者 PATH、或者查询参数,路由到后端目标微服务(比如,图中的 IDP/BFF 或者直接到领域服务)。

另外,网关还承担两个重要的安全职责:

  • 一个是令牌的校验和转换,将前端传递过来的 OAuth 2.0 访问令牌,通过调用 IDP 进行校验,并转换为包含用户和权限信息的 JWT 令牌,再将 JWT 令牌向后台微服务传递。
  • 另外一个是权限校验,网关的路由表可以和 OAuth 2.0 的 Scope 进行关联。这样,网关根据请求令牌中的权限范围 Scope,就可以判断请求是否具有调用后台服务的权限。

另外,网关还需承担集中式限流、日志监控,以及支持 CORS 等功能。

对于网关层的技术选型,当前主流的 API 网关产品,像 Netflix 开源的 Zuul、Spring Cloud Gateway 等,都可以考虑。

4、IDP 服务

IDP 是 Identity Provider 的简称,主要负责 OAuth 2.0 授权协议处理,OAuth 2.0 和 JWT 令牌颁发和管理,以及用户认证等功能。IDP 使用后台的 Login-Service 进行用户认证。

对于 IDP 的技术选型,当前主流的 Spring Security OAuth,或者 RedHat 开源的 KeyCloak,都可以考虑。其中,Spring Security OAuth 是一个 OAuth 2.0 的开发框架,适合企业定制。KeyCloak 则是一个开箱即用的 OAuth 2.0/OIDC 产品。

5、BFF 层

BFF 是 Backend for Frontend 的简称,主要实现对后台领域服务的聚合(Aggregation,有点类似数据库的 Join)功能,同时为不同的前端体验(PC/Mobile/ 开放平台等)提供更友好的 API 和数据格式。

BFF 中可以包含一些业务逻辑,甚至还可以有自己的数据库存储。通常,BFF 要调用两个或两个以上的领域服务,甚至还可能调用其它的 BFF(当然一般并不建议这样调用,因为这样会让调用关系变得错综复杂,无法理解)。如果 BFF 需要获取调用用户或者 OAuth 2.0 Scope 相关信息,它可以从传递过来的 JWT 令牌中直接获取。BFF 服务可以用 Node.js 开发,也可以用 Java/Spring 等框架开发。

6、领域服务层

领域服务层在整个微服务架构的底层。这些服务包含业务逻辑,通常有自己独立的数据库存储,还可以根据需要调用外部的服务。

根据微服务分层原则,领域服务禁止调用其它的领域服务,更不允许反向调用 BFF 服务。这样做是为了保持微服务职责单一(Single Responsibility)和有界上下文(Bounded Context),避免复杂的领域依赖。领域服务是独立的开发、测试和发布单位。在电商领域,常见的领域服务有用户服务、商品服务、订单服务和支付服务等。

和 BFF 一样,如果领域服务需要获取调用用户或者 OAuth 2.0 Scope 相关信息,它可以从传递过来的 JWT 令牌中直接获取。

可以看到,领域服务和 BFF 服务都是无状态的,它们本身并不存储用户状态,而是通过传递过来的 JWT 数据获取用户信息。所以在整个架构中,微服务都是无状态、可以按需水平扩展的,状态要么存在用户端(浏览器或者手机 App 中),要么存在集中的数据库中。

目前主流的微服务架构大致可以分为 5 层,分别是:Nginx 流量接入层 ->Web 应用层 ->API 网关层 ->BFF 聚合层 -> 领域服务层

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注