转载

Java Web 实现 HTTP Basic 认证

Basic 认证是一种较为简单的 HTTP 认证方式,客户端通过明文(Base64 编码格式)传输用户名和密码到服务端进行认证,通常需要配合 HTTPS 来保证信息传输的安全。界面如下。

Java Web 实现 HTTP Basic 认证

下面基于 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。

原文  https://blog.csdn.net/zhangxin09/article/details/107108997
正文到此结束
Loading...