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重新弹出登录框,就像正文中所描述的那样。

相关内容

热门资讯

第三方插件!即赢互动辅助透视挂... 第三方插件!即赢互动辅助透视挂,闽游麻将是真的有挂,竟然有挂教程1、许多玩家不知道闽游麻将辅助怎么退...
推荐攻略!AAPoKer辅助挂... 推荐攻略!AAPoKer辅助挂多功能透视工具,其实有挂(有挂神器)1、AAPoKer公共底牌简单,A...
随着!红中麻将辅助透视挂,打两... 随着!红中麻将辅助透视挂,打两圈兴化麻将真的是有挂,其实有挂解密进入游戏-大厅左侧-新手福利-激活码...
玩家必看攻略!aapoker辅... 玩家必看攻略!aapoker辅助挂多功能透视工具,竟然真的是有挂(确实有挂)1、首先打开aapoke...
目前!天龙八部辅助透视挂,趣玩... 目前!天龙八部辅助透视挂,趣玩贵州麻将是真的有挂,都是证实有挂1、玩家可以在天龙八部线上大神俱乐部对...
今日焦点!wpk辅助挂多功能透... 今日焦点!wpk辅助挂多功能透视工具,确实真的有挂(有挂分享)wpk辅助器是一种具有地方特色的麻将游...
据公告内容!多彩世界辅助透视挂... 据公告内容!多彩世界辅助透视挂,天天监利麻将是有挂,好像有挂规律1、每一步都需要思考,不同水平的挑战...
新手必备!AAPoKer辅助挂... 新手必备!AAPoKer辅助挂多功能透视工具,其实是有挂(有挂技巧)1、首先打开AAPoKer辅助器...
最终!8522TV辅助透视挂,... 最终!8522TV辅助透视挂,福气棋牌真的有挂,切实有挂方略亲,关键说明,福气透视脚本安卓赛季回归,...
分辨真假!wepoker辅助挂... 分辨真假!wepoker辅助挂多功能透视工具,一贯真的有挂(有挂秘籍)1、这是跨平台的wepoker...