paint-brush
设计功能性身份验证和授权系统经过@iarunava
441 讀數
441 讀數

设计功能性身份验证和授权系统

经过 Arunava12m2024/05/05
Read on Terminal Reader

太長; 讀書

在本文中,我们将讨论安全地执行身份验证和授权的系统。
featured image - 设计功能性身份验证和授权系统
Arunava HackerNoon profile picture
0-item

在本文中,我们将讨论一种安全地执行身份验证和授权的系统。首先让我们了解一下身份验证和授权之间的区别。


  • 身份验证是在访问应用程序时证明您是谁的过程。
  • 授权是定义和执行访问策略的过程 - 即您通过身份验证后可以执行的操作。

在本文中,我们将看到:



为什么身份验证和授权很重要?

身份验证和授权(来源:Jeffrey Marvin Forones|Geek Culture。已修改)


假设我们正在开会,而您是谈话的主持人。要向合适的人询问某事的更新/状态,您需要识别(即验证)此人。即使要与某人共享一些敏感数据,您也需要正确地验证此人的身份。这就是身份验证的作用所在。


现在假设,在同一个会议上,需要做出几个决定。因此,有权做出这些决定的人应该是接电话的人,我们不能让每个人都做所有的事情。显然,有些人没有足够的能力做出一些决定,有些人肯定会试图把事情搞砸。因此,这就带来了授权,它赋予某些人进行某些活动的权利。

身份验证如何进行?

基于令牌的身份验证;访问令牌和刷新令牌 [SPA=SinglePageApplication、RT=RefreshToken、AT=AccessToken、RS=RefreshServer、AS=AuthorizationServer](来源:Okta)


为了验证一个人的身份,我们可以为每个人分配一个唯一的短语,如果该人正确地说出了短语和他们的名字,我们就可以说,好的,我们已经识别了这个人。这是通常的用户名和密码方法。当给出正确的凭证时,系统会认为身份有效并授予访问权限。这称为 1FA 或单因素身份验证(SFA)。


SFA 被认为相当不安全。为什么?因为用户在保护登录信息安全方面表现糟糕。多因素身份验证 (MFA) 是一种更安全的替代方案,要求用户以多种方式证明其身份。其中一些方式包括:


  • 一次性 PIN 码/OTP
  • 由安全第三方运行的身份验证应用程序(例如 Google/Microsoft Authenticator)
  • 生物识别


一旦通过身份验证,用户就可以继续在应用程序上自由执行操作。应用程序希望在整个旅程中都能识别用户,而不会忘记他们。理想情况下,要求用户每次转到其他页面或执行某些活动时都提供密码是过分的。因此,我们需要一种方法,在用户输入凭据并通过一次身份验证后,保持用户的身份。这称为会话管理


保持用户身份验证的两种方法:

  • 基于会话的身份验证:当用户通过浏览器登录网站时,服务器会为该用户创建一个会话并分配一个 sessionid。服务器会存储此 sessionid 以供参考,并将其发送回用户,存储在浏览器的 cookie 中。现在,每次用户发出请求时,浏览器都会随请求一起发送 sessionid。这将有助于验证请求。这样,当用户访问网站时,身份验证就会保留。
  • 基于令牌的身份验证:为此,服务器创建一个加密令牌,该令牌将发送给用户,并且仅由浏览器保存为 HttpOnly Cookies。所有必需信息(例如用户信息、权限和令牌到期时间)均在令牌中加密。令牌将随服务器一起发送以进行调用。服务器只需使用密钥解密令牌并验证用户即可。此令牌会定期刷新。


这两种方法之间的主要区别在于,基于令牌的身份验证是无状态的,因为令牌不需要存储在服务器端。但是对于基于会话的身份验证,令牌也需要存储在服务器端,这使得它成为有状态的。当系统扩展或用户数量增加时,这会带来复杂性。


对于基于令牌的身份验证,我们主要使用 JWT(JSON Web 令牌)。

授权如何运作?

基于角色的授权控制 (RBAC)(来源:Ajay Shekhawat | Dribble)

一旦用户通过身份验证,我们仍然需要确保他们只被允许访问他们有权访问的资源。未经授权访问敏感数据可能会带来灾难。根据最小特权原则,公司通常会设置访问策略,以便默认情况下您可以访问您绝对需要的内容。然后在此基础上,您拥有其他访问权限。划分访问权限的常用方法有:


  • 基于角色的访问控制 (RBAC) :用户被分配到具有设定权限的特定组/角色。例如:管理员、成员、所有者。
  • 基于策略的访问控制 (PBAC) :根据策略和规则在授权期间动态确定访问权限。策略基于用户角色、工作职能和组织要求。
  • 基于属性的访问控制 (ABAC) :根据职称、认证、培训和/或位置等环境因素等属性允许用户访问。
  • 访问控制列表 (ACL) :每个用户或实体都有可以打开或关闭的单独权限,类似于在手机上安装新应用程序并决定授予哪些权限(位置服务、联系人等)


