设计模式之美04--设计一个鉴权服务; 防重攻击

设计一个鉴权服务;
每个URL拼接上AppID、密码生成的token都是固定的。未认证系统截获URL、
token和AppID之后,还是可以通过重放攻击的方式,伪装成认证系统,调用这个URL对应的接口。
为了解决这个问题,我们可以进一步优化token生成算法,引入一个随机变量,让每次接口请求生成的token都不一样。我们可以选择时间戳作为随机变量。
原来的token是对URL、AppID、密码三者进行加密生成的,**现在我们将URL、AppID、密码、时间戳四者进行加密来生成token。**调用方在进行接口请求的时候,将token、AppID、时间戳,随URL一并传递给微服务端。
微服务端在收到这些数据之后,会验证当前时间戳跟传递过来的时间戳,是否在一定的时间窗口内(比如一分钟)。如果超过一分钟,则判定token过期,拒绝接口请求。如果没有超过一分钟,则说明token没有过期,就再通过同样的token生成算法,在服务端生成新的token,与调用方传递过来的token比对,看是否一致。如果一致,则允许接口调用请求;否则,就拒绝接口调用请求
设计模式之美04--设计一个鉴权服务; 防重攻击

  1. 调用方进行接口请求的时候,将URL、AppID、密码、时间戳拼接在一起,通过加密算法生成token,并且将token、AppID、时间戳拼接在URL中,一并发送到微服务端。

  2. 微服务端在接收到调用方的接口请求之后,从请求中拆解出token、AppID、时间戳。

  3. 微服务端首先检查传递过来的时间戳跟当前时间,是否在token失效时间窗口内。如果已经超过失效时间,那就算接口调用鉴权失败,拒
    绝接口调用请求

  4. 如果token验证没有过期失效,微服务端再从自己的存储中,取出AppID对应的密码,通过同样的token生成算法,生成另外一个
    token,与调用方传递过来的token进行匹配;如果一致,则鉴权成功,允许接口调用,否则就拒绝接口调用。

  5. 充值类业务,就算对方篡改接口,最终结果可以通调用证金融机构的接口验证是否有效,不会给公司带来损失。

  6. 如果安全等级非常高,比如提现、转账可以通过发送手机短信,确保是本人操作。

  7. 如果是商品信息查询类接口,防止第三方爬取数据,可以在调用一定次数后加入”人机验证“(输入图片识别码、拼图)。

  8. 根据IP限制访问次数。

  9. 服务器间调用可以绑定mac地址、IP。

  10. 服务器、客户端通过架设私有v*n进行通信,将安全问题转移到v*n上,降低业务复杂度的同时还可以避免加解密带来的性能
    损耗,提升性能。

  11. 调用接口时通过付费方式(如实名认证、银行四要素验证这些调用一次都是要收费的),防止恶意调用。

  12. 通过独立加密硬件(如U盾)+ 独立密码验证器(Google验证器)+ 语音识别 + 面部识别(刷脸支付) + 指纹 + 多人同时输
    入动态秘钥(核打击时发射程序)。

  13. 安全性会降低系统性能适可而止。

防止重放攻击的方案在老师的基础做进一步的迭代设计:
1.要求客户端生成一个唯一的请求id,如以uuid方式
2.客户端在以sha等加密哈希方式生成token时,也将请求id加入其中
3.客户端也要将请求id作为参数传递到服务端,如果是rest api就是也要将请求id拼接到url参数中
4.服务端检查服务端的缓存中(可以是redis)是否有客户端传递的请求id,如果有,则判定为重放攻击,拒绝请求。如果没有,则将
请求id放到缓存中同时设置在token失效的时间窗内缓存的请求id自动失效(如redis key的TTL)
这个实现思路是: 在时间窗内的重放攻击,以服务端在时间缓存了在时间窗内的所有请求id的形式来防护,而在时间窗外的重放攻
击就是老师的方案中检查客户端传过来的时间(时间戳)和服务端当前时间(时间戳)相减的绝对值不能超过时间窗的长度来实现。另
外,时间戳、请求id等都hash在了token
中,所有客户端是无法篡改的。
这个实现思路的缺点是: 改实现方案要求客户端的时间和服务端的时间之间的差距不能超过时间窗,如果时间窗设置为1分钟这种比
较小的,则要求客户端时间和服务端时间不能超过1分钟,这个有点苛刻,比如客户端如app所在的手机的时间不准确了,但就差1
分钟,将无法访问接口。如果时间窗设置过长,如30分钟,则要求服务端缓存中缓存最近30分钟的请求id,如果接口的访问并发挺
大的话,缓存占用空间也将很大,需要评估。