Java for Web学习笔记(一四十)Spring security准备(1)认证

匿名认证

匿名认证有多种方式:

  • 不是通过你的ID进行认证,例如通过HTTP的session ID,实际是认证你曾经访问。
  • 作为其他认证缺失的情况:,例如可以匿名登录论坛进行浏览。当让如果要做更多的事情,通常需要进行身份认证。

密码认证

密码认证古来有之。有密码和反密码,例如空降兵密码为flash,地面部队为thunder,避免抢先问密码,导致密码泄漏。这有点类似https在使用前,用户先检查https的证书是否有效,避免将自己的信息给到一个伪造的网站。

密码采用不可逆的hash存储,但是现在黑客的工具越来越厉害,例如有着30个GPU的机器(GPU作为图形渲染,比CPU更适合用于计算hash,同时一台机器更容易带多个GPU,难怪矿机导致显卡涨价)。目前常用的BCrypt,被设计为缓慢和消耗内存资源,使得GPU字典破解困难。

账号和密码

这是我们最常见的方式。

Basic and Digest

这是HTTP协议支持的一种认证方式。客户端发送请求,服务器返回一个401 Authorized,在WWW-Authenticate中给出认证的算法。常见的有Basic Realm和digest两种。客户端根据要求在下个请求中给出认证信息。

Basic接入认证

【1】client发出HTTP请求(略)

【2】如果client请求没有认证信息,server给出要求认证的响应401

HTTP/1.1 401 Not Authorized
Date: Sun, 25 Aug 2013 21:46:47 GMT
WWW-Authenticate: Basic realm="Multinational Widget Corp. Customer Support"

如果使用浏览器,浏览器会弹出下面的框。用户可以输入账号和密码。

Java for Web学习笔记(一四十)Spring security准备(1)认证_第1张图片

【3】账号和密码组合成为 username:password,然后进行BASE64加密,写入Authorization头,重新发送请求。

【4】如果失败,再次发送401。如果认证通过,返回相关的页面,浏览器会缓存相关的信息,在之后的请求中会带上认证信息。当然这个缓存是有时效的。

由于BASE64安全级别很低,它只是编码格式,不是加密,所以可逆的。而且对于同一个账号和密码,每次加密内容是一样的,被人截取后,可以仿造。所以这种方式一般用于https的API请求。当这仍有问题,服务器端采用明文来存放密码,而不是hash。

Digest

【1】客户端请求,略

【2】服务器回应一个401 Not Authorized,在WWW-Authenticate中给出认证的算法,以及动态参数

HTTP/1.1 401 Not Authorized
Date: Sun, 25 Aug 2013 21:46:47 GMT
WWW-Authenticate: Digest realm="Multinational Widget Corp. Customer Support",
                  algorithm="MD5-sess", qop="auth,auth-int",
                  nonce="d41d8cd98f00b204e9800998ecf8427e",
                  opaque="66ffcd4fb3f0ceb07195b60fa7991592"
 
➤ 以前在sip中用过,记得需要多次MD5计算的。
   如果算法给出的是MD5,第一个hash值为MD5(username:realm:password);
   如果是MD5-sess,第一个hash值为 MD5(MD5(username:realm:password):nonce:cnonce)。
➤ 如果qop(quality of protection)给出多个,缺省为MD5,client可以选择
   如果采用auth,第二个hash为MD5(requestMethod:requestUri);
   如果采用auth-int,第二个hash为MD5(requestMethod:requestUri:MD5(requestBody)),前提是必须有body。例如POST,PUT。
➤ opaque是一个16进制的string或者BASE64,cilent必须原样给出。
➤ nonce是服务器产生的随机数,一般是随机数和时间戳的hash值,这样确保不重复。 

【3】客户端据此再生产一个带有HTTP请求,在Authorization中给出认证信息。reponse的根据算法对账号,密码,动态参数进行计算。nonce有两个,一个是服务器给的nonce,一个是客户端自己提供的cnonce,均为随机生成。

