如何使用Python解码`X-ARR-ClientCert`标头? [英] How to decode `X-ARR-ClientCert` header using Python?

查看:496
本文介绍了如何使用Python解码`X-ARR-ClientCert`标头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何解码Azure App Service传递给我的Azure函数代码的X-ARR-ClientCert标头?

How do I decode the X-ARR-ClientCert header passed by Azure App Service to my Azure Function code?

示例:

  • HTTP触发的Python Azure函数
  • Azure App Service配置为接受客户端证书
  • 请求者发送带有GET请求的客户端证书(按照邮递员的说明)
  • Azure App Service通过X-ARR-ClientCert标头将客户端证书传递给功能代码
  • HTTP-triggered, Python Azure Function
  • Azure App Service configured to accept client certs
  • Requestor sends a client certificate with GET request (per Postman instructions here)
  • Azure App Service passes client cert to Function code via a X-ARR-ClientCert header

问题:

  • 我找不到有关此标头编码方式的文档
  • 我找不到如何使用Python解码此标头的示例

我最接近的是以下代码:

import logging
import base64
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    
    logging.info('####### Python HTTP trigger certificate validation function processing a request. #######')

    # Retrieve client cert from headers
    req_cert_str = req.headers.get("X-ARR-ClientCert")
    
    req_cert_bytes = base64.b64decode(req_cert_str)
    
    decoded_string = req_cert_bytes.decode('cp1252')

    return func.HttpResponse(
        decoded_string
    )

  • 这将导致Status 500 Internal server error和:
    • Which results in Status 500 Internal server error and:
    • Exception while executing function: Functions.certiFunc <--- Result: Failure Exception: UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 403: character maps to <undefined> Stack: File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 343, in _handle__invocation_request call_result = await self._loop.run_in_executor( File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 480, in __run_sync_func return func(**params) File "/home/site/wwwroot/certiFunc/__init__.py", line 14, in main decoded_string = req_cert_bytes.decode('cp1252') File "/usr/local/lib/python3.8/encodings/cp1252.py", line 15, in decode return codecs.charmap_decode(input,errors,decoding_table) 
      

      • 替换decoded_string = req_cert_bytes.decode('utf-8')时,我得到:
        • When substituting decoded_string = req_cert_bytes.decode('utf-8'), I get:
        • Exception while executing function: Functions.certiFunc <--- Result: Failure Exception: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 1: invalid start byte Stack: File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 343, in _handle__invocation_request call_result = await self._loop.run_in_executor( File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 480, in __run_sync_func return func(**params) File "/home/site/wwwroot/certiFunc/__init__.py", line 14, in main decoded_string = req_cert_bytes.decode('utf-8') 
          

          • 运行以下命令(直接解码标头)时...
          • req_cert_str = req.headers.get("X-ARR-ClientCert")
            decoded_string = base64.b64decode(req_cert_str) 
            

            ...我得到一个Status 200 Success,但是响应是二进制(?)字符和纯文本的混搭:

            ...I get a Status 200 Success but the response is a mashup of binary(?) characters and plain text:

            使用Python解码此标头的正确方法是什么?

            对Github问题的进一步阅读提出了此处

            Further reading on the Github issue raised here

            推荐答案

            由于要添加Postman的客户端证书,因此采用DER(二进制)格式.您可以使用Python 加密从字节本身解码x509证书.

            Since you are adding the client certificate from Postman, it's in DER (binary) format. You can decode the x509 certificate from bytes itself using Python cryptography.

            from cryptography import x509
            
            # header is base64 encoded string, so extract the bytes first
            req_cert_str = req.headers.get("X-ARR-ClientCert") 
            req_cert_bytes = base64.b64decode(req_cert_str)
            
            cert = x509.load_der_x509_certificate(req_cert_bytes)
            
            # do stuffs with cert
            logging.info(f'Received client cert with serial number: {cert.serial_number}')
            
            

            注意:如果证书是PEM格式,则需要使用x509.load_pem_x509_certificate(req_cert_bytes)

            Note: If the certificate was PEM format, you would need to use x509.load_pem_x509_certificate(req_cert_bytes)

            这篇关于如何使用Python解码`X-ARR-ClientCert`标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