如今web服务随处可见,成千上万的web程序被部署到公网上供用户访问,有些系统只针对指定用户开放,属于安全级别较高的web应用,他们需要有一种认证机制以保护系统资源的安全,本文将探讨五种常用的认证机制及优缺点。
Basic模式
HTTP协议规范中有两种认证方式,一种是Basic认证,另外一种是Digest认证,这两种方式都属于无状态认证方式,所谓无状态即服务端都不会在会话中记录相关信息,客户端每次访问都需要将用户名和密码放置报文一同发送给服务端,但这并不表示你在浏览器中每次访问都要自己输入用户名和密码,可能是你第一次输入账号后浏览器就保留在内存中供后面的交互使用。先看下HTTP协议的Basic认证模式。
既然是HTTP协议规范,那其实就是约束浏览器厂商与web容器厂商实现各自软件时的行为约束,例如典型的一个认证交互过程是:浏览器向web容器发送http请求报文,web容器接收到http请求报文后解析需要访问的资源,如果该资源刚好是受保护资源,web容器则向浏览器发送认证http响应报文,浏览器接收到报文后弹出窗口让用户输入账号及密码,接着再次发送包含了账号信息的http请求报文,web容器对账号信息进行鉴权,通过验证则返回对应资源,否则重新认证。
Basic Access Authentication scheme是在HTTP1.0提出的认证方法,它是一种基于challenge/response的认证模式,针对特定的realm需要提供用户名和密码认证后才可访问,其中密码使用明文传输。Basic模式认证过程如下:
①浏览器发送http报文请求一个受保护的资源。
②服务端的web容器将http响应报文的响应码设为401,响应头部加入WWW-Authenticate: Basic realm=”myTomcat”。
③浏览器弹出对话框让用户输入用户名和密码,并用Base64进行编码,实际是用户名+冒号+密码进行Base64编码,即Base64(username:password),这次浏览器就会在HTTP报文头部加入Authorization: Basic bXl0b21jYXQ=。
④服务端web容器获取HTTP报文头部相关认证信息,匹配此用户名与密码是否正确,是否有相应资源的权限,如果认证成功则返回相关资源,否则再执行②,重新进行认证。
⑤以后每次访问都要带上认证头部。
服务端返回的认证报文中包含了realm=”myTomcat”,realm的值用于定义保护的区域,在服务端可以通过realm将不同的资源分成不同的域,域的名称即为realm的值,每个域可能会有自己的权限鉴别方案。
Basic认证模式有两个明显的缺点:①无状态导致每次通信都要带上认证信息,即使是已经认证过的资源;②传输安全性不足,认证信息用Base64编码,基本就是明文传输,很容易对报文截取并盗用认证信息。
Digest模式
HTTP协议规范的另一种认证模式是Digest模式,在HTTP1.1时被提出来,它主要是为了解决Basic模式安全问题,用于替代原来的Basic认证模式,Digest认证也是采用challenge/response认证模式,基本的认证流程比较类似,整个过程如下:
①浏览器发送http报文请求一个受保护的资源。
②服务端的web容器将http响应报文的响应码设为401,响应头部比Basic模式复杂,WWW-Authenticate: Digest realm=”myTomcat”,qop="auth",nonce="xxxxxxxxxxx",opaque="xxxxxxxx" 。其中qop的auth表示鉴别方式;nonce是随机字符串;opaque服务端指定的值,客户端需要原值返回。
③浏览器弹出对话框让用户输入用户名和密码,浏览器对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合后进行MD5运算,把计算得到的摘要信息发送给服务端。请求头部类似如下,Authorization: Digest username="xxxxx",realm="myTomcat",qop="auth",nonce="xxxxx",uri="xxxx",cnonce="xxxxxx",nc=00000001,response="xxxxxxxxx",opaque="xxxxxxxxx" 。其中username是用户名;cnonce是客户端生成的随机字符串;nc是运行认证的次数;response就是最终计算得到的摘要。
④服务端web容器获取HTTP报文头部相关认证信息,从中获取到username,根据username获取对应的密码,同样对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合进行MD5运算,计算结果和response进行比较,如果匹配则认证成功并返回相关资源,否则再执行②,重新进行认证。
⑤以后每次访问都要带上认证头部。
其实通过哈希算法对通信双方身份的认证十分常见,它的好处就是不必把具备密码的信息对外传输,只需将这些密码信息加入一个对方给定的随机值计算哈希值,最后将哈希值传给对方,对方就可以认证你的身份。Digest思想同样采如此,用了一种nonce随机数字符串,双方约好对哪些信息进行哈希运算即可完成双方身份的验证。Digest模式避免了密码在网络上明文传输,提高了安全性,但它仍然存在缺点,例如认证报文被攻击者拦截到攻击者可以获取到资源。
Form模式
上面介绍的两种模式都属于HTTP协议规范范畴,由于它的规范使得很多东西无法自定义,例如登录窗口、错误展示页面。所以需要另外一种模式提供更加灵活的认证,也就是基于Form的认证模式,各种语言体系的web容器都可以实现各自的Form模式,这里只介绍java体系的Form认证模式:
Form模式的认证流程如下:
①浏览器发送http报文请求一个受保护的资源。
②服务端的web容器判断此uri为受保护资源,于是将请求重定向到自定义的登陆页面上,例如login.html页面,可以自定义登陆页面的样式,但要遵守的约定是表单的action必须以j_security_check结尾,即<form action='xxxxxx/j_security_check' method='POST'>。用户名和密码输入框元素的name必须为'j_username' 和'j_password'。
③浏览器展示自定义的登陆页面让用户输入用户名和密码,然后提交表单。
④服务端web容器获取表单的用户名和密码,匹配此用户名与密码是否正确,是否有相应资源的权限,如果认证成功则返回相关资源,否则再执行②,重新进行认证。
⑤后面在同个会话期间的访问都不用再进行认证,因为认证的结果已经保存在服务端的session里面。
Form模式跳出了HTTP规范提供了自定义的更加灵活的认证模式,由于每种语言都可以自己定义实现自己的Form模式,所以它没有一个通用的标准,而且它也存在密码明文传输安全问题。
Spnego模式
Spnego模式是一种由微软提出的使用GSS-API接口的认证模式,它扩展了Kerberos协议,在了解Spnego协议之前必须先了解Kerberos协议,Kerberos协议主要解决身份认证及通信密钥协商问题,它大致的工作流程如下:
①客户端根据自己用户名向密钥分发中心KDC的身份认证服务AS请求TGS票证。
②AS生成一个TGS票证、查询对应用户的密码,然后通过用户密码将TGS票证加密,响应给客户端。
③客户端通过用户密码解密TGS票证,如果密码正确就能获取到TGS票证,然后用TGS票证去票证授予服务TGS请求服务票证。
④TGS将服务票证响应给客户端。
⑤客户端使用服务票证去访问某服务,服务验证服务票据是否合法。
⑥验证通过,开始通信。
在了解了Kerberos协议后,我们再来看看Spnego的认证过程是怎样的。由于spnego扩展自kerberos协议,认证的核心流程一样,只是在浏览器与web服务器之间的http通信过程中嵌入认证流程。如下图:
①客户端浏览器向web服务器发送http请求。
②服务器返回401状态码,响应头部加上 WWW-Authenticate:Negotiate。
③用户通过浏览器输入用户名向AS请求TGS票证。
④AS生成TGS票证,然后查询用户密码并用此密码加密TGS票证,返回浏览器。
⑤浏览器使用用户密码解密出TGS票证,并向TGS服务发起请求。
⑥TGS服务生成服务票证响应给浏览器。
⑦浏览器将服务票证封装到SPNEGO token中,并发送给web服务器。
⑧服务器解密出用户名及服务票证,将票证发往TGS服务验证。
⑨通过验证,开始通信。
可以看到Spnego模式提供了更加强大的安全认证,它将认证模块独立出来,虽然结构复杂了,但这样可以为所有应用提供认证功能,例如它可以很容易实现多个系统之间的单点登录。
SSL模式
SSL模式是基于SSL通信的一种认证模式,它的大体流程是这样的:客户端与服务器之间通过SSL协议建立起SSL通道,这个过程比较复杂,涉及到客户端服务端证书互相交互验证,协商通信密钥等过程,细节可以前往SSL章节阅读。完成整个SSL通道建立后才是认证的核心步骤,如下图,
①首先获取客户端证书文件,这个由于在SSL协议期间已经发送到服务端,所以可以直接从内存中获取,然后解析证书文件得到证书标识。
②通过这个证书标识去存放用户信息的地方查找出对应客户端证书用户的相关信息。
③检查此用户是否有相关资源的权限,如果验证通过则返回请求相关资源。
SSL模式也提供了高安全认证,它只对颁发的客户端证书个体信任,可用于服务端与服务端之间的通信,也可以用在浏览器与web服务器之间通信,这时必须使用https协议,因为它必须走SSL协议通道才能完成认证流程。
本文介绍了五种常见的安全认证机制,他们各自有各自的优缺点,在实际使用中根据具体的场景选择不同的认证机制。
==========广告时间==========
鄙人的新书《Tomcat内核设计剖析》已经在京东预售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。
=========================