转向微服务时,将得出结论,与单应体用程序相比,需要以不同的方式解决保护微服务的问题。
在设计解决方案时,会出现诸如"我在哪里以及如何实现身份验证和授权?"之类的问题。和"我如何授权用户采取特定行动?"可以弹出。在本文中,将为这些问题介绍一种解决方案。
首先,将说明认证和授权之间的差异。其次,将引入OpenID Connect和OAuth2作为用于微服务架构的集中式身份验证和授权的解决方案。最后,将解释授权的两个实现选择。
身份验证和授权之间有什么区别?
在谈论保护应用程序安全时,将弹出认证和授权一词。虽然这些术语可以互换使用,但它们在保护应用程序范围内代表了不同的目的。
在谈论身份验证时,这是验证他/她/所声称的实体的身份的过程。在谈论授权时,它是验证实体是否被授权访问特定信息或被允许执行某些动作的过程。
关于总安全流程,这两个原则都适用,并且组合仍然可能使请求失败。在规则中,身份验证首先,授权第二。当用户通过身份验证但未经授权时,请求仍将失败。
OpenID Connect和OAuth
在像微服务这样的分布式系统架构中,无法以传统方式实现身份验证和授权。使用单体架构方法,经常将签名会话存储在内存中或分布式会话存储中,以在单体应用程序实例之间共享会话。
由于微服务是单独的隔离的应用程序,因此无法共享不同应用程序的内存中存储。不建议集中和共享分布式会话存储。这在微服务之间建立了紧密的耦合,并为微服务之间的泄漏逻辑打开了大门。
牢记微服务架构,每个微服务应独自负责其单个业务逻辑,无论是很小的逻辑还是有限的上下文。在这种情况下,身份验证是一个贯穿各领域的问题,不应成为微服务本身的一部分。
针对此问题的一种广泛使用的解决方案是实现单独的身份服务器。该服务负责托管集中式身份验证和授权。有多种解决方案,例如WSO2身份服务器(Java),IdentityServer4(.NET)和OAuth2orize(Node.js)。所有这些框架都通过使用OpenID Connect和OAuth2支持身份验证和授权。
什么是OpenID Connect?
OpenID Connect是一种身份验证协议,它是OAuth2之上的简单身份层。它允许客户端识别客户端,以通过外部授权服务器(例如Google,Facebook或身份服务器中的嵌入式登录系统)来验证用户的身份。
流程看起来如何?用户请求访问应用程序。应用程序确定用户尚未通过身份验证,然后将用户重定向到身份服务器。用户向身份服务器进行身份验证。身份服务器在成功身份验证后向用户发送访问令牌/ ID令牌。该令牌由加密密钥签名。用户可以在应用程序上使用此令牌进行身份验证。应用程序通过检查公共加密密钥来检查签名密钥是否由身份服务器签名,从而验证签名密钥。在这种情况下,用户已成功通过身份验证!
对于令牌,使用JSON Web令牌(JWT)。JWT由标头,有效负载和签名组成。标头包含用于对令牌进行签名的算法。有效负载本质上是一个JSON对象,可以在其中添加有关用户的其他属性。由于令牌是由身份服务器签名的,因此消费应用程序可以信任该信息。应用程序可以根据身份服务器用于签署令牌的证书的公钥来验证令牌。
> High-level flow between user, application and identity server
什么是OAuth2?
在解释OpenID Connect时,术语OAuth2已经掉了。OAuth2是行业标准的授权协议。它为Web应用程序,台式机应用程序,移动电话和客厅设备提供了特定的授权流程(在规范内称为授予)。
OpenID Connect解释中描述的流程实际上使用了一种受支持的授权类型,确切地说是授权码授权类型。
通过此流程,将用户重定向到身份服务器,在该服务器上处理身份验证和授权。客户端(请求用户信息的应用程序)获得用户对所需信息的授权。这是通过配置正确的作用域来完成的。范围类似于特定客户端可以访问的数据类型。范围的示例是电子邮件和地址,分别类似于用户的电子邮件地址和地址。
范围是由应用程序在身份验证过程中请求的。当用户在身份服务器上对自己进行身份验证时,用户也有可能为请求的数据授予应用程序授权。获得授权后,数据将被添加到令牌的有效载荷中并传递给应用程序。
在身份服务器中,可以保留与用户连接的角色。可以为公司中的所有员工设置身份服务器。这些员工根据他们在公司中的角色具有不同的角色。身份服务器可以将分配的角色共享给令牌中的特定用户。这样,可以与使用中的应用程序共享。
特定于应用程序的授权逻辑应内置在哪里?
上一节已经提倡选择在单独的集中负责的服务中构建身份验证。对于特定于应用程序的授权逻辑,这变得更加困难。在微服务架构中,服务本身不应直接暴露给使用中的应用程序。管理与所有微服务的连接变得难以管理。
实施API网关会创建一个供消费者与之通信的单一入口点。API网关将请求路由到上游微服务。
> API gateway in relation to other components
当有多个使用者使用时,创建特定的API网关可能是为每个使用者创建单独的特定端点的解决方案。这种变化称为"前端的后端"模式。这样,仅为每个使用者专门实现端点。这样做的缺点是,它为每个使用者增加了另一个需要维护的单独服务。
在网关中处理特定于应用程序的授权
处理特定于应用程序的授权的一种解决方案是通过在API网关中实现此功能。以这种方式将请求限制到特定端点成为可能。在API网关中实现授权的缺点是,它只能是基于角色的端点访问。实施对特定域对象的访问的附加检查将需要在API网关内部创建特定域逻辑,因此将导致域逻辑泄漏。此外,在为前端/ API网关引入多个后端时,管理授权变得越来越困难。
在微服务中处理特定于应用程序的授权
更好的解决方案是使微服务负责处理授权。API网关应将JWT与请求一起传递给微服务。如前所述,JWT将包含分配给用户的角色。由于API网关仍负责身份验证,因此在微服务收到请求时,已经完成了令牌的验证。通过为执行请求的用户分配角色,微服务现在可以确定用户是否已获得所需请求的授权。这样,只需要在一个地方实现特定于应用程序。这样做的一个缺点是授权将分散在多个服务中。当许多角色经常变化时,管理起来就变得很乏味。
结论
当在微服务中实现身份验证和授权时,该过程比传统的单片架构要复杂得多。
虽然身份验证和授权都是保护应用程序安全的术语,但它们涵盖的范围并不相同。身份验证是关于验证其声称为实体的身份。授权是有关确定是否允许实体执行特定操作或访问特定数据的过程。
对微服务架构内的应用程序的身份验证和授权通常是在对此负责的集中式服务中实现的。有多种解决方案,例如WSO2身份服务器(Java),IdentityServer4(.NET)和OAuth2orize(Node.js)。这些服务支持OAuth2和OpenID Connect,它们是用于授权和身份验证的基础,行业标准协议。
实施身份验证检查应在API网关内部终止。可以在API网关或微服务中实现授权。为了能够进行广泛的特定于应用程序的授权检查,应该在特定的微服务中处理授权。这可以通过将JWT与请求一起传递来完成。这样,域对象的特定于应用程序的授权就不会泄漏到API网关。