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

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java Web 实现 HTTP Basic 认证

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址