网站架构安全认证

第四章、可编程网关设计实践


一、网关和BFF 演化过程

无线BFF,为前端开发的后端,主要由 前端团队开发。

BFF 可以认为是一种 代理适配服务,它可以将后端服务进行 聚合、适配、裁剪、 这样可以为无线设备提供设备友好,方便无线设备接入访问后端的服务。

架构的好处:

  • 无线APP 和内部服务 不强耦合,通过BFF可以两边独立变化
  • 前后端业务发生变化,可以通过BFF 减少前后端沟通成本
  • 无线APP 只需要知道无线BFF 的域名,不需要知道内部服务域名,域名也只需要一个BFF的,域名开销比较小
  • 内部服务躲在无线BFF 后面,不会暴露在公网上,提高了安全性

随着业务的增加,带来的问题如下:

  • 无线BFF 的单块,堆砌了大量不同业务逻辑,变得越来越臃肿。
  • 根据康威法则,单块的无线BFF 和多团队之间沟通成本变高,交付效率变低。
  • 引入了很多 跨横切面 的逻辑(即cross cutting),如安全认证,日志监控,限流熔断等。
  • 无线BFF 始终是一个适配单点,如果有一个流量洪峰,则有可能出现无线集群宕机等风险。

二、 解决无线BFF 问题

  • 1.单块BFF 进行解耦拆分,针对不同业务线,引入 独立的BFF 集群
  • 2.在内部内部BFF 之前,再引入一层 网关(gateway),网关专门负责跨横切面的功能。

好处:

  • 独立BFF 解耦后,每个业务团队可以独立开发自己的BFF。
  • 网关由独立的团队开发,专注跨横切面 的功能,如路由、认证鉴权、监控性能、调用链监控、限流熔断、防爬虫等。

当代互联网架构

服务器端 BFF 也可以看做一种特殊BFF 层,只是他输出的是HTML,不是Json 而已。

三、网关和反向代理的区别

背景: web1.0、2.0 早期时代,主要是以网站形式呈现出来,大多采用 前置反向代理,主要就是 反向代理和负载均衡,典型的有NgixHA Proxy,这些产品成熟稳定性能高,一般由运维团队管理。

如今: 如今进入微服务时代,对 路由配置、安全要求很高,这个时候就出现了很多矛盾,如传统反向代理不灵活,传统运维方式效率低下,
研发人员无法做到自配置,为了解决这些问题,网关就诞生了。网关主要面向微服务,可以提供更灵活的,由研发团队自配置的能力,Netflix zuul 就是这样的网关。

注意: 反向代理能做的,网关也能做,由此就有了两套,但是随着技术的发展,对网关要求更高,不仅要求 动态可配置
而且要求动态可编程,所以面向 云原生 的产品,出现了很多 统一代理 的概念,如 envoy, Traefik

四、网关该不该分集群部署

说明: 早期、网关和反向代理是分开的,微服务躲在网关后面,单页应用和Web 应用一般躲在反向代理后面,网关一般可以分集群部署,如H5网关、web APP网关等,这种部署架构相对来说比较复杂,反向代理和网关都有,维护成本高,如果反向代理和网关不在同一个域 中,还要解决 跨域 的问题。

统一网关部署:

为了解决上述分两套的网关的问题,采用统一网关,架构就比较简单,所有应用同于部署,没有跨域问题,只要应用在同一个根域下。
对于Web 、单页应该、微服务来说,他们也有一些差异化需求的,如网关统一错误处理,web错误一般是错误页面,api出错,一般是json 数据,
要不要分集群,主要看你公司业务大小,业务小不建议分集群,逐步规模之后建议是要分集群。

五、Faraday 网关内核设计

路由映射表,是关键,常见的有基于域名,或者基于HTTP 头,或者基于请求参数,我们的是基于域名的路由,所以映射表里存放的是HTTP 头,

和路由映射表对应的,还有一个 Http Client 映射表,它里面存放了service服务 和实际访问的 http client 的映射关系。

如果路由表有更新,则Http Client也会有更新

路由配置表,例如本地的一个路由配置表

第五章、网站安全架构


一、单块阶段

1、认证阶段

1.1 什么是认证和授权?

  • 认证:识别你是谁, 英文叫 Authorization,在网站上识别某个用户是否是合法的用户。
  • 授权:授权就是指你能做什么,能有什么权限。

