随着计算机和互联网技术的飞速发展,信息安全已经是全民关注的问题,也是各大企业都非常重视的问题。企业一般从多个层面开始保障信息安全,例如:物理安全、网络安全、系统安全(主机和操作系统)、应用安全等。对于应用安全,需要从多个角度进行安全评估,例如应用架构、代码、运维、管理。在整个应用生命周期中,软件工程师主要负责身份验证、访问授权、进程间通信安全、代码安全、安全管理和审计五个方面的工作。这五个方面中,前三个侧重于技术实现,而代码安全、管理和审计则需要更加规范的管理和执行。本文将重点介绍认证、授权、通信等技术相关内容。作简要说明。本文介绍了采用微服务架构为背景的应用程序,但大多数应用的安全解决方案与是否采用微服务架构并无强相关。如果有差异,文章会提出来。本文描述过程会涉及微服务架构中的一些相关概念术语,如下:微服务架构中安全访问相关的运行视图简化版如下:运行视图中带星号*的位置是服务调用过程中安全访问过程中的一些关键位置需要进行鉴权和鉴权,如:内外访问鉴权、token验证和授权、内外网通信协议等,后续章节将对这部分进行分析。1.身份认证大多数业务功能应用的首要任务是进行身份认证。数据披露或新闻发布等门户应用无需考虑这一点。他们更关心数??据披露前的管理和审批。认证或身份验证(Authentication),顾名思义,就是验证和识别应用程序“访问者”的身份。访客分为两类。基于登录的客户端:当用户访问服务提供商的应用程序的功能时,他们需要通过客户端界面与服务提供商进行交互。用户需要先登录,然后客户端代表用户身份访问服务商应用。API客户端(APIClient):客户端程序类型的访问者,这类客户端本身可以访问一些API,不需要用户授权。1.使用认证管理系统IAM进行访客登记认证。无论是用户还是API客户端,在访问应用之前,都需要向认证管理系统IAM注册,创建自己的身份凭证(用户账号和密码,客户端ID和密码)。只有有了身份证明才能通过认证服务的验证。统一认证管理系统IAM(IdentityandAccessManagement)负责身份识别和访问管理。其核心业务是访客在应用系统的注册、账号密码凭证管理、访客基本信息、注册访客的合法性等。访问的身份验证和初级授权(获取访问者自己的数据)等。一些企业还将组织结构、角色、甚至业务职能权限数据纳入IAM系统管理。IAM权限管理的范围可大可小,不同的企业有不同的管理要求和力度。功能授权管理是集中还是下放给业务系统进行自治,各??有利弊。只需选择适合您的方法即可。2、IAM认证管理系统采用OAuth2.0对访问者进行授权。传统的WEB应用程序使用服务器端的会话状态存储来进行用户登录访问。用户请求通常使用会话粘性会话或会话复制(Replicationsession)策略来保持客户端和服务器之间的会话。对于会话共享,会话信息必须写入公共缓存或数据库,从而导致微服务应用程序之间的耦合。在微服务架构中,不建议将session保存在服务端。如果没有必要引入状态管理,那么应用程序应该尽量保持无状态运行。建议使用另一种基于访问令牌的模式。在这种模式下,应用程序不需要保存会话状态,API客户端和基于登录的客户端都可以轻松使用访问令牌。微服务架构推荐使用OAuth2.0授权协议搭建IAM系统。Spring系统可以基于SpringSecurityOAuth实现授权服务器和客户端。在本文的背景下,方案设计针对的是企业基于微服务的整体架构。在企业整体架构中,默认的认证体系方案是企业的统一认证,而不是各个业务系统的认证(该方案的前提)。OAuth2.0本身是为三方授权设计的,但本方案讨论的是企业内部应用的整体认证授权,不存在第三方。因此,本方案中基于OAuth2.0实现的授权服务可以简单理解为只对IAM统一认证管理系统中的“账户管理应用资源提供者”进行授权,默认实现是自动授权登录-通过身份验证在帐户数据中。写入权限,登录通过后不与用户交互确认是否同意授权。其他业务系统作为资源提供者的授权是系统管理员预置的授权,用户登录时不需要决定是否授权。这个OAuth2.0的使用场景可能和其他OAuth2.0相关的不一样materials或授权框架默认实现,请注意区分。OAuth协议中定义了四种角色:资源所有者可以授予对受保护资源的访问权限的实体。当资源所有者是个人时,它被称为最终用户。资源服务器托管受保护资源并能够使用访问令牌接收和响应对受保护资源的请求的服务器。客户端一个应用程序,它使用资源所有者的授权代表资源所有者发起对受保护资源的请求。术语“客户端”不指代任何特定的实现特征(例如:应用程序是否在服务器、桌面或其他设备上执行)。授权服务器在成功验证资源所有者并获得授权后,向客户端的服务器颁发访问令牌。角色分析:对于上面提到的API客户端,它具有API访问权限,不需要用户授权。因此,OAuth角色对应时,既是客户端又是资源拥有者。在微服务架构中,Web应用一般采用前后端分离的模式。前端是基于浏览器访问的纯前端应用,网关作为应用的入口。这时,网关本身就可以代表OAuth中的客户端身份来访问服务提供者应用程序。功能界面。在微服务架构中,负责颁发访问令牌的授权服务通常实现IAM系统中的资源服务器。在微服务架构中,业务系统中所有的服务功能提供者都是资源服务器,包括IAM系统的账户、组织服务、资源权限管理服务等。在OAuth2.0授权协议中,主要定义了四类权限:授权码许可证、简单许可证、密码凭证许可证和客户端凭证许可证。详情请参考规范内容:rfc6749-TheOAuth2.0AuthorizationFramework(https://tools.ietf.org/html/rfc6749)下面我们根据访问者的类型推荐合适的授权方案。2.1API客户端作为访问者,使用客户端凭证对典型的API客户端进行授权,如批量调度系统、物联网设备程序等,通常无需用户登录授权即可自动运行。使用ClientCredentials权限类型是合适的。客户端证书上图为OAuth2.0规范标准流程图。该场景对应OAuth2.0中的角色,API客户端为OAuth2.0客户端,IAM为授权服务器。(A)API客户端向授权服务器IAM进行身份验证并请求访问令牌。(B)授权服务器IAM对API客户端进行身份验证,如果有效,则颁发访问令牌。客户端存储访问令牌以供后续请求使用。如果token过期或者失效或者需要重复这个过程重新申请accesstoken。其他说明:此类应用通常没有与用户交互的UI,不需要用户授权,具有保证客户端凭证安全的能力。此类应用的后端需要具备通过https访问授权服务器的能力。此类应用或设备需要有Token的存储访问能力2.2基于登录客户端作为访问者,使用授权码权限2.2.1Web应用OAuth2.0协议提出前端单页Web应用可以使用简单权限模型,但是简单的权限模型有一些局限性。一段时间后需要重新登录授权,不支持token刷新,用户体验差。许多使用简单授权的应用程序会颁发一个长寿命的令牌,持续数天甚至数周,以改善用户体验。如果有条件地使用授权码模式,支持刷新令牌是更好的选择。accesstoken时间较短,比如2分钟,refreshtoken是一次性token,有效期稍长,比如30分钟。如果有请求用无效的refreshtoken换取accesstoken,授权端点也能及时发现并做出相应的响应入侵处理,比如注销该用户的所有refreshtoken。在保持良好用户体验的同时,也考虑到了一些安全问题。本场景以一个常见的微服务架构前后端分离的Web应用为例。前端是一个单页应用程序。在网关的帮助下交换授权代码。因此,在微服务架构中,即使是纯前端的单页应用web应用,仍然可以使用基于网关交互的授权码方式来获取访问令牌。其他没有前后端分离的混合Web应用程序本身就是客户端,不需要借助网关来交换访问令牌。授权码上图为OAuth2.0规范标准流程图。结合这个场景,对应OAuth2.0中的角色。用户是资源拥有者,浏览器是用户代理,网关是授权客户端,IAM是授权服务器。(A)网关通过引导浏览器启动流程授权流程,重定向到统一认证中心的登录页面。(B)用户输入密码登录,授权服务器验证用户身份,确认用户是否授权网关的访问请求。(C)用户授权后,认证中心根据上次网关注册时提供的回调地址,引导浏览器重定向回网关。重定向URI包含授权代码(D)网关从授权服务器IAM请求访问令牌,其中包括在上一步中收到的授权代码和网关自己的凭据。(E)授权服务器IAM对网关进行身份验证,验证授权码,并确保收到的重定向URI与网关注册的URI相匹配。成功匹配后,授权服务器IAM向网关响应一个访问令牌和一个可选的刷新令牌。其他说明:为了保持前端会话,accesstoken由网关在响应时返回给前端,存储在前端存储空间,如Cookie,LocalStorage,SessionStorage,etc.accesstoken过期后,网关将自己的clientcredentials+refreshtoken一起发送给授权服务器,获取新的accesstoken和refreshtoken,返回response将accesstoken写入用户浏览器中的存储.在授权码模式下,用户的凭据(用户名、密码)是用户通过浏览器与授权服务进行交互,不经过网关,所以安全性最好。2.2.2移动App安装在个人移动设备上的原生App本身具有实现授权码过程的能力,不需要网关实现授权码过程。认证通过后,网关只负责验证accesstoken。授权码手机应用通常可以通过以下方式实现登录重定向:模拟web终端,使用手机浏览器和WebView,使用URIschemes和Intents在应用间跳转入侵风险包括以下两种情况:重定向过程很容易被恶意应用程序拦截,占用URLScheme或监听localhost端口。运行环境不可靠,移动应用不具备安全存储客户端密钥的能力,使用授权码获取访问令牌时需要验证客户端密钥。基于以上风险和问题,需要优化基于移动应用授权码获取访问令牌的流程。rfc规范中建议的实现方案是使用支持PKCE的授权码方式进行手机APP授权过程。PKCE,全称ProofKeyforCodeExchange,用于保护授权码授权。这实际上是一种密码学方法,确保即使有恶意的第三方截获了AuthorizationCode或其他密钥,也无法与认证服务器交换AccessToken。PKCE改进的授权码和accesstoken交换流程示意图如下:PKCE上图为PKCE模式下授权码申请和accesstoken交换流程,说明如下:(A)移动端App客户端创建并保存一个名为code_verifierRandomkeystring的文件,keystring加密转换的结果t(code_verifier)调用code_challenge,将转换后的code_challenge和转换方法一起发送给授权服务。(B)授权服务返回授权码并记录code_challenge和转换方法t_m。(C)手机App客户端收到授权码后,将授权码和code_verifierkeychain发送给授权服务器申请accesstoken。(D)授权服务器根据转换方法t_m转换code_verifier,与步骤A收到的code_challenge进行比较,一致则返回accesstoken,否则拒绝非法请求。第三方无法根据code_challenge推导出code_verifier,因为code_challenge采用了不可逆的加密方式。这两个值只有手机App客户端自己知道。因此,即使恶意App拦截了code_challenge和授权码,也无法换取accesstoken,避免安全问题。要实现手机APP的PKCE授权码方式,除了手机APP本身,还需要基于标准的授权码流程,对IAM授权服务器进行扩展实现。移动App安全认证详见官方规范:rfc8252-OAuth2.0forNativeApps(https://tools.ietf.org/html/rfc825)rfc7636-ProofKeyforCodeExchangebyOAuthPublicClients(https://tools.ietf.org/html/rfc825)://tools.ietf.org/html/rfc7636)2.3高度信任的特权客户端可以使用资源所有者密码凭证允许用户密码凭证0,用户是资源所有者,特权应用程序是客户端,IAM提供授权服务器(A)用户提供特权App用户名和密码。(B)特权App向授权服务器IAM提交用户凭证,并申请accesstoken。(C)授权服务器IAM验证用户的凭据,如果有效,则向特权应用程序颁发访问令牌。特权应用程序存储和更新授权服务器颁发的访问令牌和刷新令牌。其他注意事项:虽然它是一个特权应用程序,但该应用程序不应保留用户密码。只使用app在登录时保存AccessToken和RefreshToken。通常有两种接口:身份认证API和应用功能API。身份认证API:登录认证相关的API。为避免用户和客户端凭证泄露给第三方(IAM和访客除外),建议IAM系统直接向访客开放身份认证API或UI进行身份认证。应用功能API:功能实现来自于服务提供者,通过网关向访问者开放。网关是访问应用API的入口。用户登录认证由IAM授权服务器配合用户资源服务处理。身份验证成功后,IAM访问者会颁发访问令牌。后续访问应用功能时,必须携带访问令牌来表明访问者的身份。3.1网关负责客户端认证。网关是业务系统的API入口。当面对来自外网的访问者时,网关仍然是内外网的分界线。网关应负责访问令牌验证,令牌验证不应交给服务提供者。网关负责验证,可以防止未经验证的请求进入内网,并简化服务提供者的代码,使服务提供者不需要处理不同类型客户端的验证。其实,好处不止这些。网关可以进行统一流控,无需在应用侧重复构建类似功能;系统内部调试和敏捷变更,减少跨组织交互。网关验证accesstoken有两种方案:网关委托认证服务验证,网关直接验证。认证后,认证通过后才允许访问。网关委托IAM验证令牌。客户端认证成功后,使用UUID类型的访问令牌调用网关上的服务。由于UUID类型的token不包含客户端的信息,网关需要委托IAM认证服务来验证token。令牌检查是合法的。最后,即使请求路由到服务提供者应用,也无法解析token,需要根据UUIDtoken从IAM获取用户信息。方案二(推荐):网关直接认证需要网关识别IAM颁发的token。模式中推荐使用JWTtoken,网关需要具备解析和验证JWT加密访问令牌的能力。网关直接验证令牌。客户端认证成功后,使用JWTtoken调用网关上的服务。网关直接解密JWTtoken进行验证。token校验合法后,将请求路由到服务商。应用程序收到请求后,如果需要更多的权限信息,如果可以根据Token去权限管理服务获取权限信息(不是必须的步骤,需要的时候加上)。以上两种方案中,方案一中的token是一个没有业务意义的身份字符串,网关每次收到请求都会去IAM进行认证,这对IAM认证服务的性能造成了很大的压力。方案二,IAM颁发的token中包含一些客户端或用户信息,使用JWT加密,IAM提供认证方法或SDK给负责认证的网关。对于IAM来说,减少了每次请求token认证带来的通信次数,减轻了IAM的压力。建议使用选项2来实现令牌检查。需要注意的是选项2中的JWTtoken只包含必要的信息,不要放太多的角色权限信息。当后续功能需要附加信息时,可以根据token从IAM获取。如果token中存储了大量的权限数据,一旦后台的授权数据发生变化,就会导致token中的权限数据与实际的IAM权限不一致,只能强制用户下线登录又进来了JWT令牌是防篡改的,但未加密。如果需要存储在浏览器存储中,建议使用JWT+JWE的方式进行token加密。令牌中只能存储少量必要的数据,以避免滥用。大多数服务器通常会限制Http标头和cookie的长度。3.2系统内部应用是否通过网关?我的回答是否定的,不然太麻烦了。通常,网关由一个独立的团队负责,发布API变更、内部联调验证、跨团队协调是不可行的。建议系统内部的直接通信不通过网关,系统之间的访问必须通过网关。为此,应用程序还需要从请求源对客户端进行身份验证。这种认证方案不需要太复杂。应用应该只允许受信任的网关和系统内部应用访问其服务,不允许系统外部请求绕过网关直接调用它。因此,需要在这个小范围内建立网关与系统内部应用之间的信任。常见的解决方案有两种:方案一、内部令牌:系统中的应用在向网关发布接口时,提供一个系统内部令牌。共享令牌被提供给网关和系统中的所有应用程序。收到请求时,检查请求头是否包含系统中的可信令牌。如果包含可信令牌,则允许访问,否则拒绝第二个选项,系统中的机密性令牌+网关证书的单独认证:与系统中的机密令牌交互是第一种解决方案,但内部令牌不与共享网关。网关采用公私钥证书签名方式与域内系统建立信任。密钥被分配给每个系统。网关调用服务提供者时,在请求头中携带用私钥签名的token。应用收到请求后,用网关下发的公钥验证token。方案一的优点是实现简单,缺点是安全级别略低。在一个共同的企业架构中,不同的团队甚至不同的供应商将负责网关和业务系统的开发和维护。内部令牌与负责其他团队的网关共享。的风险。方案二比方案一稍微复杂一点,安全性更高。内部令牌用于系统内的互操作,网关提供的安全令牌检查方法用于系统和网关的认证。两种方案可根据实际需要选择。2.访问授权通过认证的API客户端是否可以访问网关开发的所有API?认证用户是否可以调用所有API?认证用户允许调用修改订单的接口,那么他是否可以修改所有人的订单呢?显然,在大多数场景下,以上三个问题的答案都是“否”。在大多数业务场景中,除了对访问者进行身份认证外,我们还需要进一步控制权限。1、API客户端访问网关接口时,网关需要控制API权限。如果访问者是API客户端,调用API的权限需要由网关控制。推荐采用先订阅后访问的授权方式。网关应该只允许API客户端访问他们订阅的API。具体实现方式是目前大多数网关提供的基于APIKey控制API访问的方式。应该注意的是,仅使用API密钥进行访问控制是不够的。APIKey是网关订阅API时生成的一串唯一数字,不具备识别客户端身份的能力。就像以前买火车票没有实名一样。谁拿到火车票,谁就可以乘坐相应的车次。火车票实行实名制后,需要先验证身份证,验证通过后才能购票乘车。如果车票不符,将不允许乘车。将客户端认证和APIKey结合起来进行访问认证和权限验证是一种更安全的方案。API权限控制上图是accesstoken结合APIKey进行鉴权认证的示意图。描述如下:Client1已获得APIKey,但没有有效的accesstoken。如果不允许匿名访问,网关会拒绝客户端1的访问,返回错误码401表示客户端没有通过认证;client2有合法的accesstoken,但是其APIKey不合法,gateway在client2认证通过后检查APIKey,发现其权限不足,如果返回403错误码,说明客户权限不足;客户端3具有合法的客户端访问令牌和API密钥来访问网关上的服务。发回正常响应数据。2、用户访问应用功能时,需要进行权限控制。用户访问的功能权限或数据权限不应受网关控制。原因是网关只能支持APIPath授权,需要控制的用户权限很多,比如菜单、API、数据等,如果用户权限由网关控制,少管理不满足需求,更多的管理会耦合太多的应用程序数据。因此,建议用户权限由业务系统自行管理、维护和控制。如果各个业务系统都需要对用户权限进行控制,可以搭建一个基础的权限框架来管理权限数据,并提供SDK给其他应用进行访问请求拦截和权限检查。也有一些企业对权限管理要求高。将系统内部的基础权限框架抽取出来作为一个独立的权限管理服务。服务由独立团队维护,分布式部署+权限缓存保证性能。这样做的好处是权限模型统一,便于审批、控制和审核权限变更。缺点是跨团队交互,变更过程复杂。关于权限管理,业务系统是自主管控还是集中管控,可以根据企业自身的需求和特点来决定。3.通信安全通信安全解决方案是基于传输过程的加密方法。常见的选择是使用Https协议进行通信。在微服务架构体系中,在逻辑层面上,外部请求通过网关作为入口进行访问,网关是内外网络的分界线。在实际部署中,网关本身也是一种多实例的分布式高可用部署形式。负载均衡器设置在它的前面。F5或者nginx用于对外提供Https协议访问和路由转发,而网关内部是企业内网,默认是信任的,内网系统之间的通信会使用更轻量级的HTTP协议。在这个方案中,微服务被SOA替代,网关被ESB替代,是传统SOA架构中的安全通信方案,本质上没有区别。示意图如下:为什么内外网通信协议都使用https来保证通信安全?https即http+ssl,利用密码学对通信报文进行加密,使报文不可篡改,实现安全传输,从而保证通信安全。网上关于https原理和负载均衡器证书配置的相关资料很多,请大家使用后尽快查阅。4、代码安全敏感的配置加密:说完上面提到的各种服务安全场景和解决方案,大家发现保管好token、keys和password是所有安全的前提。这些东西绝对不能泄露。确保密码不泄露的方法是对敏感数据保密。技术手段要求存储密码和凭据的地方(配置文件和数据库表)需要加密存储。如:配置文件中的数据库密码、数据表中存储的密码数据等。源码质量管理工具Sonar,可以支持多种编程语言,方便与Maven等编译构建工具集成。一些安全问题,比如SQL注入,可以在代码正式提交到相应分支之前,在前期进行预防。运行时安全扫描:在测试阶段,可以使用AppScan等安全扫描软件,对业务系统的前后端功能进行扫描,检查系统漏洞并及时修复。最大限度降低上线后安全事故的风险。5、管理审计运维管理安全,根??据安全要求,必须有安全相关的管理规范和工具支持,严格管控系统管理、权限分配和关键数据,做好运维审计日志记录。例如在很多安全级别较高的行业或企业,比如军工行业,对于业务系统的修改和权限管理审计,都做了严格的流程规范和功能支持。比如典型的三人管理,采用三权分立、相互制约的思想,包括系统管理员、安全管理员、安全审计员三个角色,他们可以看到彼此的信息,将业务流程划分到不同的段。科室由相应人员负责,谁也不能管大局。审计是一个非常重要的环节,没有一个系统或流程是绝对安全的。需要完整记录关键操作、数据变更等审计日志。一旦出现问题,您可以通过审计日志进行排查和跟踪分析。常见内容示例如下:访问敏感数据项(如密码)客户端注册、用户认证授权过程权限的授予和撤销、关键数据的变更、审计功能的删除、其他关键API的激活和关闭、访问命令等。在审计工作中,如果是基于API相关的审计信息记录,比如边界交互消息数据,建议基于统一的技术框架进行记录管理。对于一些内部实现方法,可以在接口和方法上注解,AOP拦截记录解决方案。其他情况下,审计数据存储方案可根据实际需要设计。
