在任何一个大公司里,X5零售集团也不例外,随着它的发展,需要用户授权的项目越来越多。 随着时间的推移,需要用户从一个应用程序无缝过渡到另一个应用程序,然后就需要使用单个单点登录 (SSO) 服务器。 但是,当 AD 或其他不具有附加属性的身份提供商已在各种项目中使用时该怎么办? 一类称为“身份经纪人”的系统将前来救援。 最实用的是它的代表,例如Keycloak、Gravitee访问管理等。大多数情况下,用例可以是不同的:机器交互、用户参与等。解决方案必须支持灵活且可扩展的功能,可以将所有需求结合在一起,而这样的解决方案我们公司现在有一个指示经纪商——Keycloak。
Keycloak 是 RedHat 维护的开源身份和访问控制产品。 它是该公司使用 SSO 的产品 - RH-SSO 的基础。
基本概念
在开始处理解决方案和方法之前,您应该决定流程的术语和顺序:
鉴定 是通过主体标识符识别主体的过程(换句话说,这是名称、登录名或号码的定义)。
认证 - 这是一个身份验证过程(使用密码检查用户,使用电子签名检查信件等)
授权 - 这是提供对资源的访问(例如,电子邮件)。
身份代理密钥斗篷
钥匙斗篷 是一种开源身份和访问管理解决方案,设计用于可以使用微服务架构模式的 IS。
Keycloak 提供单点登录 (SSO)、代理身份和社交登录、用户联合、客户端适配器、管理控制台和帐户管理控制台等功能。
Keycloak支持的基本功能:
- 浏览器应用程序的单点登录和单点退出。
- 支持 OpenID/OAuth 2.0/SAML。
- 身份代理 - 使用外部 OpenID Connect 或 SAML 身份提供商进行身份验证。
- 社交登录 - Google、GitHub、Facebook、Twitter 支持用户识别。
- 用户联合 - 来自 LDAP 和 Active Directory 服务器以及其他身份提供商的用户同步。
- Kerberos 桥 - 使用 Kerberos 服务器进行自动用户身份验证。
- 管理控制台 - 通过 Web 统一管理设置和解决方案选项。
- 帐户管理控制台 - 用于自我管理用户配置文件。
- 根据公司的企业形象定制解决方案。
- 2FA 身份验证 - 使用 Google Authenticator 或 FreeOTP 支持 TOTP/HOTP。
- 登录流程 - 用户自行注册、密码恢复和重置以及其他都是可能的。
- 会话管理 - 管理员可以从单点管理用户会话。
- 令牌映射器 - 将用户属性、角色和其他所需属性绑定到令牌。
- 跨领域、应用程序和用户的灵活策略管理。
- CORS 支持 - 客户端适配器具有内置的 CORS 支持。
- 服务提供商接口 (SPI) - 大量 SPI 允许您自定义服务器的各个方面:身份验证流程、身份提供商、协议映射等。
- JavaScript 应用程序、WildFly、JBoss EAP、Fuse、Tomcat、Jetty、Spring 的客户端适配器。
- 支持使用支持 OpenID Connect 依赖方库或 SAML 2.0 服务提供商库的各种应用程序。
- 可使用插件进行扩展。
对于 CI / CD 流程以及 Keycloak 中管理流程的自动化,可以使用 REST API / JAVA API。 文档可通过电子方式获取:
REST API
Java接口
企业身份提供商(本地)
能够通过用户联合服务对用户进行身份验证。
还可以使用传递身份验证 - 如果用户使用 Kerberos(LDAP 或 AD)对工作站进行身份验证,那么他们可以自动通过 Keycloak 进行身份验证,而无需再次输入用户名和密码。
对于用户的身份验证和进一步授权,可以使用关系型DBMS,它最适用于开发环境,因为它不涉及项目早期阶段的冗长设置和集成。 默认情况下,Keycloak 使用内置 DBMS 来存储设置和用户数据。
支持的 DBMS 列表非常广泛,包括:MS SQL、Oracle、PostgreSQL、MariaDB、Oracle 等。 迄今为止测试最多的是 Oracle 12C Release1 RAC 和 MariaDB 3.12 的 Galera 10.1.19 集群。
身份提供商 - 社交登录
可以使用社交网络登录。 要激活对用户进行身份验证的功能,请使用 Keycloack 管理控制台。 不需要更改应用程序代码,并且该功能是开箱即用的,并且可以在项目的任何阶段激活。
可以使用 OpenID/SAML 身份提供商进行用户身份验证。
Keycloak 中使用 OAuth2 的典型授权场景
授权码流程 - 与服务器端应用程序一起使用。 最常见的授权权限类型之一,因为它非常适合外部人员无法获取应用程序源代码和客户端数据的服务器应用程序。 本例中的过程是基于重定向的。 应用程序必须能够与用户代理(用户代理)(例如 Web 浏览器)通信,以接收通过用户代理重定向的 API 授权代码。
隐式流动 - 由移动或网络应用程序(在用户设备上运行的应用程序)使用。
隐式授权权限类型用于无法保证客户端机密性的移动和 Web 应用程序。 隐式权限类型还使用用户代理重定向,从而将访问令牌传递给用户代理以在应用程序中进一步使用。 这使得该令牌可供用户和用户设备上的其他应用程序使用。 这种类型的授权权限不会验证应用程序的身份,并且流程本身依赖于重定向 URL(之前在服务中注册)。
隐式流不支持访问令牌刷新令牌。
客户凭证授予流程 — 当应用程序访问 API 时使用。 这种类型的授权权限通常用于必须在后台执行而无需立即用户交互的服务器到服务器交互。 客户端凭据授予流程允许 Web 服务(机密客户端)在调用另一个 Web 服务时使用自己的凭据,而不是模拟用户进行身份验证。 为了获得更高级别的安全性,调用服务可以使用证书(而不是共享密钥)作为凭证。
OAuth2 规范描述于
JWT 代币及其好处
JWT(JSON Web Token)是一个开放标准(
根据标准,令牌由三部分组成,采用 Base-64 格式,并用点分隔。 第一部分称为标头,其中包含令牌的类型和用于获取数字签名的哈希算法的名称。 第二部分存储基本信息(用户、属性等)。 第三部分是数字签名。
。 。
切勿将令牌存储在数据库中。 由于有效令牌相当于密码,因此存储令牌就像以明文形式存储密码一样。
访问令牌 是授予其所有者访问安全服务器资源的令牌。 它的生命周期通常很短,并且可能携带附加信息,例如请求令牌的一方的 IP 地址。
刷新令牌 是一个令牌,允许客户端在其生命周期到期后请求新的访问令牌。 这些代币通常会发行很长一段时间。
在微服务架构中使用的主要优点:
- 能够通过一次性身份验证访问各种应用程序和服务。
- 如果用户配置文件中缺少许多必需的属性,则可以使用可添加到有效负载的数据进行丰富,包括自动的和动态的。
- 不需要存储有关活动会话的信息,服务器应用程序只需要验证签名。
- 通过有效负载中的附加属性进行更灵活的访问控制。
- 对标头和有效负载使用令牌签名提高了整个解决方案的安全性。
JWT 令牌 - 组成
产品名称 - 默认情况下,标头仅包含令牌类型和用于加密的算法。
令牌的类型存储在“typ”键中。 JWT 中会忽略“type”键。 如果存在“typ”键,则其值必须是 JWT 以指示该对象是 JSON Web 令牌。
第二个密钥“alg”定义用于加密令牌的算法。 默认情况下应设置为 HS256。 标头采用 base64 编码。
{“alg”:“HS256”,“类型”:“JWT”}
有效负载(内容) - 有效负载存储任何需要检查的信息。 有效负载中的每个密钥称为“声明”。 例如,您只能通过邀请(封闭促销)进入应用程序。 当我们想邀请某人参加时,我们会向他们发送邀请函。 检查电子邮件地址是否属于接受邀请的人非常重要,因此我们将在有效负载中包含该地址,为此我们将其存储在“电子邮件”键中
{ “电子邮件”: ”[电子邮件保护]"}
有效负载中的密钥可以是任意的。 不过,还是有一些保留的:
- iss(颁发者)- 标识发送令牌的应用程序。
- sub(主题)- 定义令牌的主题。
- aud(受众)是区分大小写的字符串或 URI 的数组,它是此令牌的接收者的列表。 当接收方收到带有给定密钥的 JWT 时,它必须检查接收方中是否存在自身 - 否则忽略该令牌。
- exp(过期时间)- 指示令牌何时过期。 JWT 标准要求其所有实现拒绝过期令牌。 exp 键必须是 unix 格式的时间戳。
- nbf(Not Before)是unix格式的时间,用于确定令牌生效的时刻。
- iat (Issued At) - 该密钥表示令牌的发行时间,可用于确定 JWT 的年龄。 iat 键必须是 unix 格式的时间戳。
- Jti (JWT ID) — 定义此令牌的唯一标识符的字符串,区分大小写。
重要的是要了解有效负载不是以加密形式传输(尽管令牌可以嵌套,然后可以传输加密数据)。 因此,它不能存储任何秘密信息。 与标头一样,有效负载也是采用 Base64 编码的。
签名 - 当我们有标题和有效负载时,我们可以计算签名。
Base64编码:获取header和payload,通过点组合成字符串。 然后该字符串和密钥被输入到标头中指定的加密算法(“alg”密钥)。 键可以是任何字符串。 较长的绳子是最受欢迎的,因为它需要更长的时间来拾取。
{“alg”:“RSA1_5”,“有效负载”:“A128CBC-HS256”}
构建Keycloak故障转移集群架构
当所有项目使用单个集群时,对 SSO 解决方案的要求会增加。 当项目数量较少时,这些要求对于所有项目来说并不是那么明显,但是,随着用户数量和集成数量的增加,对可用性和性能的要求也会增加。
单一 SSO 失败风险的增加增加了对解决方案架构和用于冗余组件的方法的要求,并导致非常严格的 SLA。 在这方面,更常见的是,在开发或实施解决方案的早期阶段,项目都有自己的非容错基础设施。 随着发展的进展,需要提供发展和扩展的机会。 使用容器虚拟化或混合方法构建故障转移集群是最灵活的。
为了工作在Active/Active和Active/Passive集群模式下,需要保证关系数据库中的数据一致性——两个数据库节点必须在不同地理分布的数据中心之间同步复制。
容错安装的最简单示例。
使用单个集群有哪些好处:
- 高可用性和性能。
- 支持工作模式:主动/主动、主动/被动。
- 能够动态扩展 - 使用容器虚拟化时。
- 集中管理和监控的可能性。
- 项目中用户识别/身份验证/授权的统一方法。
- 不同项目之间的交互更加透明,无需用户参与。
- 能够在各种项目中重用 JWT 令牌。
- 单点信任。
- 使用微服务/容器虚拟化更快地启动项目(无需提升和配置其他组件)。
- 可以从供应商处购买商业支持。
规划集群时要注意什么
DBMS
Keycloak 使用数据库管理系统来存储:领域、客户端、用户等。
支持多种 DBMS:MS SQL、Oracle、MySQL、PostgreSQL。 Keycloak 带有自己的内置关系数据库。 建议用于非加载环境 - 例如开发环境。
要工作在Active/Active和Active/Passive集群模式下,需要关系数据库中的数据一致性,并且两个数据库集群节点在数据中心之间同步复制。
分布式缓存(Infinspan)
为了使集群正常工作,需要使用 JBoss 数据网格对以下类型的缓存进行额外同步:
身份验证会话 - 用于在对特定用户进行身份验证时保存数据。 来自此缓存的请求通常仅包括浏览器和 Keycloak 服务器,而不包括应用程序。
操作令牌用于用户需要异步确认操作(通过电子邮件)的场景。 例如,在忘记密码流程期间,actionTokens Infinispan 缓存用于跟踪有关已使用的关联操作令牌的元数据,因此无法重复使用。
持久数据的缓存和失效——用于缓存持久数据,以避免对数据库进行不必要的查询。 当任何一个Keycloak服务器更新数据时,所有数据中心的所有其他Keycloak服务器都需要知道它。
Work - 仅用于在集群节点和数据中心之间发送无效消息。
用户会话 - 用于存储有关用户会话的数据,这些数据在用户浏览器会话期间有效。 缓存必须处理来自最终用户和应用程序的 HTTP 请求。
暴力保护 - 用于跟踪有关失败登录的数据。
负载均衡
负载均衡器是 keycloak 的单一入口点,并且必须支持粘性会话。
应用服务器
它们用于控制组件之间的交互,并且可以使用现有的自动化工具和基础设施自动化工具的动态扩展进行虚拟化或容器化。 OpenShift、Kubernates、Rancher 中最常见的部署场景。
第一部分——理论部分到此结束。 在接下来的系列文章中,将分析与各种身份提供商集成的示例和设置示例。
来源: habr.com