• 手工实现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 }


  • 相关阅读:
    Oracle 删表前验证表名是否存在并且删除
    Mysql的建表规范与注意事项
    MYSQL总结之sql语句大全
    主机屋云服务器(绑定域名)初探
    (十)Thymeleaf用法——Themeleaf内联
    (九)Thymeleaf用法——Themeleaf注释
    (八)Thymeleaf的 th:* 属性之—— 模板布局& th:with& 属性优先级
    (七)Thymeleaf的 th:* 属性之—— th: ->设值& 遍历迭代& 条件判断
    (六)Thymeleaf的 th:* 属性之—— th: ->text& utext& href
    (五)Thymeleaf标准表达式之——[7->8]条件表达式& 默认表达式
  • 原文地址:https://www.cnblogs.com/nolan4954/p/10911267.html
Copyright © 2020-2023  润新知