访问控制列表屏幕(来源:Povio)


ACL 的使用范围比 ABAC 或 RBAC 更广 - 例如,授予个人用户对某个文件的访问权限。ABAC 和 RBAC 通常作为公司范围的政策制定。


认证系统设计

认证授权系统设计(来源:InterviewPen. 已修改)

要求

首先让我们定义系统的功能需求

  • 注册:允许用户提供必要的信息进行注册。
  • 登录:根据用户凭证对其进行身份验证。
  • 会话管理:有效管理用户会话,确保安全。
  • 密码恢复:为用户提供一个安全的密码恢复流程。
  • 访问控制:为不同的用户类型定义角色和权限。
  • 审计跟踪:维护身份验证事件的详细日志以供审计。
  • 性能:确保低延迟和快速响应时间。


在本文的讨论范围内我们不会考虑一些非功能性需求,包括:

  • 多因素身份验证 (MFA) :实施强大的 MFA 系统。
  • 安全性:通过加密、安全存储和安全通信优先考虑数据安全。
  • 可扩展性:设计系统来处理不断增长的用户和交易数量。
  • 可靠性:最大限度地减少系统停机时间并确保高可用性。
  • 可用性:开发直观的用户界面以获得无缝体验。


容量估算

交通预测

首先让我们从流量估算开始。假设平均流量为每月 100,000。我们估计每月有 100k 用户流量。这相当于每秒 0.04 个请求。我们需要在 90% 的时间内 500 毫秒内响应每个请求,即我们需要 500 毫秒的 p90 延迟。


 assumed_traffic_per_month = 100000 #requests assumed_traffic_per_day = assumed_traffic_per_month / 30 ~= 3350 (assuming on higher end; 3333.33 to be precise) estimated_time_per_request = 500 #ms; P90 of 500ms traffic_per_second = (assumed_traffic_per_month) / (30*24*60*60) = 0.04


服务级别目标 (SLO) :500ms(可接受的最大延迟,与系统负载无关)根据我们的计算,假设特定请求没有发生繁重的处理,则 1 个实例所需的平均容量大约为 35ms 来处理一个请求。


让我们使用上述指标生成另外两个派生指标

  • 容量:每个实例可接受的积压:在不影响 SLO 的情况下,实例可以接受的最大请求数(负载)。
  • 需求:每个实例的积压:根据当前流量流入单元/实例的请求总数(负载)。

因此,

 SLO = 500ms approx_response_time_for_one_request = 35 #ms capacity = SLO/approx_response_time_for_one_request = 500 / 35 ~= 20 load_on_one_instance = 0.04 instances_available = 1 demand = traffic_per_second / instances_available = 0.04


根据需求和可用容量,让我们计算所需的实例总数。

 total_units_required = demand / capacity = 0.04 / 20 = 0.002 ~= 1

因此,我们每月可以轻松处理 10 万个请求,每秒处理 0.04 个请求,只需 1 个实例。其中每个单元每秒可以处理 20 个请求,而不会影响 SLO。


存储估算

理想情况下,我们需要存储每个用户的用户详细信息,以便进行身份验证和授权访问。假设 5kb/用户

monthly_new_users = 500 monthly_additional_storage = 500 * 5kb = 2500kb ~= 2GB


因此,假设我们每个月新增 500 名用户,我们将需要 2GB 以上的存储空间。如果我们想保留身份验证日志,则每个身份验证请求预计需要 2kb 的存储空间。

 auth_request_size = 2kb #assumption monthly_storage = monthly_visitors * auth_request_size = 100,000 * 2KB ~= 200MB

因此,假设每月流量为 100k,我们每月将需要额外的 200MB。

数据库设计

现在我们已经完成了容量估算。让我们创建支持功能需求所需的数据库模式。

身份验证和授权数据库架构

让我们快速浏览一下表格。我们使用了 6 个表格。

  1. 用户 - 存储所有用户信息
  2. 凭证——用户获得授权后,存储访问/刷新凭证。
  3. 密码——存储用户加密的用户密码。
  4. PasswordRequests——存储特定用户的密码更改请求。
  5. 会话——存储用户何时进行活动会话以及上次活动的时间。
  6. ActivityApproval - 存储特定用户执行的活动的批准请求,由管理员验证。


