某某茶叶有限公司欢迎您!
金沙棋牌在线 > Web前端 > 传统 Web 应用中的身份验证技术

传统 Web 应用中的身份验证技术

时间:2019-12-03 00:06

传统 Web 应用中的身份验证技术

2016/12/13 · 基础技术 · WEB, 身份验证

本文作者: 伯乐在线 - ThoughtWorks 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

标题中的 “传统Web应用” 这一说法并没有什么官方定义,只是为了与“现代化Web应用”做比较而自拟的一个概念。所谓“现代化Web应用”指的是那些基于分布式架构思想设计的,面向多个端提供稳定可靠的高可用服务,并且在需要时能够横向扩展的Web应用。相对而言,传统Web应用则主要是直接面向PC用户的Web应用程序,采用单体架构较多,也可能在内部采用SOA的分布式运算技术。

一直以来,传统Web应用为构成互联网发挥了重要作用。因此传统Web应用中的身份验证技术经过几代的发展,已经解决了不少实际问题,并最终沉淀了一些实践模式。

图片 1

在讲述多种身份鉴权技术之前,要强调一点:在构建互联网Web应用过程中,无论使用哪种技术,在传输用户名和密码时,请一定要采用安全连接模式。因为无论采用何种鉴权模型,都无法保护用户凭据在传输过程中不被窃取。

标题中的 “传统Web应用” 这一说法并没有什么官方定义,只是为了与“现代化Web应用”做比较而自拟的一个概念。所谓“现代化Web应用”指的是那些基于分布式架构思想设计的,面向多个端提供稳定可靠的高可用服务,并且在需要时能够横向扩展的Web应用。相对而言,传统Web应用则主要是直接面向PC用户的Web应用程序,采用单体架构较多,也可能在内部采用SOA的分布式运算技术。

登录工程:现代Web应用中的身份验证技术

2017/05/10 · 基础技术 · WEB, 登录

本文作者: 伯乐在线 - ThoughtWorks 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

“登录工程”的前两篇文章分别介绍了《传统Web应用中的身份验证技术》,以及《现代Web应用中的典型身份验证需求》,接下来是时候介绍适应于现代Web应用中的身份验证实践了。

文/ThoughtWorks 陈计节

Basic和Digest鉴权

基于HTTP的Web应用离不开HTTP本身的安全特性中关于身份鉴权的部分。虽然HTTP标准定义了好几种鉴权方式,但真正供Web应用开发者选择的并不多,这里简要回顾一下曾经被广泛运用过的Basic 和 Digest鉴权。

不知道读者是否熟悉一种最直接向服务器提供身份的方式,即在URL中直接写上用户名和密码:

1
2
http://user:passwd@www.server.com/index.html
 

这就是Basic鉴权的一种形式。

Basic和Digest是通过在HTTP请求中直接包含用户名和密码,或者它们的哈希值来向服务器传输用户凭据的方法。Basic鉴权直接在每个请求的头部或URL中包含明文的用户名或密码,或者经过Base64编码过的用户名或密码;而Digest则会使用服务器返回的随机值,对用户名和密码拼装后,使用多次MD5哈希处理后再向服务器传输。服务器在处理每个请求之前,读取收到的凭据,并鉴定用户的身份。

图片 2

Basic和Digest鉴权有一系列的缺陷。它们需要在每个请求中提供凭据,因此提供“记住登录状态”功能的网站中,不得不将用户凭据缓存在浏览器中,增加了用户的安全风险。Basic鉴权基本不对用户名和密码等敏感信息进行预处理,所以只适合于较安全的安全环境,如通过HTTPS安全连接传输,或者局域网。

看起来更安全的Digest在非安全连接传输过程中,也无法抵御中间人通过篡改响应来要求客户端降级为Basic鉴权的攻击。Digest鉴权还有一个缺陷:由于在服务器端需要核对收到的、由客户端经过多次MD5哈希值的合法性,需要使用原始密码做相同的运算,这让服务器无法在存储密码之前对其进行不可逆的加密。Basic 和Digest鉴权的缺陷决定了它们不可能在互联网Web应用中被大量采用。

一直以来,传统Web应用为构成互联网发挥了重要作用。因此传统Web应用中的身份验证技术经过几代的发展,已经解决了不少实际问题,并最终沉淀了一些实践模式。

登录系统

首先,我们要为“登录”做一个简要的定义,令后续的讲述更准确。之前的两篇文章有意无意地混淆了“登录”与“身份验证”的说法,因为在本篇之前,不少“传统Web应用”都将对身份的识别看作整个登录的过程,很少出现像企业应用环境中那样复杂的情景和需求。但从之前的文章中我们看到,现代Web应用对身份验证相关的需求已经向复杂化发展了。

我们有必要重新认识一下登录系统。登录指的是从识别用户身份,到允许用户访问其权限相应的资源的过程。举个例子,在网上买好了票之后去影院观影的过程就是一个典型的登录过程:我们先去取票机,输入验证码取票;接着拿到票去影厅检票进入。取票的过程即身份验证,它能够证明我们拥有这张票;而后面检票的过程,则是授权访问的过程。之所以要分成这两个过程,最直接的原因还是业务形态本身具有复杂性——如果观景过程是免费匿名的,也就免去了这些过程。

图片 3

在登录的过程中,“鉴权”与“授权”是两个最关键的过程。接下来要介绍的一些技术和实践,也包含在这两个方面中。虽然现代Web应用的登录需求比较复杂,但只要处理好了鉴权和授权两个方面,其余各个方面的问题也将迎刃而解。在现代Web应用的登录工程实践中,需要结合传统Web应用的典型实践,以及一些新的思路,才能既解决好登录需求,又能符合Web的轻量级架构思路。