1.2 认证阶段具体过程

  • 传统认证: 通过 服务器端session + 浏览器端cookie 来实现。 那么服务器是怎么知道用户需要登录,或者说用户登录后不需要再登录呢?
  • 答: 用户通过浏览器,输入用户名密码,查表后通过校验后,会在服务器端写一个session,会写一个session ID 和用户的记录(类似hashtable),之后服务器端会给客户端把这个 session ID 给返回,浏览器端会以cookie的形式,种到浏览器端。

2、访问阶段

2.1 访问阶段具体过程

  • 登录完当用户要去访问这个网站时,浏览器会自动会把这个session ID 以cookie的形式,发送到后端,后端一旦能校验通过这个session,
    则认为是登录后的用户,不需要重新登录,直到session过期。 其中session是可以存储一些用户信息的,如userId 等。

  • 如果session过期,则会强制让用户登录退出,下次登录重新更新session的过期时间,如果用户长期不刷新页面,则session过期后也会让用户重新登录。

3、粘性会话

3.1 V1 版本上线后,有一些Bug 出现,具体表现为:

  • 登录随意退出:莫名其妙用户退出登录,原因是因为session每次只存在于一台服务器上,后台是集群的形式,跳server则找不到session导致退出登录。

  • 解决这个问题的方案,有一种手段是粘性会话,将用户的会话,黏住在某一台服务器。

3.2 粘性会话的问题:

  • 1.稳定性问题: 服务器正常升级时,或者down机,一波用户的会话则会瞬间消失,必须重新登录,造成用户体验差

  • 2.部分用户访问慢: 某些用户感觉有时候很慢,大多数用户觉得是挺快的,原因是后台访问觉得慢的用户,被黏在那台慢的服务器上而下不来。

4、如何解决粘性会话

4.1 如何来解决粘性会话带来的问题呢?

  • 1.会话同步复制: 每一台机器上的会话,都会同步到其他服务器上,不好的是引入复杂的状态同步机制,扩展性变差。

  • 2.无状态会话法: 会话session不存在服务器端,而存储在浏览器端,通过请求响应捎带来传递数据,不好的是cookie存在浏览器中是有风险的,一般需要加密,在一个cookie不能存储大数据,一般最大4K

  • 3.集中会话技术,如下图:

通过缓存Redis,将用户的会话存储在后台的一个Redis缓存中,好处是 LB 和 server集群都不用去存储会话,当需要session ID 时,只需要去Redis中去获取即可,这样server集群的水平扩展性提高了。

二、微服务阶段

1、微服务应用场景

2、微服务3.0认证体系

2.1 登录认证抽成一个独立的service,依赖独立的DB:

这个service独立承担如下职责:

  • 登录认证
  • 令牌颁发、令牌校验
  • 会话管理

服务鉴权: 服务鉴权认证主要是使用了token作为校验,这个令牌是一个透明令牌,所谓透明令牌,就是一个随机的无异议的字符串,和一次会话相互关联,下次访问也可以通过这个令牌访问。

登录的整个流程:

  • 1.用户通过某种平台登录,通过后,调用Auth Service,校验通过后在服务器上建立一个session(有过期时间),并生成令牌。
  • 2.校验通过颁发令牌,拿到颁发好的令牌,将token令牌 种到客户端,根据不同平台,例如种到cookie中。
  • 3.客户端使用token,去调用后端微服务。
  • 4.后端微服务拿到token后去调用 Auth Service 校验Auth token是否合法。
  • 5.校验token合法后,可以拿到一些user info的信息,去后台service做一些业务逻辑,如Auth 鉴权。
  • 6.将处理好的业务逻辑的response 返回。

  • 好处:

    • 1.认证鉴权全部放到单独的 Auth Service,通过扩展后,还可以实现SSO (单点登录)
    • 2.引入令牌,类似session ID
  • 不好:

    • 1.每个微服务,都要实现认证授权的功能,给开发方带来一定复杂性,不能让开发方很好的聚焦业务逻辑。
    • 2.认证鉴权放到每个微服务中,开发不统一,不容易规范,容易出错。

3、解决3.0中问题,V3.5

引入网关 gateway 来解决上述问题,

