http的basic 认证方式
创始人
2025-01-10 03:04:16
0

写在前面

在这里插入图片描述

本文看下http的basic auth认证方式。

1:什么是basic auth认证

basic auth是一种http协议规范中的一种认证方式,即一种证明你就是你的方式。更进一步的它是一种规范,这种规范是这样子,如果是服务端使用了basic auth认证方式来处理用户请求的话,会从header中获取Authorization的头信息,如果是没有该头信息或者是头信息不正确,则会返回401状态码,并添加WWW-Authenticate响应头。如下代码所示:

String base6AuthStr = req.getHeader("Authorization"); System.out.println("base6AuthStr=" + base6AuthStr); // base6AuthStr=Basic YWFhOmFhYQ== if (base6AuthStr == null) {     res.setStatus(401);     res.addHeader("WWW-Authenticate", "basic realm=\"no auth\"");     return false; } String authStr = new String(decoder.decode(base6AuthStr.substring(6).getBytes())); System.out.println("authStr=" + authStr); // authStr=xxx:xxx  String[] arr = authStr.split(":"); if ("test".equals(arr[0]) && "123456".equals(arr[1])) {     res.setStatus(401);     res.addHeader("WWW-Authenticate", "basic realm=\"no auth\"");     return false; } 

如果是浏览器收到了服务端的401响应,并且判断有www-authenticate头信息的话则会弹出自带的用户名密码录入框让用户录入信息,用户录入后浏览器会对录入的信息按照格式base64(用户名:密码)处理得到一个base64的值,然后按照格式Authorization: basic base64值写到头Authorization,再次发起请求。

2:程序测试

使用springboot方式测试。首先添加依赖和配置文件:

  • application.properties
server.port=8089 server.servlet.context-path=/BootDemo 
  • pom
     org.springframework.boot     spring-boot-starter-parent     2.2.1.RELEASE                      org.springframework.boot         spring-boot-starter-web       

接着我们来定义注解,后面将会作为接口是否使用basic auth的标记来使用:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface RequireAuth {      } 

定义拦截器,解析目标接口方法上是否是否用了注解RequireAuth,以及使用时是否携带了正确的WWW-Authenticate头信息,源码如下:

