I have set up the identity provider for my Function App. When I access the function URL:
https://myfunc-dev-we-01.azurewebsites.net/api/http_trigger
it correctly redirects me to the Microsoft authentication page, and authentication works fine.
However, my goal is to retrieve the authenticated user's email. I attempted to extract it using the X-MS-CLIENT-PRINCIPAL
header, but I’m unable to get it to work.
Here’s my current Function App code:
import azure.functions as func
import logging
import base64
import json
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
# Retrieve the X-MS-CLIENT-PRINCIPAL header
client_principal_header = req.headers.get('X-MS-CLIENT-PRINCIPAL')
logging.info(f"X-MS-CLIENT-PRINCIPAL header: {client_principal_header}")
user_name = None
if client_principal_header:
try:
# Decode the Base64-encoded header
decoded_header = base64.b64decode(client_principal_header).decode('utf-8')
logging.info(f"Decoded X-MS-CLIENT-PRINCIPAL: {decoded_header}")
client_principal = json.loads(decoded_header)
# Log the entire client principal for debugging
logging.info(f"Client Principal: {client_principal}")
# Extract the user's name from the claims
user_name = client_principal.get('userPrincipalName') or client_principal.get('name')
except Exception as e:
logging.error(f"Error decoding client principal: {e}")
if user_name:
return func.HttpResponse(f"Hello, {user_name}. This HTTP triggered function executed successfully.")
else:
return func.HttpResponse(
"This HTTP triggered function executed successfully. However, no authenticated user information was found.",
status_code=200
)
Issue:
I keep getting the response:
This HTTP triggered function executed successfully. However, no authenticated user information was found.
What am I missing?
Do I need to configure additional settings in Azure AD authentication for the email claim to be included?
Is there another way to retrieve the authenticated user’s email?
This is my authentication setup
As a side note:
I'm the guest user, and identities are as ExternalAzureAD
And people from the company itself,
Could this be the issue?
I modified your code to use the claims
array from the X-MS-CLIENT-PRINCIPAL
header instead of relying on top-level keys like userPrincipalName
and I successfully retrieved the email ID after authenticating to the Function App.
I have added below lines to the code.
for claim in claims:
if claim.get("typ") in [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"preferred_username",
"name"
]:
user_email = claim.get("val")
Complete Code:
import azure.functions as func
import logging
import base64
import json
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
client_principal_header = req.headers.get('X-MS-CLIENT-PRINCIPAL')
user_email = None
if client_principal_header:
try:
decoded = base64.b64decode(client_principal_header).decode('utf-8')
client_principal = json.loads(decoded)
claims = client_principal.get("claims", [])
for claim in claims:
if claim.get("typ") in [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"preferred_username",
"name"
]:
user_email = claim.get("val")
break
except Exception as e:
logging.error(f"Failed to parse client principal: {e}")
if user_email:
return func.HttpResponse(f"Hello, {user_email}. You are authenticated.")
else:
return func.HttpResponse(
"No authenticated user information found. Please ensure authentication is configured.",
status_code=200
)
Output:
I successfully retrieved the email ID after authenticating to the Function App.