3.1.认证授权集中在网关上做

  • 网关可以截获令牌,并且集中到auth service上集中校验。
  • 网关可以从Auth Service 上获取请求相关的 user info,再接着向后台转发,因为网关和微服务之间是相互信任的,微服务就不需要单独去Auth Service 上认证鉴权了。

不好处:

  • 框架比较重,实现比较复杂。
  • 对Auth Service 的压力比较大,每次认证授权都得过Auth Service。

4、轻量级 JWT 认证

Auth Service 的本质,还是一个集中状态认证架构,这种架构适合于大部分比较严格的微服务认证场景,这种框架的劣势是 Auth Service 的压力会比较大,很可能造成网站性能瓶颈。对于 安全要求不太高的场景,可以采用 JWT 令牌校验

3.2.重构后的V3.6 架构

  • JWT 不是一个透明令牌,它是自包含数据和签名信息的。
  • 优化后,如第4步,网关不需要再去 Auth Service 做认证,因为JWT 自包含数据和签名,网关就只去解析这个JWT 令牌就可以了,不需要再去
    Auth Service 中去认证再去拿 user info 等动作,从而减小了 Auth Service 的压力。

说明:总体是一种 高性能可扩展 的认证架构,适用于安全要求不太高的场景。

5、 JWT 原理

概念: JWT 即 Json Web Token,它是 RFC7519 定义的一个开放标准,它定义了一个 紧凑的信息传输方式,通过他可以在多个系统间安全的传递信息,它是 可信任 的,主要用于 认证授权、信息交互

结构: Header + Payload(消息体) + Signature(签名),中间使用 . 来区分

JWT 令牌是公开可见的,任何人拿到JWT 令牌,都可以去 jwt.io 上面去解密,看到其中内容,所以 JWT不能保证信息的保密性
但是他可以 保证信息的 可依赖性不可篡改性,类似现实生活中的支票签名。


6、JWT 的流程

6.1.HMAC 流程

注意: Auth Server 和 Resource Server(微服务)需要提前声明一个用于解签的 secret,必须严格保密。

  • 1.用户通过client发送登录请求
  • 2.Auth Server 校验通过后,生成JWT数据结构,使用 HMAC 算法 生成 JWT token,返回给客户端。
  • 3.客户端将token存储起来,如cookie存储,在请求后台微服务,一般会带上这个JWT,调用后台service。
  • 4.resource(后台service)在拿到这个token后通过声明好的secret 进行解签,拿到 JWT 信息后处理逻辑后返回数据到client。

6.2.RSA 流程

与HMAC 区别就在于,secret采用 RSA 公钥和私钥 这种签名算法(公私钥成对出现)

  • Auth Server 使用 private key 私钥
  • resource Server 使用 public key 公钥

注意: 只有在 Auth Server 上保存私钥,保密性好,公钥在 是公开的,resource server拿到公钥,最多可以做解签校验,不能够篡改,加签,相比来说,HMAC 比 RSA 要简单。

JWT 优劣###

  • 好处:

      1. 紧凑轻量,尤其适合无线传输的场景。
      1. 对Auth Server 压力小
      1. 简化Auth Server 的实现,微服务可以不用再Auth Server 上去校验令牌,因为他是自校验的。
  • 不足:

      1. 无状态和吊销无法两全,比方说黑客在攻击,很难吊销他的JWT,只能等到令牌过期后吊销。假设Auth Server 上更新了令牌,老的令牌必须等到自然过期之后重新登录,才能用到新的令牌。
      1. JWT 内容大会 影响网络传输,过大会影响性能。

总结: JWT 更适合 安全不敏感 场景,而透明令牌(引用令牌)更适合 安全敏感场景

第六章、 微服务架构分层(Spring boot)


一、Spring boot 应用分层

1、服务层(Service层),service 和 domain 层两者共同实现业务逻辑

  • 胖领域模型:业务逻辑主要包含在领域对象内(domain),服务层(service)只是作为和业务逻辑domain的一个协调器。
  • 瘦领域模型: 业务逻辑主要在 service层内,而domain层只是一些状态字段等,不包含业务逻辑,也叫 平学领域模型

胖瘦领域模型孰好孰坏,业界有争论。

2、数据持久层 Repository ,主要负责数据库对象存储逻辑,底层一般是 ORM 框架,如 hibernatemybatis ,Repository 是 领域驱动设计DDDDomain-Driven Design)的一种设计模式。

