Basic 认证是一种较为简单的 HTTP 认证方式,客户端通过明文(Base64 编码格式)传输用户名和密码到服务端进行认证,通常需要配合 HTTPS 来保证信息传输的安全。界面如下。
下面基于 Servlet 标准 Filter 实现一个 HTTP Basic 登录机制,可以用作测试时的临时发布用。部分函数利用了 AJAXJS 库。
package com.ajaxjs.web; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ajaxjs.util.Encode; import com.ajaxjs.util.CommonUtil; import com.ajaxjs.util.logger.LogHelper; /** * 简单的 HTTP Basic 登录 * * @author sp42 frank@ajaxjs.com */ public class HttpBasicAuthFilter implements Filter { private static final LogHelper LOGGER = LogHelper.getLog(HttpBasicAuthFilter.class); /** * 登录名,写死只有一个用户 admin */ private static final String userid = "admin"; /** * 登录密码 */ private static String pwd = "123123"; /** * 报告是否启动的状态,让外界知晓 */ public static boolean isEnadble = false; @Override public void init(FilterConfig config) throws ServletException { LOGGER.info("启动 HTTP BasicAuth 后台管理"); if (config.getInitParameter("adminPassword") != null) pwd = config.getInitParameter("adminPassword");// 读取 web.xml 配置里的密码 isEnadble = true; } @Override @SuppressWarnings("deprecation") public void doFilter(ServletRequest _request, ServletResponse _response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) _request; HttpServletResponse response = (HttpServletResponse) _response; if (!checkAuth(request)) { String msg = "/"Please input your account/""; // 如果认证失败,则要求认证 ,不能输入中文 response.setCharacterEncoding("utf-8"); response.setStatus(401, "Authentication Required");// 发送状态码 401, 不能使用 sendError,坑 response.setHeader("WWW-Authenticate", "Basic realm=" + msg);// 发送要求输入认证信息,则浏览器会弹出输入框 response.setCharacterEncoding("utf-8"); response.getWriter().append("<meta charset=/"utf-8/" />Please login! 请登录系统!"); LOGGER.info("HTTP BasicAuth 登录失败!"); } else { // request.setAttribute("userName", userid); chain.doFilter(request, response); } } @Override public void destroy() { } /** * 检查是否合法登录 * * @param request 请求对象 * @return 是否合法登录 */ private static boolean checkAuth(HttpServletRequest request) { return checkAuth(request.getHeader("Authorization"), userid, pwd); } /** * 是否不合法的数组 * * @param arr * @return 是否不合法的数组 */ private static boolean isBadArray(String[] arr) { return arr == null || arr.length != 2; } /** * 检查是否合法登录 * * @param authorization 认证后每次HTTP请求都会附带上 Authorization 头信息 * @param username 用户名 * @param password 密码 * @return true = 认证成功/ false = 需要认证 */ private static boolean checkAuth(String authorization, String username, String password) { if (CommonUtil.isEmptyString(authorization)) return false; String[] basicArray = authorization.split("//s+"); if (isBadArray(basicArray)) return false; String idpass = Encode.base64Decode(basicArray[1]); if (CommonUtil.isEmptyString(idpass)) return false; String[] idpassArray = idpass.split(":"); if (isBadArray(idpassArray)) return false; return username.equalsIgnoreCase(idpassArray[0]) && password.equalsIgnoreCase(idpassArray[1]); } }
HTTP Basic 安全性还是太弱,所以可以考虑加强版: 摘要认证——HTTP Digest。