1.客户端身份认证 图
看下面这个图:
大家对这个图一定似曾相识吧,我们公司的工作日志登录界面就是形似这样的丑陋款式,显然它不用css、htm堆积出来的。它应该属于http协议的范围。
当浏览器接收到web服务器发送的401(Unauthorized)的响应状态码(状态行)和WWW-Autherticate响应头时,浏览器就会弹出类似上面的对话框。用java servlet实现如下:
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setHeader("WWW-Authenticate", "BASIC realm=\"this a realm\"");
2.认证方式
服务器发送的响应头可以指定两种认证方式:BASIC和DIGEST[dai'dʒest](即基本认真方式和文摘认证方式)。
2.1 BASIC
BASIC验证(上面的代码就会要求一个BASIC验证)要求浏览器把用户名和密码进行BASE64编码后创送给服务器。注意了:BASE64只是一个编码方式,不是加密的,是明码的,知道原理很随意就可以看成原文。
例如,如果你输入的用户名为:admin,密码为:123456。浏览器将会变为:Basic YWRtaW46MTIzNDU2,并方到消息头(请求头)中发送过去。如下所示:
“Basic YWRtaW46MTIzNDU2”中,Basic 表示Basic 认证方式。YWRtaW46MTIzNDU2则为admin:123456的BASE64编码。
看了上面的原理,服务端在后台接受的方式就呼之欲出了:
byte[] decodedBytes = decoder.decodeBuffer(encodedAuth.substring(6));//去除前面的Base64 /* 读者可以试试对于中文的用户名,下行代码该选择什么字符集进行解码? */ String decodedInfo = new String(decodedBytes); System.out.println("BASE64解码:"+decodedInfo); int idx = decodedInfo.indexOf(":"); if (idx < 0) { out.println("信息格式不完整"); return; } String user = decodedInfo.substring(0, idx); String password = decodedInfo.substring(idx + 1);
2.2 DIGESTD
DIGESTD的认证方式细节比较复杂,基本思路是将用户名和密码以及某些其他信息进行混合后,在执行MD5散列算分,并将散列算法结果和附加信息一起以名文文本通过网络发送到服务器。
下载附件,访问http://localhost:8080/Test_servlet/index.jsp,点击其中的,[AuthenticateBaseServlet-Base方式客户端身份认证]即可看到效果。
PS:浏览器最多只允许用户输入3次用户名和密码。
参考:《深入体验Java_Web开发内幕-核心基础》
……