二、测试分类

1、组件测试

  • 说明:集成测试、单元测试,都不能保证一个微服务的功能完整性,在微服务场景下,更多推荐组件测试。

  • 组件测试:所谓组件测试,就是把一个微服务看成是一个独立的组件,而不去关心内部的细节,把他看成一个黑箱,仅对暴露的接口进行测试,一般来说我们需要把这个service依赖的外部 API全部mock掉,这样才能保证一个微服务的独立性。

微服务测试一般需要mock数据,常见的mock分为

  • mock 数据分类
    • 内部mock:内部模块之间mock数据,如Repository mock数据等。
    • 外部mock:mock一个微服务所依赖的外部数据。

2、端到端测试(End To End)

端到端测试:(End to End)所谓端到端测试,将整个系统看成一个黑盒子,一般通过其接口,如Api 对整体业务线做整体测试。

3、测试总结

三、测试金字塔

说明: 所谓 测试金字塔,就是说我们在某个测试环节所应关注的 关注度是多少

  • 推荐多做 单元测试集成测试, 原因和测试特性有关联,从上到下来看测试力度变细,越往下越稳定、越往下测试越快。
  • 端到端测试: 建议力度放少,因为成本比较高,而且不稳定,好处是他的覆盖面比较广,实践上一般绕不开的,一定要去做。

注意: 不是每一种测试都要去追求力度,而是主要要遵循测试金字塔的力度指导。

四、灰度测试 + 生产监控

注意: 线下测试做的再多,也不能完全模拟线上,所以一般到了线上,我们一般要做 灰度测试 + 生产监控

  • 灰度测试: 一部分新功能,让少量用户来测,如果测试过了我再切流量到 100%
  • 生产监控: 监控线上环境,互联网应用一般认为是一种生产测试。

第七章、可运维架构生产实践

一、何谓生产就绪 Production Ready

1.1、传统经典编程过程

1.2、现代互联网交付过程

1.3、何谓生产就绪

说明:所谓生产就绪,就是在上线交付到客户手中,要完成如下部分:

  • Metrics 监控: 如调用数、调用延迟、出错数、CPU指标
  • 健康检查(healthy check),Nginx或者负载均衡器(LB)看到你不存活,就会把你拉出集群,保证用户体验。
  • 调用链监控: 调用记录、谁调用你,你调用谁,也可以统计调用链性能问题。
  • 安全性考量: 如用户下单、支付等,这些最起码得登录,还要有一点的安全check,权限校验等。
  • 高可用考量: 一个实例挂,能不能提供另一个实例服务,一般无状态服务,是可以水平扩展的(HPA),有状态的服务,要考量主备机制。
  • 扩展升级考量: 如流量上来了,能不能顺利扩展,增加一些实例,升级扩展要考虑上线是不是平滑的,升级的难易程度等,比如说我上线要灰度测试,蓝绿部署等。

1.4、有状态和无状态服务

  • 无状态服务: 就是没有 特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息)

  • 有状态服务: 与之相反, 有状态服务在服务端保留之前请求的信息, 用以处理当前请求,比如 session

典型的无状态服务的例子就是 http 协议

有状态服务举例:

  • 例如: 有状态服务,服务会存储请求上下文相关的数据信息,先后的 请求,是可以有关联 的。例如,要实现一种计数服务,每次请求都要对之前请求处理的数据结果进行+1 的操作,这就需要在服务端存储维护计数的数据,这样的服务就属于有状态的服务。

  • 例如: 在Web 应用中,经常会使用 Session 来维系登录用户的上下文信息。 虽然http 协议是无状态的,但是 借助于Cookie 和Session,可以使 http 服务转换为有状态服务。

详细参考:https://book.51cto.com/art/201807/578642.htm

第九章、云原生(Cloud Native)

一、何谓云原生?

说明:云原生就是基于 微服务 原理而开发的应用,以 容器 云方式打包。在运行时,容器由运行于 云基础设施 之上的平台进行调度。应用开发采用 持续交付Devops 实践。

  • 应用要以微服务方式构建
  • 微服务一开始就要面向容器云部署,通过如K8S等一键部署环境。

二、何谓:CI/CD?

  • CI 即 持续集成,CD 即 持续交付
原文地址:https://www.cnblogs.com/vpersie2008/p/14449903.html