上一篇“登录工程”的文章介绍了《现代Web应用中的典型身份验证需求》,现在是时候介绍适应现代Web应用的认证实践了。登录系统首先,我们需要对“登录”做一个简单的定义,以便后面的描述更加准确。前两篇文章有意无意混淆了“登录”和“认证”这两个词,因为在本文之前,很多“传统Web应用”都将身份的识别视为整个登录过程,很少出现像那些复杂的场景和需求在企业应用程序环境中。但是从之前的文章中我们看到,现代Web应用对于身份验证的要求变得更加复杂。我们有必要重新认识一下登录系统。登录是指从识别用户身份到允许用户访问与其权限对应的资源的过程。比如网上买票后去电影院看电影的过程就是一个典型的登录过程:我们先去售票机,输入验证码取票;然后取票去影院检票。取票的过程就是身份验证,可以证明我们有这张票;而后面查票的过程就是授权访问的过程。分成这两个流程最直接的原因是业务形式本身的复杂性——如果查看流程是免费匿名的,这些流程就会被淘汰。在登录过程中,“认证”和“授权”是最关键的两个过程。接下来要介绍的一些技术和实践也包含在这两个方面。虽然现代Web应用的登录需求比较复杂,但是只要处理好认证和授权这两个方面,其他方面的问题也就迎刃而解了。在现代Web应用的登录工程实践中,需要结合传统Web应用的典型实践和一些新的思路,既要解决登录需求,又要符合Web的轻量级架构思想。常见登录场景解析在一个简单的web系统中,典型的认证是要求用户输入并比对用户名和密码的过程,而授权则是保证sessioncookie的存在。在稍微复杂一点的Web系统中,需要考虑多种认证方式和授权场景。上一篇文章中描述的“多种登录方式”和“双因素认证”就是多种认证方式的例子。有经验的人常开玩笑说,只要懂得认证和授权,就能清楚地理解登录系统。不仅如此,它还是安全登录系统的基础。认证方式多种多样,传统的用户名密码对、客户端证书、第三方登录、人们越来越熟悉的手机验证,以及新兴的扫码、指纹等方式,都可以用于验证用户。身份被识别。在成功识别用户之后,在用户可以访问资源或者进行操作之前,我们还需要对用户的操作进行授权。在一些特别简单的情况下——一旦被识别,用户就可以无限制地访问资源并可以执行所有操作——系统只是将访问权限授予所有“登录人员”。比如高速公路收费站,只要车辆有合法车牌,就可以放行,不需要给司机开罚单,注明“允许行驶的方向或者时间”。除了这种极其简单的情况,授权更多的时候是一件比较复杂的工作。在单一的传统Web应用中,授权过程通常由一个会话cookie来完成——只要服务器发现浏览器携带了相应的cookie,就允许用户访问资源和进行操作。在浏览器之外,例如WebAPI调用、移动应用、富Web应用等场景,需要token技术提供安全灵活的授权方式。Token是各种介绍登录技术的文章中经常提到的一个概念,也是现代Web应用系统中非常关键的技术。令牌是一个非常简单的概念,指的是在用户通过身份验证后分配给用户的临时凭证。在系统内部,各子系统只需统一正确识别和处理该凭证,即可完成对用户访问和操作的授权。在上面提到的例子中,电影票是一个典型的令牌。影厅入口处的工作人员只需确认来访者持有的是对应演出的电影票,即视为合法参观,无需关心顾客从何种渠道获得电影票(如自己购买、朋友赠送等),电影票可在本场次范围内连续使用(如中场休息时可外出休息等),成为到期后无效。通过电影票等简单的代币机制,电影票可以在各个渠道销售,但验票员的工作还是简单轻松的。从这个例子也可以看出,代币并不是什么神奇的机制,而是一种非常普遍的做法。还记得第一篇文章中的“独立cookie”吗?它实际上只是一个写有有效性的标记——就像电影票上写着“与剧院号码相同”一样。可见,在Web安全体系中引入令牌,具有与传统场合同样的妙用。在安全系统中,令牌通常用于包含安全上下文信息,例如标识的用户信息、令牌发行来源、令牌本身的有效期等。此外,如果需要,系统可以撤销令牌,下次使用它进行访问、操作时,用户将被禁止。由于代币具有这些特殊的神奇功能,安全行业对于代币标准的制定也一直没有停止过。在现代Web系统的演进过程中,流行的方式是选择基于Web技术的“简单”技术来替代相对复杂、重量级的技术。通常,例如,使用JSON-RPC或REST接口而不是SOAP格式的服务调用,使用微服务架构而不是SOA架构等等。适用于Web技术的令牌标准是JsonWebToken(JWT),它指定了一种基于JSON的令牌的简单格式,可用于安全地封装安全上下文信息。OAuth2、OpenIDConnect令牌用于广泛使用的OAuth技术来完成授权过程。OAuth是一种开放的授权模型,它规定了资源拥有者和消费者之间一种简单直观的交互方式,即由消费者向资源拥有者发起一个经过AccessToken(访问令牌)签名的HTTP请求。这样,消费者应用程序就不需要(也不能)获取用户凭证。只要用户完成认证过程,并同意消费者以自己的身份调用数据和操作,消费者就可以获得一个可以完成功能的访问令牌。卡片。OAuth简单的流程和自由的编程模型,使其很好地满足开放平台场景下授权第三方应用使用用户数据的需求。很多互联网公司搭建开放平台,将自己平台上的用户数据以API的形式开放给第三方应用,让用户享受到更丰富的服务。OAuth在各种开放平台的成功运用,让更多的开发者了解它,并被它简洁明了的流程所吸引。另外,OAuth协议规定了授权模型,并没有规定accesstoken的数据格式,也没有限制整个登录过程中需要使用的认证方式。人们很快发现,只要使用得当,OAuth可以在自己的系统中用于多种场景。例如,将Web服务视为资源所有者,将丰富的Web应用程序或移动应用程序视为消费者应用程序非常适合开放平台场景。另一个经常使用的场景是基于OAuth的单点登录。OAuth没有规定认证部分,也没有要求在握手交互过程中包含用户的身份信息,因此不适合作为单点登录系统使用。但是,由于OAuth流程中隐藏了认证步骤,所以很多开发者仍然将这个认证步骤作为单点登录系统,成为一种实用的模式。有人把这种做法标准化了,就是OpenIDConnect——一种基于OAuth的身份上下文协议,通过它可以以JWT的形式在多个应用之间安全地共享用户身份。其次,只要认证服务器支持更长的会话时间,就可以使用OAuth为多个业务系统提供单点登录功能。我们还没有讨论OAuth对身份验证系统的影响。事实上,OAuth对认证系统没有任何影响。在它的框架内,只是假设已经有一个有效的识别用户的机制,而这个机制是如何工作的,OAuth并不关心。因此,我们不仅可以使用用户名和密码(大多数开放平台提供商都使用这种方法),还可以使用扫码登录来识别用户,我们还可以提供其他功能,例如“记住密码”或双因素认证.总结上面列出的大量术语和解释,在一个典型的Web系统中如何设计一个安全系统呢?结合这些技术,从端到云端,从Webportal到内部服务,本文给出了如下架构方案建议:建议对整个应用的所有系统和子系统部署全HTTPS。如果出于性能和成本考虑而无法做到这一点,那么至少要确保在用户或设备直接访问的整个Web应用程序中使用HTTPS。使用不同的系统进行身份和登录,以及业务服务。用户登录成功后,使用OpenIDConnect向业务系统下发一个JWT格式的accesstoken和身份信息。如果需要,登录系统可以提供多种登录方法,或增强功能,例如双因素登录。作为安全令牌服务(STS),它还负责发行、刷新、验证和撤销令牌的操作。在每一步认证过程中,都会使用OAuth和JWT中内置的机制来验证数据的来源是否可信:登录系统必须保证登录请求来自于经过审核的业务应用,并且业务获得token之后还需要验证token的有效性。在网页应用中,应申请时限较短的token。将获取到的token以httponly方式作为sessioncookie写入客户端页面,用于后续请求的授权;当后续请求到达时,验证请求中携带的令牌并延长其有效期。基于JWT的自包含特性,辅以完整的签名认证,Web应用不需要维护额外的会话状态。在富客户端web应用(单页应用),或者移动端和客户端应用中,可以根据应用的业务形式,申请一个时限较长的token,或者使用时限较短的token,配合使用专用刷新令牌。Web应用的子系统之间,在调用其他子服务时,可以灵活使用“应用标识”(如果服务根本不直接向用户提供调用),也可以使用用户传入的token直接传递给被调用的服务,通过这种方式进行授权。每个业务系统都可以结合基于角色的访问控制(RBAC)开发自己专用的权限系统。作为工程师,我们不禁要思考一下。既然登录系统的需求可能很复杂,而且很多时候大家面临的需求又很相似,那么有没有现成的(OutofBox)解决方案呢?自然是有的。IdentityServer是一个完整的开发框架,提供了普通登录OAuth和OpenIDConnect的完整实现;OpenAM是一个开源的单点登录和访问管理软件平台;而MicrosoftAzureAD和AWSIAM在公共云身份服务上。几乎每个级别都有现成的程序。使用现成的产品和服务可以大大降低开发成本,尤其是为创业团队快速构建产品和灵活变革提供了更有力的保障。本文简要介绍了登录过程中涉及的基本原理,以及现代Web应用中身份验证的几种实用技术,希望对您开发身份验证系统有所帮助。现代Web应用的身份验证需求多变,应用本身的结构也比传统Web应用复杂。要求架构师在明确登录系统基本原理的基础上,灵活利用各种技术的优势来解决问题。问题。【本文为专栏作家《ThoughtWorks》原创稿件,微信公众号:Thinkworker,转载请联系原作者】点此查看该作者更多好文