身份验证系统的高层设计

身份验证和授权 HLD

系统端点

端点

描述

/登录

验证用户凭证。

/登出

结束用户会话并撤销身份验证令牌。

/登记

创建新用户。

/更新/:用户ID

更新用户信息。

/删除/:用户ID

删除用户帐户。

/授予/:用户ID/:许可

授予用户特定权限。

/撤销/:用户ID/:许可

撤销用户的权限。

/检查/:用户ID/:资源

检查用户对特定资源的访问。

/创建/:用户ID

创建一个新的用户会话。

/过期/:sessionId

使用户会话过期。

/验证/:sessionId

验证活动用户会话。


满足要求

现在,所有一切就绪,让我们看看如何完成所有要求。


登记


  • 要求- 当新用户访问我们的应用程序时。我们需要存储用户详细信息,以便在用户下次访问时对其进行授权/识别。
  • 已实现- 当新用户访问应用程序并输入用户详细信息以及其电子邮件和密码时。这些信息将被捕获到数据库中。用户详细信息将存储在用户表中。密码将以加密形式存储在凭证表中。


登录

  • 要求- 当现有用户访问我们的应用程序时。我们需要识别用户,以便我们可以授权/识别他们的操作并向他们显示属于他们的数据。
  • 已完成- 当现有用户访问应用程序并输入其详细信息、电子邮件和密码时。我们对密码进行哈希处理,并将哈希与凭据表中为用户存储的哈希进行匹配。如果匹配,则我们能够成功识别用户。否则,他们需要输入注册时输入的正确密码。此过程称为身份验证


会话管理

  • 要求- 当用户通过输入用户名和密码进行身份验证时。我们需要确保他们在执行未来操作/尝试查看敏感数据时保持登录状态,而无需他们一次又一次地重新输入密码。
  • 已完成- 当用户身份验证成功时。身份验证服务器将与客户端共享 2 个令牌。一个access_token和一个refresh_token 。access_token 可以包含加密数据,并且出于安全原因,其有效期较短。一旦客户端拥有 access_token,它会将 access_token 与每个请求一起发回,这有助于验证请求。当 access_token 过期时,客户端必须使用提供的 refresh_token 请求新的 access_token。这有助于维持会话。


找回密码

  • 要求- 当用户忘记密码时,他们需要能够安全地重置密码。
  • 已实现- 当用户忘记密码时,他们可以在忘记密码页面提交他们的电子邮件地址,我们将生成一次性代码并将链接发送到他们的电子邮件。当用户点击带有代码和电子邮件地址的此链接时。我们将能够安全地识别密码恢复请求是真实的。并允许用户设置他们的新密码。从而能够恢复密码。


访问控制

  • 要求- 当用户执行某个操作时,我们需要确保用户已经过身份验证才能执行该操作,然后才允许该操作发生。
  • 已完成- 为简单起见,我们将维护一个操作列表,假设为 1-12。对于每个用户,我们将维护该用户的已验证操作。现在假设用户尝试执行操作 #id 4。我们将检查用户是否具有执行操作 4 的权限。如果是,我们将继续完成请求。否则,我们将显示请求因缺乏权限而未成功。


审计追踪

  • 要求- 如果发生安全事故,我们应该有足够的日志来查看,并对可能发生的事情有一个合理的解释/或对可能导致事故的任何线索。
  • 已实现- 对于此类场景,我们可以为服务器上发生的每个身份验证操作保留日志。 (a)。对于每个登录请求,我们将保留有关身份验证发生时间、地点、IPS 和其他相关详细信息的日志。 (b)。对于每个密码恢复请求,我们将保留有关发起时间、地点、IPS、请求是否完成和其他相关详细信息的日志。 (c)。此外,我们将在每次用户被授权/未授权执行某项操作时以及由谁授权时保留日志。总的来说,这些日志应该能够表明在尝试了解某些场景时可能发生的情况。


表现

  • 要求- 如容量估算部分所述,性能要求为每秒 0.04 个请求和每月 10 万个请求。
  • 已满足— 我们已经在容量估算部分处理了足够的服务器的需求。

结论

身份验证与授权(来源:OutSystems)

在本文中,我们首先了解了身份验证和授权之间的区别。接下来,我们创建了一个身份验证和授权系统。该系统安全可靠,性能出色,同时符合行业标准并满足所有要求。今后,我可能会更新文章的某些部分,以使其保持相关性,并涵盖构建此类系统的更多信息和见解。