“登录工程”的前两篇文章分别介绍了《传统Web应用中的身份验证技术》,以及《现代Web应用中的典型身份验证需求》,接下来是时候介绍适应于现代Web应用中的身份验证实践了。

简单实用的登录技术

对于互联网Web应用来说,不采用Basic或Digest鉴权的理由主要有两个:

  1. 不能接受在每个请求中发送用户名和密码凭据
  2. 需要在服务器端对密码进行不可逆的加密

因此,互联网Web应用开发已经形成了一个基本的实践模式,能够在服务端对密码强加密之后存储,并且尽量减少鉴权过程中对凭据的传输。其过程如下图所示:

图片 4

这一过程的原理很简单,专门发送一个鉴权请求,只在这个请求头中包含原始用户名和密码凭据,经服务器验证合法之后,由服务器发给一个会话标识(Session ID),客户端将会话标识存储在 Cookie 中,服务器记录会话标识与经过验证的用户的对应关系;后续客户端使用会话标识、而不是原始凭据去与服务器交互,服务器读取到会话标识后从自身的会话存储中读取已在第一个鉴权请求中验证过的用户身份。为了保护用户的原始凭据在传输中的安全,只需要为第一个鉴权请求构建安全连接支持。

服务端的代码包含首次鉴权和后续检查并授权访问的过程:

IUser _user_; if( validateLogin( nameFromReq, pwdFromReq, out _user _)){ Session["CurrentUser"] = _user_; }

1
2
3
4
5
IUser _user_;  
if( validateLogin( nameFromReq, pwdFromReq, out _user _)){  
  Session["CurrentUser"] = _user_;  
}
 

(首次鉴权)

IUser _user_ = Session["CurrentUser"] as IUser; if( _user_ == null ){ Response.Redirect( "/login?return_uri=" + Request.Url.ToString() ); return; }

1
2
3
4
5
6
7
IUser _user_ = Session["CurrentUser"] as IUser;  
if( _user_ == null ){  
     Response.Redirect( "/login?return_uri=" +
     Request.Url.ToString() );  
     return;  
}
 

(后续检查并拒绝未识别的用户)

类似这样的技术简易方便,容易操作,因此大量被运用于很多互联网Web应用中。它在客户端和传输凭据过程中几乎没有做特殊处理,所以在这两个环节尤其要注意对用户凭据的保护。不过,随着我们对系统的要求越来越复杂,这样简易的实现方式也有一些明显的不足。比如,如果不加以封装,很容易出现在服务器应用程序代码中出现大量对用户身份的重复检查、错误的重定向等;不过最明显的问题可能是对服务器会话存储的依赖,服务器程序的会话存储往往在服务器程序重启之后丢失,因此可能会导致用户突然被登出的情况。虽然可以引入单独的会话存储程序来避免这类问题,但引入一个新的中间件就会增加系统的复杂性。

图片 5

解析常见的登录场景

在简单的Web系统中,典型的鉴权也就是要求用户输入并比对用户名和密码的过程,而授权则是确保会话Cookie存在。而在稍微复杂的Web系统中,则需要考虑多种鉴权方式,以及多种授权场景。上一篇文章中所述的“多种登录方式”和“双因子鉴权”就是多种鉴权方式的例子。有经验的人经常调侃说,只要理解了鉴权与授权,就能清晰地理解登录系统了。不光如此,这也是安全登录系统的基础所在。

鉴权的形式丰富多彩,有传统的用户名密码对、客户端证书,有人们越来越熟悉的第三方登录、手机验证,以及新兴的扫码和指纹等方式,它们都能用于对用户的身份进行识别。在成功识别用户之后,在用户访问资源或执行操作之前,我们还需要对用户的操作进行授权。

图片 6

在一些特别简单的情形中——用户一经识别,就可以无限制地访问资源、执行所有操作——系统直接对所有“已登录的人”放行。比如高速公路收费站,只要车辆有合法的号牌即可放行,不需要给驾驶员发一张用于指示“允许行驶的方向或时间”的票据。除了这类特别简单的情形之外,授权更多时候是比较复杂的工作。

在单一的传统Web应用中,授权的过程通常由会话Cookie来完成——只要服务器发现浏览器携带了对应的Cookie,即允许用户访问资源、执行操作。而在浏览器之外,例如在Web API调用、移动应用和富 Web 应用等场景中,要提供安全又不失灵活的授权方式,就需要借助令牌技术。

登录系统

首先,我们要为“登录”做一个简要的定义,令后续的讲述更准确。之前的两篇文章有意无意地混淆了“登录”与“身份验证”的说法,因为在本篇之前,不少“传统Web应用”都将对身份的识别看作整个登录的过程,很少出现像企业应用环境中那样复杂的情景和需求。但从之前的文章中我们看到,现代Web应用对身份验证相关的需求已经向复杂化发展了。

我们有必要重新认识一下登录系统。登录指的是从识别用户身份,到允许用户访问其权限相应的资源的过程。举个例子,在网上买好了票之后去影院观影的过程就是一个典型的登录过程:我们先去取票机,输入验证码取票;接着拿到票去影厅检票进入。取票的过程即身份验证,它能够证明我们拥有这张票;而后面检票的过程,则是授权访问的过程。之所以要分成这两个过程,最直接的原因还是业务形态本身具有复杂性——如果观景过程是免费匿名的,也就免去了这些过程。

在登录的过程中,“鉴权”与“授权”是两个最关键的过程。接下来要介绍的一些技术和实践,也包含在这两个方面中。虽然现代Web应用的登录需求比较复杂,但只要处理好了鉴权和授权两个方面,其余各个方面的问题也将迎刃而解。在现代Web应用的登录工程实践中,需要结合传统Web应用的典型实践,以及一些新的思路,才能既解决好登录需求,又能符合Web的轻量级架构思路。