OpenID Connect:从通用到标准的内部应用程序授权

几个月前,我正在实现一个OpenID Connect服务器来控制对数百个内部应用程序的访问。从我们自己的发展,在较小的规模上方便起见,我们转向了公认的标准。通过中央服务的访问极大地简化了单调的操作,降低了执行授权的成本,使您能够找到许多现成的解决方案,并且在开发新解决方案时不会动脑筋。在本文中,我将讨论这种过渡以及我们设法弥补的障碍。

介绍

曾几何时...一切如何开始


几年前,当内部应用程序太多需要手动控制时,我们在公司内部编写了一个用于访问控制的应用程序。这是一个简单的Rails应用程序,连接到具有有关员工信息的数据库,并在其中配置了对各种功能的访问权限。然后,我们提出了第一个SSO,该SSO基于来自客户端和授权服务器的令牌验证,该令牌以加密的形式传输并带有多个参数,并在授权服务器上进行了检查。这不是最方便的选择,因为在每个内部应用程序上必须描述一个相当大的逻辑层,并且雇员的基础与授权服务器完全同步。

一段时间后,我们决定简化集中授权的任务。 SSO转移到平衡器。他们在Lua上使用OpenResty,添加了一个模板来检查令牌,知道请求所在的应用程序,并可以检查那里是否有访问权限。这种方法大大简化了控制内部应用程序访问的任务-在每个应用程序的代码中,不再需要描述其他逻辑。结果,我们从外部关闭了流量,应用程序本身对授权一无所知。

然而,问题之一仍然没有解决。那些需要有关员工信息的应用程序呢?您可以编写用于授权服务的API,但是随后您必须为每个此类应用程序添加其他逻辑。此外,我们希望摆脱对我们内部授权服务器上对我们自己编写的应用程序之一的依赖,该应用程序进一步致力于转换为OpenSource。我们待会儿再谈他。解决这两个问题的方法是OAuth。

达到公认的标准


OAuth是一种可以理解的,公认的授权标准,但是由于其功能还不够,因此立即开始考虑使用OpenID Connect(OIDC)。OIDC本身是开放式身份验证标准的第三种实现,已通过OAuth 2.0协议(开放式授权协议)扩展到了外接程序中。该解决方案解决了关于最终用户的数据不足的问题,并且还使得可以改变授权提供者。

但是,我们没有选择特定的提供程序,而是决定为现有的授权服务器添加与OIDC的集成。为了支持这种解决方案,OIDC在授权最终用户方面非常灵活。因此,可以在当前的授权服务器上实现OIDC支持。

图片

我们实现自己的OIDC服务器的方式


1)他们将数据带到所需的形式


要集成OIDC,您需要以一种标准可以理解的方式带来当前用户数据。在OIDC中,这称为索赔。品牌本质上是用户数据库中的结束字段(名称,电子邮件,电话等)。有一个标准的品牌列表,该列表中未包括的所有内容均视为自定义。因此,如果要选择现有的OIDC提供商,首先要注意的一点是可以方便地自定义新品牌。

品牌组将合并到下一个子集-范围。在授权过程中,即使不需要范围中的某些标志,也不要求访问特定品牌,即范围。

2)实施必要的赠款


OIDC集成的下一部分是选择和实现授权类型,即所谓的授权。所选应用程序与授权服务器交互的其他场景将取决于所选授权。下图给出了选择权利授予的近似方案。

图片

对于我们的第一个应用程序,我们使用了最常见的授权-授权码。它与其他人的区别在于它是三个步骤,即通过其他验证。首先,用户发出授权许可请求,接收令牌-授权码,然后使用此令牌(好像带有旅行票证)来请求访问令牌。此授权方案的所有主要交互都基于应用程序和授权服务器之间的重定向。在此处阅读有关此补助金的更多信息

OAuth坚持以下概念:授权后收到的访问令牌应该是临时的,最好平均每10分钟更改一次。授权代码的授予是通过重定向进行的三个步骤的检查;坦率地说,每10分钟执行一次此步骤对眼睛来说并不是一种愉快的体验。为了解决这个问题,我们还部署了另一个补助金-刷新令牌。这里的一切都比较简单。在测试过程中,除了主要访问令牌之外,还从另一个授权中发出了另一个令牌-刷新令牌,该令牌只能使用一次,并且其寿命通常会更长。使用此刷新令牌,当主访问令牌的TTL(生存时间)结束时,对新访问令牌的请求将到达另一个授予的端点。使用的刷新令牌将立即重置。这种检查是两步操作,可以在后台执行,对用户是不可见的。