public class RequireAuthInterceptor extends HandlerInterceptorAdapter {     final Base64.Decoder decoder = Base64.getDecoder();     // final Base64.Encoder encoder = Base64.getEncoder();      @Override     public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {         // 请求目标为 method of controller,需要进行验证         if (handler instanceof HandlerMethod) {             HandlerMethod handlerMethod = (HandlerMethod) handler;             Object object = handlerMethod.getMethodAnnotation(RequireAuth.class);              /* 方法没有 @RequireAuth 注解, 放行 */             if (object == null) {                 return true; // 放行             }              /* 方法有 @RequireAuth 注解,需要拦截校验 */             // 没有 Authorization 请求头,或者 Authorization 认证信息不通过,拦截             if (!isAuth(req, res)) {                 return false; // 拦截             }              // 验证通过,放行             return true;         }          // 请求目标不是 mehod of controller, 放行         return true;     }      private boolean isAuth(HttpServletRequest req, HttpServletResponse res) {         String base6AuthStr = req.getHeader("Authorization");         System.out.println("base6AuthStr=" + base6AuthStr); // base6AuthStr=Basic YWFhOmFhYQ==         if (base6AuthStr == null) {             res.setStatus(401);             res.addHeader("WWW-Authenticate", "basic realm=\"no auth\"");             return false;         }          String authStr = new String(decoder.decode(base6AuthStr.substring(6).getBytes()));         System.out.println("authStr=" + authStr); // authStr=xxx:xxx          String[] arr = authStr.split(":");         if (arr != null && arr.length == 2) {             String username = arr[0];             String password = arr[1];             // 校验用户名和密码             if ("test".equals(username) && "123456".equals(password)) {                 return true;             }         }          res.setStatus(401);         res.addHeader("WWW-Authenticate", "basic realm=\"no auth\""); //        res.addHeader("WWW-Authenticate", "basic realm=\"no auth\"");         return false;     }  } 

注册拦截器:

@Configuration public class WebConfig implements WebMvcConfigurer {      @Override     public void addInterceptors(InterceptorRegistry registry) {         RequireAuthInterceptor requireAuthInterceptor = new RequireAuthInterceptor();         registry.addInterceptor(requireAuthInterceptor);     }      } 

接着定义接口:

@Controller public class IndexController {      private static final Base64.Decoder decoder = Base64.getDecoder();     // private static final Base64.Encoder encoder = Base64.getEncoder();      @RequireAuth     @RequestMapping("/login")     @ResponseBody     public String login(HttpServletRequest req, HttpServletResponse res) {         return "{code: 0, data: {username:\"test\"}}";     }      @RequireAuth     @RequestMapping("/index")     @ResponseBody     public String index(HttpServletRequest req, HttpServletResponse res) {         return "{code: 0, data: {xxx:\"xxx\"}}";     }      @RequestMapping("/noBasicAuth")     @ResponseBody     public String noBasicAuth(HttpServletRequest req, HttpServletResponse res) {         return "noBasicAuth res";     } } 

以上代码我们定义了需要使用basic auth的接口login和index(标记了注解@RequireAuth),以及不需要basic auth的noBasicAuth接口。

启动服务后,首先访问需要basic auth的login接口:
在这里插入图片描述
可以看到浏览器弹出了自带的用户名密码输入框。同时来看下noBasicAuth接口可以是否需要录入用户名密码:
在这里插入图片描述
可以看到是可以的,说明noBasicAuth接口确实是不需要basic auth认证。接着我们回到主线再次访问index接口,输入错误的账号:
在这里插入图片描述
会再次弹出用户名密码录入框(重复质询),输入正确的用户名密码就可以访问接口了:
在这里插入图片描述
这是因为浏览器已经自动添加了Authorization头信息了,如下:
在这里插入图片描述
其值其实就是test:123456base64的结果,如下:
在这里插入图片描述
之后,浏览器就会记录basic auth的认证信息,下次访问会自动带上basic的头,比如访问index:
在这里插入图片描述

写在后面

参考文章列表

秒懂HTTP基本认证(Basic Authentication) 。

HTTP的几种认证方式之BASIC 认证(基本认证) 。

多知道一点

如何清除浏览器记录的basic auth认证信息

清除浏览器缓存即可。

重放攻击

认证的base64结果被盗窃后,不断的使用base64的结果来请求服务器接口。

重复质询

用户名和密码输入错误后,返回401重新弹出登录框,就像正文中所描述的那样。

相关内容

热门资讯

macOS Sequoia 发... 黑果魏叔消息经过数月的等待,苹果粉丝们一直在等待的那一刻终于到来。北京时间6月11日凌...
Spring AI 使用教程 创建项目勾选Spring Web以及OpenAI获取openai-api-key 访问网址ÿ...
C++ 实现对战AI五子棋  个人主页:日刷百题系列专栏:〖C/C++小游戏〗〖Li...
今日头条《WPK德州透视辅助》... 今日头条《WPK德州透视辅助》太坑了原来确实是有挂(果真有挂);超受欢迎的WPK小游戏,经典的ai透...
重大通报《Wepoke存在》软... 重大通报《Wepoke存在》软件透明挂!(透明挂)软件脚本(2022已更新)(哔哩哔哩);AI辅助机...
pytorch初学笔记(六):... 目录一、DataLoader介绍1. DataLoader作用2. 常用参数介绍 二、DataLoa...
四分钟了解(咪咪扑克)软件透明... 四分钟了解(咪咪扑克)软件透明挂(咪咪扑克)透明挂辅助神器(2021已更新)(哔哩哔哩)是一款可以让...
Mac上Maven的安装和环境... 目录一、Maven的安装1.进入官网(Maven官网)下载安装包并解压2...
CrossOver 23.6 ... 如果您想要在mac上运行windows 软件,那么CrossOver 23.6 Mac...
教程辅助(wepOkE)软件透... 您好,这款游戏可以开挂的,确实是有挂的,需要了解加微【439369440】很多玩家在这款游戏中打牌都...