API安全认证技术(翻译)

在网上看到的一个API安全认证技术对比表格,觉得蛮好的,方案选型时用的上,MARK并翻译一下。

原文来自:Authentication Techniques for APIs

Hexo的表格渲染太烂了。。。还是看原文吧

           HTTP Basic Auth Stateless Session Cookie JWT Stateful Session Cookie Random Token Full Request Signature OAuth
简介 基础认证,需要每个请求都附带用户名与密码 对包含用户信息的cookie进行签名或加密,通常Web框架可以处理 对用户信息签名或加密到一个编码后的json字符串,每个语言都有经过良好测试的类库可以利用 标准cookie,大部分web框架和浏览器支持 一个不包含任何信息 强壮、安全的随机令牌,无法被猜测。等价于session id 通过AWS认证普及开来的一种机制。客户端与服务端共享一个秘钥,客户端使用这个秘钥对整个请求进行签名,服务端通过这个秘钥对请求进行验证。AWS文档 当你想从第三方应用中获取你用户的信息,可以使用这种机制。如果你没有第三个应用,oauth机制则有点大材小用
适用场景 最好仅用在内网没什么价值的服务端接口认证 如果仅仅开发一个基于web的应用,并且你的框架支持,而且你没有一个类似Redis/Memcache的分布缓存,那么可以用用,但不要自己实现(利用框架或容器) 当你可以放弃自动过期与主动失效机制时,原生移动端,web移动端,服务端适用 适用于可以把信息存储到数据库或分布式缓存中的web应用 如果你有一个类似redis或memcache的分布式缓存那么web应用与移动应用适用,服务端更适合基于JWT的一次性令牌 当你为你的客户端提供管理加解密算法的类库并且在意重放攻击的服务端应用适用。实际上,为每个请求使用JWT并且将url和关键请求参数包含到JWT中,这种方法最大的好处是不用实现复杂的标准算法 适用于你要从外部第三方应用获取数据并且你的用户授权第三方应用提供他的数据给你的场景,如果不是,oauth有点大材小用
存储机制 用户名密码存储在服务端。用户名密码附带在每个请求上,服务端通过传递过来的用户名密码校验用户是否合法,校验通过后进行请求对应的操作 存在cookie中 编码后的json(令牌)中 服务端的内存、数据库、分布式缓存或磁盘中 服务端的内存、数据库、分布式缓存或磁盘中 服务端,userid通过请求传递,服务器通过签名确定用户,然后从数据库中获取想要的信息 TBD
过期策略 无,服务器端管理 有,cookie控制 有,令牌控制 有,服务端控制 有,服务端控制 通过请求传递,通常仅设置一个很短的时间 TBD
加密机制 有,通常web框架处理 有,有成熟的第三方类库 有,但是AWS没有提供类库,可以提供一个自己的客户端类库,否则很痛苦 TBD
闲置过期(失效/超时) 无,不要将此技术用于基于Web的客户端 服务端需要为每个请求的cookie设置新的超时时间,如果web框架不支持,自己处理会很痛苦 有很痛苦,你需要刷新客户端提供令牌,并且要在数据库或缓存中维护令牌最后一次请求时间,而且已然失去无状态的好处 有,每个web框架都以实现 有,每个进来的请求在服务端判断超时时间 无意义 TBD
主动失效 无,不要将此技术用于基于Web的客户端(前面直翻,其实依赖服务端) 很痛苦,需要在一个分布式存储中维护一个撤销列表。这样已然失去无状态的好处 很痛苦,需要在一个分布式存储中维护一个撤销列表。这样已然失去无状态的好处 有,实际上取决于使用的web框架 有,在服务端删除生成的令牌那么下个进来的请求将被认为未授权的请求 有,服务端可以请求拒绝请求 TBD
浏览器存储 无,不要将此技术用于基于Web的客户端 浏览器自动存储,程序无需处理 有,开发人员需要编码存储token。通常是sessionStorage或localStorage中 浏览器自动存储,程序无需处理 有,开发人员需要编码存储token。通常是sessionStorage或localStorage中 不适用,此机制不适合web应用 TBD
凭证传递 通过HTTP头 Authorization传递。
Example:
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l 用户名密码没有被加密
通过cookie传递,浏览器自动发送到服务器 通过请求头Authorization: Bearer <token>传递,开发人员需要编码为每个请求添加 通过cookie传递,浏览器自动发送到服务器 通过请求头Authorization: Bearer <token>传递,开发人员需要编码为每个请求添加 通过请求头Authorization传递,但是适用自定义的schema替换了”bearer”。开发人员需要编码为每个请求添加 TBD
CSRF预防 非常脆弱,不要用在基于Web应用,除非是非常没价值的内网web应用 非常脆弱,开发者需要自己预防跨站脚本攻击 可以预防,请求头中包含token 非常脆弱,开发者需要自己预防跨站脚本攻击 可以预防,请求头中包含token 不适用,此机制不适合web应用 TBD
移动端适用 不要使用,web应用无法安全的存储凭证,同时用户也不会想手动的为每个请求输入凭证 原生移动端会很痛苦,避免为原生移动端基于session认证的api 移动端用户期望只需登录一次,JWT通过设置一个长的失效时间可以实现,但是更好的策略是用一个不存储任何信息的安全随机令牌 原生移动端会很痛苦,避免为原生移动端基于session认证的api 在第一次登录的时候创建一个随机令牌,在app的整个生命周期中使用它 不适用,此机制不适用web应用 TBD
服务端适用 如果服务端应用(内网相互调用的服务)基于HTTPS,基础认证也许是个不错(方便)的选择。基础认证使用非常简单,客户端与服务端框架的支持非常好 服务端应用会很痛苦,避免为服务端提供基于session认证的api 创建一个公私秘钥对,然后让客户端使用私钥生成JWT,服务端通过公钥进行验证。也可以维护一个共享的口令来创建JWT。当然公私秘钥对最佳。为每个请求创建JWT,同时设置一个很短的过期时间 服务端应用会很痛苦,避免为服务端提供基于session认证的api 类似客户端传递api key,不过如果其他人获取了api key有可能造成重放攻击。服务端最好使用JWT公私秘钥对 如果服务端需要更高的安全性这是首选,原则上类似JWT共享秘钥,但在此机制下所有的东西都会被签名:url、请求参数、请求头、请求体 TBD
重放攻击预防 绝对有可能 有可能 如果过期时间很长,那很有可能,如果每个请求的JWT只用一次那么重放会变的很难 有可能 有可能 所有东西都被签名了,不可能重放 TBD