手工实现HttpBasic校验

 
HttpBasic:
是RFC中定义的一种控制HTTP协议访问资源的方式。具体当HTTP请求受限资源时,就需要在请求头中添加以"Authorization"为key的header,value的具体形式是"Basic <credentials>", 其中<credentials>
是以“${username}:${password}"进行BASE64编码后的字符串。如果携带的这个请求头的信息和服务端保存
的用户名密码信息不匹配,就需要服务端必须返回401的状态码和WWW-Authenticate的返回头,其中值要形如
”Basic realm=testHttpBasic"其中”Basic realm"是固定死的

特性:
是最简单的控制访问方式,不需要cookies啊,session identifiers(session id)啊/login pages什么的。
各大浏览器都会以好RFC定义的约定规则实现对应的逻辑的。
 
实现:
SpringSecurity框架中就包含了HttpBasic的功能,但如果不想依赖这么重的玩意儿,可以自己写一个。
我是写了一个Filter,用于过滤请求,已通过Chrome浏览器验证Ok.
  1 package org.zeng.test.test.web.httpbasic;
  2 
  3 import javax.servlet.*;
  4 import javax.servlet.annotation.WebFilter;
  5 import javax.servlet.http.HttpServletRequest;
  6 import javax.servlet.http.HttpServletResponse;
  7 import javax.servlet.http.HttpSession;
  8 import java.io.IOException;
  9 import java.util.Base64;
 10 
 11 @WebFilter(servletNames = "authFilter", urlPatterns = "/basic/*")
 12 public class AuthFilter implements Filter {
 13 
 14     private final String USERNAME = "admin";
 15     private final String PASSWORD = "123456";
 16 
 17     /**
 18      * 核心逻辑比较简单,就是:
 19      * 1.简单的字符串解析
 20      * 2.解码Base64
 21      * 3.验证用户名密码
 22      * 4.将用户标识放入session中
 23      *
 24      * @param servletRequest
 25      * @param servletResponse
 26      * @param filterChain
 27      * @throws IOException
 28      * @throws ServletException
 29      */
 30     @Override
 31     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 32         HttpServletRequest request = (HttpServletRequest)servletRequest;
 33         HttpSession session = request.getSession();
 34 
 35         if (session.getAttribute("user") == null) {
 36             String basicValue = request.getHeader("Authorization");
 37 
 38             //打印出了值形如 "Basic YW423222222lalalla"
 39             System.out.println("Authorization: " + basicValue);
 40 
 41             if (basicValue != null && basicValue.length() > 0) {
 42                 String[] authorizationValue = basicValue.split(" ");
 43                 if (authorizationValue.length == 2) {
 44 
 45                     //获取到解码后的值,形如 "admin:123456"
 46                     String base64Encoded = new String(Base64.getDecoder().decode(authorizationValue[1]));
 47                     if (authorizationValue != null && base64Encoded.length() > 0) {
 48                         String userAndPwdArray[] = base64Encoded.split(":");
 49                         if (userAndPwdArray.length != 2) {
 50                             checkFailed(servletResponse);
 51                         } else {
 52                             String user = userAndPwdArray[0];
 53                             String password = userAndPwdArray[1];
 54                             if (USERNAME.equals(user) && PASSWORD.equals(password)) {
 55 
 56                                 //放入session中,下次登录无需再次提示登录框
 57                                 session.setAttribute("user", USERNAME);
 58 
 59                                 checkSuccess(servletRequest, servletResponse, filterChain);
 60                             } else {
 61                                 checkFailed(servletResponse);
 62                             }
 63                         }
 64                     } else {
 65                         checkFailed(servletResponse);
 66                     }
 67                 } else {
 68                     checkFailed(servletResponse);
 69                 }
 70             } else {
 71                 checkFailed(servletResponse);
 72             }
 73         } else {
 74             checkSuccess(servletRequest, servletResponse, filterChain);
 75         }
 76     }
 77 
 78     @Override
 79     public void init(FilterConfig filterConfig) throws ServletException {
 80 
 81     }
 82 
 83     @Override
 84     public void destroy() {
 85 
 86     }
 87 
 88     /**
 89      * 校验成功
 90      * @param servletRequest
 91      * @param servletResponse
 92      * @param filterChain
 93      * @throws IOException
 94      * @throws ServletException
 95      */
 96     private void checkSuccess(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 97         filterChain.doFilter(servletRequest, servletResponse);
 98     }
 99 
100     /**
101      * 校验失败返回
102      * @param servletResponse
103      */
104     private void checkFailed(ServletResponse servletResponse) {
105         HttpServletResponse response = (HttpServletResponse) servletResponse;
106         response.setStatus(401);
107         response.setHeader("WWW-Authenticate", "Basic realm=anything you can write!");
108     }
109 }

 



posted @ 2019-05-23 13:00  nolan4954  阅读(341)  评论(0编辑  收藏  举报