在网络公司的面试中,面试官经常会问这样的问题
“禁用浏览器cookie时,如何实现用户跟踪和身份验证? ”
很遗憾,依然有很多候选人没有回答问题,无法分清cookie和session的区别。 工作中也有惊人的事例。 之所以将user ID保存在local storage中作为token使用,是因为他声称抛弃了cookie这样落后的东西。 移动端项目要求客户端模拟cookie以使用服务器提供的API,从而像浏览器中的ajax一样消耗API。
互联网建立在HTTP协议的基础上,而HTTP协议因为简单而普及。 但是,HTTP协议是无状态的(在通信水平上虚拟电路比数据报昂贵)。 因此,人们想出了cookie/session机制、token、flash跨浏览器cookie甚至浏览器指纹等多种方法来跟踪用户。
将用户id隐藏在任何地方(甚至不需要浏览器指纹技术) ) ) ) )。
虽然已经有很多使用spring security等具体技术的资料,但是本文不打算写框架和代码的具体实现。 介绍了认证和许可的区别,介绍了业界广泛采用的技术,最后介绍了如何为API构建选择合适的认证方式。
认证、许可、证书首先,认证和许可是两个不同的概念,为了更安全更清晰地设计API,必须了解认证和许可的区别。 这些是英语中也不同的单词。
身份验证是身份验证,是指当前用户的身份,用户登录后,系统可以跟踪自己的身份并按照相应的业务逻辑进行操作。 即使用户没有登录,大多数系统也会跟踪自己的身份,并将其作为来宾或匿名用户处理。 认定技术解决了“我是谁? 中选择所需的族。
与许可证不同,许可证是授权,意味着任何id都可以访问特定资源,并且在获得用户id后继续检查用户的权限。 大多数情况下,单个系统许可是通过身份验证进行的,但开放API的多系统配置允许在不同的系统(如OAuth )上进行许可。 许可技术是“我能做什么? ”的解决方案。 请参阅。
实现认证和授权的基础是媒体( credentials )需要标识访问者的身份或权利,现实生活中每个人都需要身份证才能访问自己的银行账户、结婚、办理养老保险。 这是认证的证书。 在古代军事活动中,皇帝给参战的将军颁发兵符,下级将军不关心拿兵符的人,执行与兵符相对应的命令即可。 在互联网世界中,服务器向所有访问者发放session ID并将其存储在cookie中。 这是证书技术。 数字证书还体现在SSH登录密钥、JWT令牌、一次性密码等各个方面。
用户帐户也不一定是数据库中存储的表,一些企业的IT系统要求更多的帐户管理和权限。 因此,帐户技术( accounting )有助于您以不同的方式管理用户帐户,并具有在不同系统之间共享帐户的能力。 例如微软的活动目录( ad )、有限目录访问协议( LDAP )甚至区块链技术。
另一个重要概念是访问控制策略( AC )。 在需要将资源权限划分为细粒度的情况下,考虑用户以何种身份访问有限的资源,基于访问控制列表( ACL )、基于用户的角色的访问控制( RBAC )或/和
在流行的技术和框架中,这些概念并不是孤立实现的,因此在现实中使用这些技术时,关于OAutp是认证还是许可的概念往往争论不休。 为了便于理解,在文末附上了常见技术和概念的术语表。 本节介绍了API开发中常用的几种身份验证和授权技术: http基本身份验证、HAMC、OAutp和身份验证技术JWT token。
http基本身份验证您应该使用过这种方式吧。 但是,我不一定知道那是什么。 不久前,进入家用路由器的管理界面时,经常会出现浏览器弹出表单,提示输入用户密码。
在这背后,用户输入用户名和密码后,浏览器给了我们非常简单的操作:
使用用户名和密码的组合进行Base64编码,并在编码字符串中添加Basic前缀。 然后,通过设置名为Authorization的头API,可以方便地提供http基本身份验证验证方法,从而使客户端可以方便地通过Base64传输用户名和密码。
用冒号连接用户名和密码。 例如,username:abc123456建议使用UTF-8编码对上述字符串进行Base 64编码,以避免用户名或密码中包含超出ASCII代码范围的字符。 例如,dXNlcm5hbWU6YWJjMTIzNDU2在HTTP请求报头中包含“基本编码的字符串”,即basicqwxhzgrpbjpcgvuu2vzyw1l 当然,Base64只被称为编码而不是加密的缺点也很明显。 (实际上,不需要设置加密密钥的客户端没有可靠的加密方案,而是依赖于TSL协议。 这种方式的致命弱点在于,编码密码以明文传输时容易在网络传输过程中泄露,如果密码不会过期,一旦密码泄露,就只能修改密码。
HMAC(AK/sk )认证是在对接几个PASS平台和支付平台时,事先请老师进行访问密钥( AK )和安全密钥( sk ),通过签名方式完成认证请求此外,在大多数情况下,签名只能使用一次,从而避免重放攻击
该基于AK/SK的认证方案主要是使用散列的消息认证码( hash-basedmessageauthenticationcode )来实现的,因此经常被称为HMAC认证,实际上不是非常准确。 HMAC只是利用具有key值的哈希算法生成消息摘要,在设计API时有具体不同的实现。
HMAC在网络通信身份验证设计中用作证书生成算法,以避免密码等敏感信息在网络中传输。 基本流程如下。
客户端必须在认证服务器上设置访问密钥(称为AK或app ID )和安全密钥( sk ),在调用API时,客户端按自然顺序对参数和访问密钥进行排序其他参数digest服务器基于预配置的secure key执行类似的摘要计算,注意secure key无法在网络上传输,并且存储在不可信的位置(例如浏览器),以满足每个请求
行业标准包括问答算法( ocra )、基于时间的一次性密码算法( totp )、基于时间的一次性密码算法
质询/响应算法质询/响应算法要求客户端向服务器请求一次,获取401个未经验证的返回,然后获取随机字符串( nonce )。 在以上述方式进行的HMAC签名中附加nonce,服务器使用预先分配的nonce同样地进行签名验证,由于该nonce在服务器中只被使用一次,因此能够提供唯一的摘要。
基于时间的一次性密码验证使用时间时间戳进行协商,以避免额外的请求并获取nonce,并且某些算法在同步时间中进行匹配,例如,在某些情况下
这里的只是为了验证而利用了时间时间戳,时间窗口并不是严格基于时间的一次性密码算法。 中选择另一种天花板类型。时间的一次性密码算法多用于两阶段认证。 例如,谷歌认证功能不需要网络通信就可以实现认证。 但是,它取决于准确的时间服务。 原理是客户端服务器可以共享密钥,并通过时间窗口计算HMAC算法中的相同认证码。
TOTP的基本原理和常见厂家
OAutp和Open IDOAuth是开放标准,允许第三方网站访问存储在其他服务提供商处的信息,而无需向第三方网站提供用户名和密码,也无需共享数据的全部内容
OAuth是许可标准而不是认证标准。 提供资源的服务器无需知道准确的用户身份( session ),而是可以验证认证服务器已授予的权限( token )。
上图只是OAuth的简化过程。 OAuth的基本思想是通过许可服务器获取访问token和Refreshtoken,然后使用Refreshtoken从资源服务器获取数据以重新更新访问token。 在特定场景中,还有以下模式:
授权码模式“授权码”简易模式“输入”密码模式“资源密码”客户端模式“客户端身份证明”
在介绍验证访问令牌的OAuth的博客中,很少提到资源服务器是如何验证访问令牌的。 虽然OAuth core标准没有定义本节,但OAuth的其他标准文档中提到了验证access token的两种方法。
批准过程完成后,资源服务器可以使用OAuth服务器提供的解释界面验证访问工具包。 OAuth服务器返回访问令牌的状态和过期时间时间。 在OAuth标准中,验证token的术语是Introspection。 还必须注意,访问令牌是用户和资源服务器之间的证书,而不是资源服务器和许可服务器之间的证书。 资源服务器和许可服务器之间必须使用其他认证,如Basic认证。 使用JWT认证。 认证服务器使用私钥发布JWT格式的访问密钥。 资源服务器必须使用预配置的公钥验证JWT token,以获取token的状态和访问token中包含的信息。 因此,在JWT方案中,资源服务器和许可证服务器不需要进行通信,在一些场景中会带来很大的好处。 同时,JWT也有一些弱点。 在JWT部分进行说明。 refresh token和access token在大多数人刚开始认识OAuth的时候,都有一个疑问,为什么已经有了access token而需要refresh token。
许可服务器在初始许可请求时将访问token和refresh token一起返回,之后更新访问token时只需要refresh token。 access token和refresh token的设计意图不同。 access token设计用于客户端和资源服务器之间的交互,而refresh token设计用于客户端和许可服务器之间的交互。
根据许可模式,access token必须发布到浏览器,并充当资源服务器和浏览器之间的临时会话。 由于浏览器和资源服务器之间不存在签名机制,访问主题是唯一的证书,因此访问主题过期时间时间(TTL )尽可能短,用户的访问主题不会被窃取
由于access token时间很短,因此refresh token有助于用户保持长时间的状态,并避免频繁的重新许可。 我想大家只要让access token维持较长的有效期限时间就可以了。 实际上,refresh token和access token的区别在于,即使refresh token被拦截,系统也是安全的,客户端需要预先配置的secure key才能拥有refresh token获取access token
OAuth、Open ID和OpenID Connect身份验证术语太多,在构建您自己的身份验证服务器或访问第三方身份验证平台时,您可能要到开发完成后才能理解这些术语。
即使客户端和资源服务或认证服务位于同一台计算机上,OAuth也负责解决分布式系统之间的许可问题。 OAuth虽然没有解决认证问题,但提供了有利于与现有认证系统对接的设计。
Open ID解决的问题是分布式系统之间的认证问题,使用Open ID token可以在多个系统之间认证用户,返回用户信息,与OAuth无关,可以独立使用。
OpenID Connect解决了OAuth体系下的用户认证问题,其基本原理是将用户的认证信息( ID token )作为资源处理。 在OAuth框架下完成许可后,通过access token获取用户的id。
这三个概念的关系有点难以理解,但在现实情况中,如果系统内需要独立的认证系统,则直接采用Open ID不需要多系统之间的许可证。 如果使用OAuth作为许可条件,则可以使用OpenID Connect来完成用户的身份验证。
JWT在OAuth等分布式认证、授权体系下,对证书技术有了更多的要求。 例如,包括诸如用户ID、过期日期等信息,并且无需与外部存储相关联。 为此,业界对token进行了进一步的优化,设计了一种自包含式令牌,通过分析令牌可以获取令牌的过期日期、有效性等信息,而无需在令牌发放后从服务器存储中检查其是否合法。 这就是jwt(JSONwebtoken )。
JT包含令牌( self-contained token )或value token ),以前与session关联的散列值称为参考令牌。
简单来说,基本的JWT令牌是一段一段分为三段的结构。
eyjhbgcioijiuzi1niisinr5CCI6ikpxvcj9. eyjzdwiioiixmjm0nty3odkwiiwibmftzsi6ikpvag4grg9liwiywrtaw4ionrydwv9. tjva 95 ORM 7e 2c Bab
生成JWT令牌的过程如下
头json的基本64被编码在作为令牌的第一部分的支付json中的基本64被编码在用作为令牌的第二部分的第一和第二部分编码的用json和secret签名的令牌的第三部分中由于使用了加密算法,只要在消息主体中添加用户ID、有效期限信息,就可以验证令牌是否有效、是否有效,因此即使第一、第二部分发生了变更,包括过期信息在内也无法通过验证。 jt的优点是不仅可以作为token使用,还可以承载必要的信息,省去多次(查询 )。
注意:
根据JWT token的自包含特性,JWT token的第一、第二部分只有base64码,肉眼看不到,不应该保存敏感信息,因此无法从JWT撤回的签名算法可以自行编写,为了便于调试,本地环境为对称加密算法生产环境提出使用非对称密码算法JWT token在微服务器系统中具有特别优势。 多层调用的API可以直接传递JWT token,利用自带能力,减少用户信息查询次; 更重要的是,使用非对称加密方法,可以通过向系统分发密钥来验证JWT token。
当然,OAuth对用于访问token等证书的技术没有限制。 OAuth并不是强制使用JWT,在使用JWT自包含特性的优点时,必须考虑到JWT撤回的困难。 一些对撤回token要求很高的项目不适合使用JWT。 另外,即使采用了几个方案来实现( whitelist和blacklist ),也与设计JWT的初衷相违背。
Cookie、Token in Cookie和Session Token仍然用于构建API,开发人员会发现我们的身份验证方式与web APP应用程序略有不同。 除了典型的web技术(如ajax )之外,如果希望API是无状态的,则不推荐使用Cookie。
使用Cookie的本质是在用户首次访问时为服务器分配一个会话ID,然后客户端会将该ID作为当前用户的标志进行后续请求。 因为HTTP本身是无状态的,所以Cookie是一种嵌入浏览器以实现状态的方法。 如果我们的API是用于客户端的,那么强制要求API的调用者管理Cookie也可以完成任务。
对于不是传统或标准身份验证实现的项目,可以查看这些方法以快速实现身份验证。
使用饼干。 例如,像web项目中的ajax一样,使用session ID或hash作为token,但如果将token放入header中并传递,则会将生成的token (可能是JWT )放入coookie中。 选择仅http和安全标签上保护token的合适认证方式随着微服务的发展,API的设计不仅适用于WEB或移动app,还适用于后台前端( BFF )和域名API的认证
客户端到服务器的认证与服务器到服务器的认证不同。
最终用户( Human )参与的通信称为human-to-machine(h2m ),服务器和服务器之间的通信称为machine-to-machine ( m2m )。
H2M的通信需要更高的安全性,M2M的通信比H2M更天然安全,因此更加强调性能,根据情况选择合适的认证技术尤为重要。 例如,HTTP Basic Authentication作为H2M认证使用有点晚,但在M2M中被大量使用。
另外,在H2M的通信方式中,由于客户端不受控制,无法独自发布加密密钥,因此认证通信的安全性高度依赖于HTTPS。
从宏观的角度看他们的关系,对我们的技术选定非常有帮助。
术语表
Browser fingerprinting通过查询浏览器的代理字符串、屏幕颜色浓度、语言等。 然后,这些值被传递给散列函数以生成指纹,从而允许浏览器消息身份验证代码( MAC )在不通过Cookie的情况下通过密码学识别消息认证码。 基于散列消息认证码的一次性密码算法two-timepasswordalgorithm ( hotp ),使用经过特定算法生成的短消息检查消息的完整性多因素身份验证中的特殊一次性OTP (一次性密码)密码,包括注册邮件和短信验证码参考文章,使用两种不同的元素进行统一验证
3359 swagger.io/docs/specification/authentic ation/basic-authentic ation /
hmac:keyed-hashingformessageauthentication
hotp:an hmac-based one-timepasswordalgorithm
ocra:oath challenge-response algorithm
the oauth 2.0授权框架
Jonwebtoken(jwt ) )。
OAuth 2.0
Internet-Draft Archive for OAuth
文/ThoughtWorks林宁
原文: 3359 insights.thoughtworks.cn/API-2 /
更多精彩洞察,关注微信公众号: ThoughtWorks洞见