检查HTTP 的 Digest 认证. since http1.1
代码如下所示:(此代码还不完善, RFC2617算法未实现).
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %> <%@ page import="sun.misc.BASE64Decoder" %> <%@ page import="java.io.IOException" %> <%@ page import="java.util.UUID" %> <%@ page import="java.util.HashMap" %> <%@ page import="java.util.Map" %> <%! // 检查HTTP 的 Basic认证. since http1.0 public static boolean checkAuth(HttpServletRequest request, String _username, String _password){ boolean authOK = false; // 认证后每次HTTP请求都会附带上 Authorization 头信息 String Authorization = request.getHeader("Authorization"); if(null == Authorization || Authorization.trim().isEmpty()){ // 需要认证 return authOK; } // 示例数据, 没有换行,有逗号,也有空格 // Digest username="admin", realm="DIGEST tiemao", // nonce="227c89449fd644a3b9df12e7cb8b0e33", uri="/digest.jsp", // algorithm=MD5, response="a8bc07c1d6dc38802ce538247e22f773", // qop=auth, nc=00000001, cnonce="f337ac5d88670ef5" String[] digestArray = Authorization.split("\\s+"); if(null == digestArray || digestArray.length < 2){ return authOK; } // Map<String,String> authMap = new HashMap<String,String>(); for(int i = 0; i < digestArray.length; i++){ String paraAndValue = digestArray[i]; // String[] pvArray = paraAndValue.split("="); if(null == pvArray || 2 != pvArray.length){ continue; // 不处理0 } String key = pvArray[0]; String value = pvArray[1]; // if(null==key || null == value){ } // value = value.replace("'",""); value = value.replace(",",""); value = value.replace("\"",""); value = value.trim(); authMap.put(key, value); } // String username = authMap.get("username"); String nonce = authMap.get("nonce"); String response = authMap.get("response"); // 这里应该有个 RFC2617 算法,与客户端一致,即计算用户密码 if(_username.equalsIgnoreCase(username) && checkAuth_RFC2617(_username, _password, response)){ authOK = true;// 认证成功, } // return authOK; } // RFC2617 运算,这算法比较复杂,暂时未实现 // 参考地址: http://www.faqs.org/rfcs/rfc2617.html public static boolean checkAuth_RFC2617(String _username,String _password, String response){ boolean authOK = false; if(null != _username || null !=_password || response.equalsIgnoreCase(response)){ authOK = true;// 认证成功, } return true; } // 不依赖 this 状态的方法,其实都应该设置为 static public static void requireDigestAuth(HttpServletResponse response, String nonce){ // 发送状态码 401, 不能使用 sendError,坑 response.setStatus(401,"Authentication Required"); // String authHeader = "Digest realm=\"DIGEST tiemao\""; authHeader += ",nonce=\""+ nonce +"\""; authHeader += ",algorithm=MD5"; authHeader += ",qop=\""+ "auth" +"\""; // 发送要求输入认证信息,则浏览器会弹出输入框 response.addHeader("WWW-Authenticate", authHeader); return; } %> <% // String Authorization = request.getHeader("Authorization"); // String _username = "admin"; String pwd = "11111111"; boolean authOK = checkAuth(request, _username, pwd); // if (!authOK) { // String nonce = UUID.randomUUID().toString().replace("-",""); // 如果认证失败,则要求认证 requireDigestAuth(response, nonce); return; } %> <html> <head> <title>DIGEST认证示例</title> </head> <body> R U OK? <%=_username %>. Your Password is <%="********"%> </body> </html>代码如上所述,.