今天谈下对API网关接入的接口服务进行安全管理方面的内容。
在原来谈Kong网关的时候,曾经谈到Kong网关和安全相关的插件能力,其中包括了身份认证插件:Kong提供了Basic Authentication、Key authentication、OAuth2.0 authentication、Hmac authentication、JWT、LDAP authentication认证实现。安全控制插件:ACL(访问控制)、CORS(跨域资源共享)、动态SSL、IP限制、爬虫检测实现。
这些内容相对还是比较抽象,因此准备重新再整理下对接口的安全管理。
接口安全实际上本身分为了传输安全,数据安全,访问控制安全。对于常说的Oauth2.0,JWT,Basic Authentication实际都属于访问控制安全范畴。对于访问控制安全本身又拆分为了认证和鉴权,但是很多时候两者又在混用,后面再展开。
对于传输安全一般会谈到Https和SSL,首先看下基本描述。
HTTPS 全称Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。
HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。对于SSL简单说明如下:
SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。
HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。
当实施Https传输安全的时候,就需要设置SSL证书,对于SSL数字证书有免费的,但是大部分都是商用和收费的,证书本身也有很大类型,不同类型的加密程度也存在不同。同时证书本身又分为了客户端和服务端证书,既可以实施单向,也可以实施双向。在条件允许的情况下,一般是两端都需要安装证书。
数据安全即常说的对数据进行加密处理。在前面谈传输安全的时候可以看到对于传输的数据已经进行了加密处理。即如果传输的内容被监听或拦截,获取到的信息是加密后的消息报文。
加密就有加密算法,加密算法又存在密钥。
明文+加密算法(密钥)=》密文
对于密钥本身又分为公钥和私钥,在对称加密方式下两者是一样的,但是非对称加密下两者不同,公钥是公开的,任何人都可以用公钥+算法来对文本进行加密,但是只有知道私钥的人才能够真正解开密文。
由于传输安全本身已经进行了加密处理,那么在API网关接入API接口服务的时候,实际上不涉及到数据安全的相关操作。
如果存在某些场景,即接口的调用方输入的数据,本身也不希望API网关能够看到详细的明文,那么这个时候就可以考虑对消息报文进行数据加密,或者说个别接口如涉及到工资薪酬等信息,那么也需要对个别字段信息进行加密处理。
这类数据加密接口消费方和接口提供方自己协商算法并进行处理即可,对于API网关来说并不需要接入到详细的数据加密过程。
对于API网关,即使企业数据安全也可以看到,对于消费方将消息报文发送到API网关的这段实际是没有进行数据加密的,而只能在API网关和后端Server进行数据加密。只有消费端在调用接口的时候就加密才能够做到端到端数据加密。
因此简单总结就是:就API网关来说一般不用参与具体的消息报文的数据加密,直接其余Https传输安全控制即可。
如上图,先举一个场景来进行说明:
即当前ERP接口服务注册和接入到API网关,API网关暴露接口服务给CRM,SRM等业务系统使用,同时ERP系统本身也有一个前端的微服务模块,需要调用ERP后端微服务的API接口,而这些接口不用注册到API网关,直接走注册中心方式调用。
两层的安全控制
首先要指出的是在引入了API网关接入和发布服务后,实际整体架构下面对的是两层的安全控制。即首先要控制CRM系统对API网关暴露服务的安全,同时还需要控制API网关和前端模块对后端ERP系统API接口服务的安全。
ERP提供的API接口的安全
在这里假设ERP系统后端微服务模块一共暴露了50个API接口,但是仅只有10个API接口注册和接入到了API网关,其他的40个API接口是ERP前端微服务模块访问使用。
对于ERP前端模块来说,更多是认证操作,只要认证通过即可以访问所有API接口服务。但是对于API网关来说,则是认证+鉴权,在认证通过后还需要确定具体那些API接口资源可以供API网关来进行调用。
API封装后暴露的API接口安全
对于API网关封装暴露的接口安全,同样包括了两个层面,一个是认证,一个是鉴权。由于API接口服务本身无状态,在这种无状态情况下实际认证和鉴权是绑定在一起来完成的。
比如对于CRM系统当前对API网关的接口服务发起调用,实际上需要处理两个事情。其一是该调用请求确实是CRM系统发起的,其二是确定CRM系统是否有调用这个接口的权限。
基于IP地址的安全控制
由于API网关暴露的接口最终使用的是业务系统而不是用户,比如CRM系统,SRM系统。因此可以增加IP地址来进行安全控制。
可以提前对每个调用端系统的IP地址进行配置,一个系统可以配置多个地址。
那么当某个sysid的系统发起调用请求后,我们首先校验过来的IP地址是否是我们已经配置并允许的IP地址,如果校验通过才放行,否则拒绝。
但是基于IP地址控制本次又存在两个问题。
其一是IP地址本身可以伪造,其二是在业务系统容器化改造后,实际业务系统的IP地址是在动态变化的,这两点都增加了IP地址控制的难度。
已经基本的用户名密码来控制
我们给每个系统都分配一个独立的用户名和密码,业务系统在调用API网关上的接口服务的时候,在http header里面带上用户名和密码信息。这个信息传递到API网关后,API网关对用户名和密码进行校验,只要验证通过后才放行。
在这种情况下本身也存在问题。
即用户名和密码泄露,但是在实施了Https安全传输后,通过Http拦截的方式来获取到用户密码信息已经不可能,那么密码往往是业务系统以其它方式出现了泄露。
实际上密码泄露,只要定期修改密码即可,这样已经满足大部分的场景要求。
前端微服务对后端微服务API访问
在这种场景下一般不适合用传统的Session会话保持方式来进行认证和鉴权,因此引入了JWT来实现认证和鉴权。
对于JWT具体介绍参考网上详细文章。
简单解释下就是对于服务端认证通过的客户端,服务端返回一个包含了数字签名的Token给客户端,这个token本事包括了客户端信息,有效期信息等。以后每次客户端对服务端的请求只需要附带这个Token即可。既只要客户端认证通过了,在Token的有效期里面都可以附带这个信息来访问服务端提供的接口服务。
JWT Token = Header+Payload+Signature
简单来说你发起请求调用的时候附加我当时颁发给你的Token,里面是含了签名信息,当前我接到请求后,我通过密钥对签名信息进行验证,通过后则放行。
这种方法实际和前面谈的用户名密码感觉并没有本质区别,因为Token本身也是类似密码的一种展现方式。那么走JWT方式认证鉴权的好处在哪里?
其一是只需要在认证的时候通过用户名密码,后续接口调用都不用再传递密码,减少了密码泄露的可能性。其次Token本身有时效性的要求,即使Token信息泄露,往往不会造成太大的影响。
在前面已经谈到启用了API网关后实际存在两层的安全控制。一个是CRM系统到API网关的安全,一个是API网关到ERP系统的安全。
在启用了JWT后可以看到,如果ERP系统认证通过了CRM颁发了一个Token给CRM系统,CRM系统每次在调用API网关接口的时候都附带了这个Token,API网关本身会将信息透传给后端的ERP系统。告诉ERP这个请求调用实际是你经过认证的CRM发起的,可以放行。
因此在这种情况下,我们不用再特意去处理API网关和ERP系统间的访问安全性。API网关在这里只起到了一个代理透传的作用。
那么CRM系统调用API网关接口,API网关是否转发该请求?
这个就涉及到了CRM和API网关之间的安全控制。
消费端系统和API网关间的访问安全
如何控制消费端到API网关的访问安全,实际道理是一样的,既可以采用简单的为每个消费端分配一个用户名和密码,进行基础的安全验证。也可以启用JWT,通过JWT来进行验证授权。
如果在API网关上也启用JWT,实际是另外一个思路,即变化为两级的安全控制。
消费方只要通过了API网关的鉴权就默认可以访问后端服务
后端服务本身只对API网关进行认证和鉴权
这个本身也是一种常用的方式,即对于ERP系统来说实际只需要考虑API网关的认证鉴权接口,这种情况下完全可以简化化双方约定一个key即搞定。
从静态Token到动态Token
在前面谈到,即使在采用JWT方式下,如果Token泄露,那么实际上是可以访问通过的,除非Token本身已经失效。因此更加好的方式是动态Token。
一种动态Token的生成方法是,每一次的接口调用消费端都需要从认证服务器获取到一个仅单次有效的Token,然后将Token传递到后端,后端基于Token进行验证。但是这种方式本身会带来不小的性能损耗。
另外一种动态Token生成方法可以是消费端和API网关间约定了一个基于时间作为密钥的来动态生成签名或加密信息的方法。
即:静态Token+和时间相关的Key => 动态Token
因此消费方在消费接口服务的时候,会基于当前的时间,然后基于双方约定的规则来生成一个动态的Token作为签名。而信息发送到API网关后,API网关基于同样的规则来计算签名,只有双方计算出来的结果一样的时候,才算验证通过。
这本身是一种更加严格的安全控制,即接口的调用中Token随时都在不断的变化。
Token的刷新
对于Token一般会设置有效时间,比如采用JWT方式的时候,Token里面本身就包含了Token本身的有效期信息。如果Token过了有效期,那么即使附带了Token信息调用,也会因为Token失效而调用失败。
因此需要一种Token的刷新机制。
比如消费端可以在Token过期前主动的调用接口来获取一个新的Token值,要获取新的Token值实际有两种方式可以选择。
其一是用初始化的用户名,密码来认证,认证通过后给新Token
其二是基于sysid+oldToken值进行调用,验证通过后发放新的Token
在新Token发放,同时旧的Token本身还没有过期的时候,实际上两个Token都应该可以调用成功。这个时候对于Token的验证应该支持这种情况。
接口访问授权
前面主要谈认证,比如CRM系统认证通过了可以访问API网关上的接口服务。但是并不是说所有的接口服务都可以访问。
接口服务本身是一种资源,满足基于资源的授权模型。
因此可以进行细粒度的接口服务授权,比如ERP提供提供了A到D四个接口服务。但是在API网关上可以控制或授权CRM系统只能够访问A和B两个接口。
如果CRM系统发起多D服务的访问,即在API网关层级就鉴权不通过而拒绝。
前面谈到在API网关的访问安全管理里面,往往认证和授权两个事情是同步完成的,即首先验证过来的请求是CRM系统的,没有仿冒。其次再进一步验证CRM系统对某个接口是否有访问权限。当前也可以参考RBAC模型方式,对一类业务系统或一组接口服务统一进行授权。
OAuth2.0安全控制
OAuth是Open Authorization的简写。
OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的。
在前面已经谈到了API网关和后端系统间是一套独立的安全机制,API网关对后端系统服务的访问并不是说需要前端CRM系统授权通过才可以。同时对于API网关在整个微服务架构下仍然是和内部IT系统在一个大的部署域内。
因此大部分场景下,API网关并不涉及到OAuth2.0的安全认证和控制,也没必要启用。如果考虑到不应该在API网关存储过重的业务系统用户名,密码等信息,那么直接和启用内部的LDAP统一认证中心进行集成即可。