How do I decode the X-ARR-ClientCert header passed by Azure App Service to my Azure Function code?
Example:
- 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-ClientCertheader
Issue:
- I cannot find documentation on how this header is encoded
- I cannot find an example of how to decode this header using Python
The closest I've got is this code:
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
)
- Which results in
Status 500 Internal server errorand:
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)
- 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')
- When running the following (directly decoding the header)...
req_cert_str = req.headers.get("X-ARR-ClientCert")
decoded_string = base64.b64decode(req_cert_str)
...I get a Status 200 Success but the response is a mashup of binary(?) characters and plain text:
What is the correct method for decoding this header using Python?
Further reading on the Github issue raised here

Deserialize a certificate from PEM encoded data.How do I know thatX-ARR-ClientCertis PEM encoded data? The client uploaded a cert in.crtformat (as Postman only currently supports.crt.and.pfxformats)..crt/.pfx, useload_der_x509_certificate- Deserialize a certificate from DER encoded data. DER is a binary format and is commonly found in files with the .cer extension (although file extensions are not a guarantee of encoding type).load_der_x509_certificatesays it takes data of typebytes. TheX-ARR-ClientCertheader if of typestr. Do I need to convert first?req_cert_str = req.headers.get("X-ARR-ClientCert") req_cert_bytes = base64.b64decode(req_cert_str)then passreq_cert_bytestoload_der_x509_certificate