3)定制的用户数据输出格式


选定的赠款实施后,授权即可生效,值得一提的是有关最终用户的数据接收。OIDC为此具有一个单独的端点,您可以在该端点上使用当前访问令牌并在相关时请求用户数据。而且,如果用户数据变化不那么频繁,并且您需要多次进行修改,则可以做出像JWT令牌这样的决策。这些令牌也受标准支持。JWT令牌本身由三部分组成:标头(有关令牌的信息),有效负载(任何必要的数据)和签名(签名,令牌由服务器签名,以后您可以检查其签名的来源)。

在OIDC实现中,JWT令牌称为id_token。可以将其与常规访问令牌一起请求,剩下的只是验证签名。授权服务器为此具有一个单独的终结点,该终结点带有一堆JWK格式的公钥值得一提的是,还有一个基于RFC5785标准的端点可以反映OIDC服务器的当前配置。它包含端点的所有地址(包括用于签名的公钥链的地址),支持的品牌和范围,使用的加密算法,支持的授权等。

例如在Google上:
{
 "issuer": "https://accounts.google.com",
 "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
 "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
 "token_endpoint": "https://oauth2.googleapis.com/token",
 "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
 "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
 "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
 "response_types_supported": [
  "code",
  "token",
  "id_token",
  "code token",
  "code id_token",
  "token id_token",
  "code token id_token",
  "none"
 ],
 "subject_types_supported": [
  "public"
 ],
 "id_token_signing_alg_values_supported": [
  "RS256"
 ],
 "scopes_supported": [
  "openid",
  "email",
  "profile"
 ],
 "token_endpoint_auth_methods_supported": [
  "client_secret_post",
  "client_secret_basic"
 ],
 "claims_supported": [
  "aud",
  "email",
  "email_verified",
  "exp",
  "family_name",
  "given_name",
  "iat",
  "iss",
  "locale",
  "name",
  "picture",
  "sub"
 ],
 "code_challenge_methods_supported": [
  "plain",
  "S256"
 ],
 "grant_types_supported": [
  "authorization_code",
  "refresh_token",
  "urn:ietf:params:oauth:grant-type:device_code",
  "urn:ietf:params:oauth:grant-type:jwt-bearer"
 ]
}


因此,使用id_token,您可以将所有必要的标记转移到令牌的有效载荷上,而不必每次都与授权服务器联系以请求用户信息。这种方法的缺点是从服务器更改用户数据不会立即进行,而是带有新的访问令牌。

执行结果


因此,在实现我们自己的OIDC服务器并在应用程序侧建立与其的连接之后,我们解决了传输用户信息的问题。
由于OIDC是开放标准,因此我们有机会选择现有的提供程序或服务器实现。我们尝试了Keycloak,事实证明它很容易配置,在应用程序侧设置和更改连接配置后,就可以使用了。在应用程序端,仅需更改连接配置。

谈到现有解决方案


作为我们组织的一部分,作为第一台OIDC服务器,我们汇总了实现,并根据需要对其进行了补充。详细查看其他现成的解决方案后,我们可以说这是有争议的。供应商方面担心缺乏必要的功能可以作为其服务器实施的解决方案,以及存在一个旧系统,在该旧系统中,对某些服务有各种自定义授权,并且存储了大量有关员工的数据。但是,在现成的实现中,集成很方便。例如,Keycloak有其自己的用户管理系统,并且数据直接存储在其中,因此在这里赶超其用户将很困难。为此,Keycloak有一个API,可让您完全实现转移的所有必要步骤。

在我看来,另一个经过认证的有趣示例是Ory Hydra。有趣的是,它由不同的组件组成。为了进行集成,您需要将用户管理服务与其授权服务链接起来,并根据需要进行扩展。

Keycloak和Ory Hydra不是唯一的交钥匙解决方案。最好选择经过认证的OpenID Foundation实现。通常,此类解决方案具有OpenID认证标志。

Openid认证


另外,如果您不想保留OIDC服务器,也不要忘记现有的付费服务提供商。到目前为止,有很多不错的选择。

下一步是什么


在不久的将来,我们将以另一种方式关闭对内部服务的访问量。我们计划将使用OpenResty的平衡器上的当前SSO转移到基于OAuth的代理。这里还有许多现成的解决方案,例如:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

附加材料


jwt.io-检查
openid.net/developers/JWT认证令牌的良好服务-认证的OIDC实施列表

All Articles