HTTP 基本身份验证而不是 TLS 客户端认证

如何解决HTTP 基本身份验证而不是 TLS 客户端认证

[the] 海报说,如果我们不使用客户端 SSL 认证,服务器并不真正知道它在与谁交谈。

那不是我说的:) 这就是我说的:

除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。

单独是这里的关键词。还:

如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)。

换句话说,TLS 客户端身份验证是对 REST API 客户端进行身份验证的一种方式。因为最初的 SO 问题是关于 SSL 的,所以我提到如果您仅依赖 TLS,TLS 客户端身份验证是唯一的“内置”身份验证形式。因此,如果您使用 TLS,并且不利用 TLS 客户端身份验证,则必须使用其他形式的身份验证来验证您的客户端。

有很多方法可以对 REST 客户端进行身份验证。TLS 客户端身份验证只是其中之一(TLS 的唯一“内置”身份验证,通常非常安全)。然而,TLS 是一种网络级协议,大多数人认为对于许多最终用户来说配置过于复杂。因此,大多数 REST API 产品选择更易于使用的应用程序级协议,例如 HTTP,因为它对大多数人来说更易于使用(例如,只需设置一个 HTTP 标头)。

因此,如果您要使用 HTTP 标头路由,则必须使用标头值来验证 REST 客户端。

在 HTTP 身份验证中,您有一个标头 ,Authorization和它的值(标头名称相当不幸,因为它通常用于身份验证,而不是经常用于访问控制,即授权)。标Authorization头值是服务器用来执行身份验证的值,它(通常)由三个令牌组成

  1. HTTP 身份验证方案名称,后跟
  2. 空格(几乎总是一个空格字符),后跟
  3. 特定于方案的文本值。

一种常见的 HTTP 身份验证方案是该Basic方案,它非常……嗯……基本 :)。特定于方案的文本值只是以下计算值:

String concatenated = username + ":" + raw_password;
String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());

因此,您可能会看到相应的标题如下所示:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

服务器知道如何解析该值。它说“嘿,我知道Basic方案,所以我将采用尾随文本值,base64对其进行解码,然后我将获得用户名和提交的密码。然后我可以查看这些值是否与我存储的值匹配。”

这本质上是Basic身份验证。因为这个方案特别包括提交的原始密码 base64 编码,所以除非您使用 TLS 连接,否则它不被认为是安全的。TLS 保证(大部分)窥探者无法拦截标头(例如通过数据包检查)并查看密码是什么。这就是为什么您应该始终将 TLS 与 HTTP 基本身份验证一起使用。即使在公司内部网环境中。

当然,还有其他更安全的 HTTP 身份验证方案。一个示例是使用基于摘要的身份验证的任何方案。

基于摘要的身份验证方案更好,因为它们的方案文本值不包含提交的密码。相反,计算某些数据(通常是其他标头字段和值)的基于密码的散列,并将结果放入Authorization标头值中。服务器使用它在本地存储的密码计算相同的基于密码的哈希值。如果服务器的计算值与请求的标头值匹配,则服务器可以认为请求已通过身份验证。

这就是为什么这种技术更安全的原因:只传输散列 - 而不是原始密码本身。这意味着即使通过明文(非 TLS)连接也可以使用此技术对请求进行身份验证(但如果请求数据本身当然不敏感,您只会希望这样做)。

一些基于摘要的身份验证方案:

亚马逊和其他喜欢它的 REST 比 OAuth 1.0a 更安全,因为它们总是对整个请求进行身份验证 - 包括请求实体有效负载(即 HTTP 标头之后的所有内容)。OAuth 1.0a 仅针对与使用或有效负载application/x-www-form-urlencoded的 REST API 无关的内容(目前大多数 REST API)执行此操作。application/xml``application/json

有趣的是,OAuth2不是基于摘要的——它使用了我认为不太安全的东西,称为“不记名令牌”(在许多情况下确实很好,但仍然不如银行、军事和政府通信中使用的摘要方案)。

解决方法

授予的答案实际上根本没有解决这个问题。它仅在数据传输的上下文中提及 SSL,实际上并未涵盖身份验证。

您确实在询问安全地验证 REST API 客户端。除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。没有客户端身份验证的 SSL 仅对服务器进行身份验证,这与大多数 REST API 无关。

如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)。

所以考虑到我将在没有客户端认证的情况下使用 HTTPS, 我的问题是海报说如果我们不使用客户端 SSL 认证服务器并不真正知道它与谁交谈。我在这里理解的是,如果我使用身份验证令牌来访问以针对服务器对客户端进行身份验证。然后服务器不知道谁在发送令牌,即使该令牌与我的服务器数据库中的用户 ID 配对。

首先

1-这是一个真正的问题吗?如果我特别使用 Https?(没有 TLS 客户端身份验证)

2-也是最重要的,假设这是一个重要的安全漏洞;如海报所述,Http基本身份验证如何在这里提供帮助?Http 基本身份验证只是在标头中发送编码的用户名密码。因此,当客户端收到一个令牌(在他发送用户名密码后作为回报)然后对于他的其余请求,他将在此标头中使用此令牌而不是密码,并且一切都很好吗?

仍然服务器不知道请求来自哪里,也许服务器在其数据库中有一个有效令牌与匹配的用户,但不知道谁真正发送它。(虽然我仍然很难看到令牌会通过 https 被盗并被其他人使用!)

每当我提出这个主题时,我都会收到回复..“嗯..你发送了一个令牌,但服务器不知道谁发送了这个令牌,不是很安全”所以我理解这一点,因为浏览器保持一种身份验证,服务器知道在哪里请求来自正确的地方然后我可以确定具有该令牌的配对用户(从我的数据库中检查)是“真正正确的”

或者也许这里所说的不正确

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-