http的basic 认证方式
写在前面
本文看下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:xxxString[] 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
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
接着我们来定义注解,后面将会作为接口是否使用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();@Overridepublic 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:xxxString[] 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 {@Overridepublic 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")@ResponseBodypublic String login(HttpServletRequest req, HttpServletResponse res) {return "{code: 0, data: {username:\"test\"}}";}@RequireAuth@RequestMapping("/index")@ResponseBodypublic String index(HttpServletRequest req, HttpServletResponse res) {return "{code: 0, data: {xxx:\"xxx\"}}";}@RequestMapping("/noBasicAuth")@ResponseBodypublic 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:123456
base64的结果,如下:
之后,浏览器就会记录basic auth的认证信息,下次访问会自动带上basic的头,比如访问index:
写在后面
参考文章列表
秒懂HTTP基本认证(Basic Authentication) 。
HTTP的几种认证方式之BASIC 认证(基本认证) 。
多知道一点
如何清除浏览器记录的basic auth认证信息
清除浏览器缓存即可。
重放攻击
认证的base64结果被盗窃后,不断的使用base64的结果来请求服务器接口。
重复质询
用户名和密码输入错误后,返回401重新弹出登录框,就像正文中所描述的那样。
相关文章:

http的basic 认证方式
写在前面 本文看下http的basic auth认证方式。 1:什么是basic auth认证 basic auth是一种http协议规范中的一种认证方式,即一种证明你就是你的方式。更进一步的它是一种规范,这种规范是这样子,如果是服务端使用了basic auth认证…...
【信息系统项目管理师练习题】信息系统治理
IT治理的核心是关注以下哪项内容? a) 人员培训和发展计划 b) IT定位和信息化建设与数字化转型的责权利划分 c) 业务流程的绩效管理 d) IT基础设施的优化利用 答案: b) IT定位和信息化建设与数字化转型的责权利划分 IT治理体系框架的组成部分包括以下哪些? a) IT战略目标、IT治…...

RabbitMQ之顺序消费
什么是顺序消费 例如:业务上产生者发送三条消息, 分别是对同一条数据的增加、修改、删除操作, 如果没有保证顺序消费,执行顺序可能变成删除、修改、增加,这就乱了。 如何保证顺序性 一般我们讨论如何保证消息的顺序性&…...

轻松上手的LangChain学习说明书
一、Langchain是什么? 如今各类AI模型层出不穷,百花齐放,大佬们开发的速度永远遥遥领先于学习者的学习速度。。为了解放生产力,不让应用层开发人员受限于各语言模型的生产部署中…LangChain横空出世界。 Langchain可以说是现阶段…...

【论文笔记】Training language models to follow instructions with human feedback A部分
Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 : 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式;模型架构是基于 Transformer 的叠加解码器(掩码自注意…...
嵌入式交叉编译:x265
下载 multicoreware / x265_git / Downloads — Bitbucket 解压编译 BUILD_DIR${HOME}/build_libs CROSS_NAMEaarch64-mix210-linuxcd build/aarch64-linuxmake cleancmake \-G "Unix Makefiles" \-DCMAKE_C_COMPILER${CROSS_NAME}-gcc \-DCMAKE_CXX_COMPILER${CR…...

一、Redis五种常用数据类型
Redis优势: 1、性能高—基于内存实现数据的存储 2、丰富的数据类型 5种常用,3种高级 3、原子—redis的所有单个操作都是原子性,即要么成功,要么失败。其多个操作也支持采用事务的方式实现原子性。 Redis特点: 1、支持…...

C语言动态内存管理malloc、calloc、realloc、free函数、内存泄漏、动态内存开辟的位置等的介绍
文章目录 前言一、为什么存在动态内存管理二、动态内存函数的介绍1. malloc函数2. 内存泄漏3. 动态内存开辟位置4. free函数5. calloc 函数6. realloc 函数7. realloc 传空指针 总结 前言 C语言动态内存管理malloc、calloc、realloc、free函数、内存泄漏、动态内存开辟的位置等…...

最近惊爆谷歌裁员
Python团队还没解散完,谷歌又对Flutter、Dart动手了。 什么原因呢,猜测啊。 谷歌裁员Python的具体原因可能是因为公司在进行技术栈的调整和优化。Python作为一种脚本语言,在某些情况下可能无法提供足够的性能或者扩展性,尤其是在…...

音频可视化:原生音频API为前端带来的全新可能!
音频API是一组提供给网页开发者的接口,允许他们直接在浏览器中处理音频内容。这些API使得在不依赖任何外部插件的情况下操作和控制音频成为可能。 Web Audio API 可以进行音频的播放、处理、合成以及分析等操作。借助于这些工具,开发者可以实现自定义的音…...
【中等】保研/考研408机试-动态规划1(01背包、完全背包、多重背包)
背包问题基本上都是模板题,重点:弄熟多重背包模板 dp[j]max(dp[j-v[i]]w[i],dp[j]) //核心思路代码(一维数组版) dp[i][j]max(dp[i-1][j], dp[i-1][j-v[i]]w[i])//二维数字版 一、 0-1背包 一般输入两个变量:体积&…...
[DEMO]给两个字符串取交集的词语
要求:2个英文字符串中,取相同的大于等于4个字母的词组 比如: 字符串1:" xingMeiLingabcdef WorldHello", 字符串2:"mnjqlup WorldLingLing xingMeiLingHello" 获取交接: [xingMeiLing…...
leetcode53-Maximum Subarray
题目 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,4] 输出…...
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现 目录...

【go项目01_学习记录06】
学习记录 1 使用中间件1.1 测试一下1.2 push代码 2 URI 中的斜杆2.1 StrictSlash2.2 兼容 POST 请求 1 使用中间件 代码中存在重复率很高的代码 w.Header().Set("Content-Type", "text/html; charsetutf-8")统一对响应做处理的,我们可以使用中…...

Vue中Element的下载
打开vscode让项目在终端中打开 输入npm install element-ui2.15.3 然后进行下载 在node_modules中出现element-ui表示下载完成 然后在输入Vue.use(ElementUI); import Vue from vue import App from ./App.vue import router from ./router import ElementUI from element-ui…...
机器人项目相关
机器人项目相关 1. Nvidia 1.1 Jetson 1.1.1 初步安装Riva教程 llamaspeakJetson AGX Orin踩坑记录(1)安装Riva 参考知乎链接:https://zhuanlan.zhihu.com/p/670007305 1.1.2 NVIDIA Jetson AI Lab 借助 NVIDIA Jetson™ 将生成式 AI…...
Mac升级go版本某种错误情况处理
当看到 "go1.21 is keg-only, which means it was not symlinked into /opt/homebrew" 这样的信息时,意味着Homebrew没有自动为你创建指向新版本Go的符号链接(symlink),因为这是一个旧版本Go的替代版本。 Homebrew中的…...

美团KV存储squirrel和Celler学习
文章目录 美团在KV存储squirrel优化和改进在水平方向1、对Gossip协议进行优化 在垂直扩展方面1、forkless RDB数据复制优化2、使用多线程,充分利用机器的多核能力 在高可用方面 美团持久化kv存储celler优化和改进水平扩展优化1、使用bulkload进行数据导入2、线程模型…...

Python学习笔记------处理数据和生成折线图
给定数据: jsonp_1629344292311_69436({"status":0,"msg":"success","data":[{"name":"美国","trend":{"updateDate":["2.22","2.23","2.24",&qu…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...