GET /support HTTP/1.1
Host: www.example.org
Authorization: Digest realm="Multinational Widget Corp. Customer Support",
               username="John", qop="auth", uri="/support",
               nc="000001"
               nonce="d41d8cd98f00b204e9800998ecf8427e",
               opaque="66ffcd4fb3f0ceb07195b60fa7991592",
               cnonce="9dba9637e8635a4d912075cd6ea55530",
               response="4b4a3883cc8d220fc105e81a9592331c" 
➤ nc是cnounce的一个计数器,也成为串行请求序号。对于同一个client,nc也是不重复的。
➤ 如果server未指定qop,则response为MD5(firstHash:nonce:secondHash);如果指定,则是MD5(firstHash:nonce:nc:cnonce:qop:secondHash)。由于后者安全更高,一般server都会指定qop。
➤ 在服务器中密码可以通过MD5(username:realm:password)来进行存储。一来省一步hash计算,二来也是密码的hash。

【4】服务器检查认证信息,如果成功,返回200OK,如果认证失败,返回404,如果授权失败,返回403。

HTTP/1.1 200 OK
Date: Sun, 25 Aug 2013 21:47:10 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 11485
...

鉴于目前对MD5的攻击,digest也不真的那么安全,所以如可能,还是要用HTTPS。目前,流行的浏览器不支持auth-int。

表单认证

当用户试图访问受保护的资源时,服务器通过重定向302 Found, 303 See Other, 或者307 Temporary Redirect到一个登录页面,那里有一个HTML的form,要求填入账号和密码。注意,这些信息是明文传输的,所以需要采用HTTPS。

微软Windows认证

只用于Windows的机器,不是所有浏览器都支持,当然IE支持。浏览器不需登录表单,让用户输入账号和密码,而是通过IWA(Integrated Windows Authentication)SPNEGO, Kerberos, 或者 NTLMSSP 自动获取用户的Windows的凭证,并以某种安全的方式送到Windows domain controller进行检查。

如果在Windows机器上使用其他的浏览器,可能有点麻烦,Firefox支持NTLMSSP,但需要在 about:config 中的network.automatic-ntlm-auth.trusted-uris中配置IWA请求的信息站点。而Chrome支持IWA,但比IE要严格,站点必须先符合Local Intranet security zone。如果不是Windows机器,就不用想了。这种方式一般只适合企业内部。

客户端证书

这个和流行的HTTPS方式类似的,不过反过来。在注册的过程中(通常是用户创建账号和密码时),服务器通知浏览器去生成公私钥对,浏览器生成公私钥对,并将公钥传递给服务器,之后使用私钥进行加解密。服务器中存放的是各个用户(浏览器)的证书(公钥)。

如果用户变更机器,需要copy公私钥对。这对用户的技能有所要求,所以一般只用在高敏感的应用程序。

Smart Cards和生物识别

智能卡是一个特殊的IC,例如门禁卡,网银的U盾。智能卡和生物识别可以用在web app,但比较少,因为需要辅助的硬件设备。

基于声明的认证(Claims-Based)

就是基于第三方的认证,例如使用微信账号登陆,使用微博账号登陆。OAuth和SAML实现或支持Claims-Bases认证。

Java for Web学习笔记(一四十)Spring security准备(1)认证_第2张图片

多因素认证

采用两种或者以上的认证方式,加大黑客的入侵难度。例如客户端证书加上账号密码认证。最常见的短信验证码。书中还提到一种根据同一个seed,用户手中的dongle或者手机App会随着时间不同而产生一个6到9位的数字,边个更时间在30~60秒,这个dongle我以前见过,长得和传呼机有点像,就一个液晶显示屏,定期更改数字。这个数字就是验证码。不过这种东西没有在国内流行。

相关链接:我的Professional Java for Web Applications相关文章

你可能感兴趣的:(JAVA,读书笔记,愷风(Wei)之Java,for,Web学习笔记)