如何确认用户/通过 http 授权?
Posted
技术标签:
【中文标题】如何确认用户/通过 http 授权?【英文标题】:How to confirm user/pass for http authorization? 【发布时间】:2021-12-23 19:21:13 【问题描述】:服务器侦听数据包,我们将 http GET 请求数据包发送到此侦听器。如果我们使用带有用户名/密码的 auth 标头服务器不接受连接并且失败。有没有办法解析此 auth 标头信息(用户名/密码) 在听众身上?因为我们要根据用户/通行证比较来进行认证
注意:在 GET 数据包 http 侦听器中没有 auth 标头接受连接,它工作正常
HTTP 数据包监听器
import socket
serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 8080
serverSocket.bind(("127.0.0.1", serverPort))
serverSocket.listen(1)
while True:
print('Ready to serve...')
try :
connectionSocket, addr = serverSocket.accept()
except :
print (f"Socket error occured for 127.0.0.1 serverPort ")
HTTP 客户端
import requests
from requests.auth import HTTPBasicAuth
r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'pass'))
感谢您的帮助!
【问题讨论】:
见这里:***.com/questions/2929532/… @floatingpurr 但在这个例子中它只是发送数据包......不确认用户名/密码。就我而言,我的侦听器程序已经收到来自客户端的数据包我的问题是如何解析身份验证标头并确认数据包侦听器上的身份验证 你必须实现一个合适的 HTTP 服务器,即理解 HTTP 协议的服务器,而不是你所知道的 TCP 监听器。然后,您需要从 Authorization 标头中提取凭据并检查您拥有的任何身份验证后端。现在的问题离这个太远了,因此太宽泛了。这就像有一个方向盘,然后问如何围绕它造一辆汽车。 我要发布一个示例/PoC。 @floatingpurr 感谢您的回复,是的,我知道 :) 我需要构建正确的 http 服务器 flasjk/django 来处理 http 数据包和标头。我只是想知道是否有办法解析这些信息通过使用请求模块或套接字模块。这就是我问这个问题的原因。现在我很清楚我将使用另一个应用程序数据来共享用户名/传递信息,以便可以用正则表达式解析它们再次感谢您的解释 【参考方案1】:这是您需要的工作示例。
tl;dr:正如 cmets 中所指出的,您在传输级别使用套接字。 HTTP 基本身份验证位于 TCP/IP(或 OSI)堆栈的更高级别。如果您不想采用 HTTP 协议(是吗?),您需要手动处理请求和标头,模仿 HTTP 协议。事实上,pythonrequests
管理成熟的 HTTP 请求。
我稍微修改了您的代码以解析 http 标头并管理类似 HTTP 的身份验证。好了(代码中的cmets和解释):
import socket, base64
from http.server import BaseHTTPRequestHandler
from io import BytesIO
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverPort = 8080
serverSocket.bind(("127.0.0.1", serverPort))
serverSocket.listen(1)
# Auth section
user = 'user'
password = 'pass'
# The token you want the client to provide (string)
server_token = base64.b64encode(bytes(f'user:password','utf-8')).decode('utf-8')
# Use this simple class to parse you HTTP headers
# Read more here: https://***.com/a/5955949/4820341
class HTTPRequest(BaseHTTPRequestHandler):
def __init__(self, request_text):
self.rfile = BytesIO(request_text)
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
def send_error(self, code, message):
self.error_code = code
self.error_message = message
while True:
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
data = connectionSocket.recv(1024)
# Those are your data coming from the client
print(data.decode('utf-8'))
# parse your headers
http_headers = HTTPRequest(data)
try:
# get the incoming auth token
client_token = http_headers.headers['Authorization'].strip('Basic ')
if server_token != client_token:
connectionSocket.sendall(bytes("HTTP/1.1 401 Unauthorized\n\n" + 'Wrong credetials', 'utf-8'))
else:
# process the request and do your stuff here
connectionSocket.sendall(bytes("HTTP/1.1 200 OK\n\n" + 'Ok, all is fine here', 'utf-8'))
except AttributeError:
connectionSocket.sendall(bytes("HTTP/1.1 401 Unauthorized\n\n" + 'No credentials provided', 'utf-8'))
finally:
connectionSocket.close()
这是带有身份验证的requests.get
与服务器端的外观:
Ready to serve...
GET / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: python-requests/2.26.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Authorization: Basic dXNlcjpwYXNz
现在,让我们看看它的实际效果:
>>> r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'pass'))
>>> r.status_code
200
>>> r.text
'Ok, all is fine here'
>>>
>>>
>>> r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'wrongpass'))
>>> r.status_code
401
>>> r.text
'wrong credentials'
>>>
>>>
>>> r = requests.get('http://127.0.0.1:8080')
>>> r.status_code
401
>>> r.text
'No credentials provided'
【讨论】:
以上是关于如何确认用户/通过 http 授权?的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 passport-github 以在回调时确认用户?
使用Spring Security登录认证,通过Oauth2.0开发第三方授授权访问资源项目详解