Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion chat-app/backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fastapi==0.136.0
uvicorn[standard]==0.44.0
pydantic[email]==2.13.2
pydantic-settings==2.14.2
PyJWT[crypto]==2.10.1
PyJWT[crypto]==2.15.0

agent-framework-azure-ai==1.0.0rc6
agent-framework-core==1.0.0rc6
Expand Down
6 changes: 5 additions & 1 deletion chat-app/frontend/src/components/EnhancedChatPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,11 @@ export const EnhancedChatPanel = ({
const ttsHeaders: Record<string, string> = { 'Content-Type': 'application/json' };
const bearer = getApiBearerToken();
if (bearer) {
ttsHeaders.Authorization = `Bearer ${bearer}`;
const isSameOriginProxy =
typeof window !== 'undefined' &&
new URL(apiBase || '/', window.location.origin).origin === window.location.origin;
const headerName = isSameOriginProxy ? 'X-Backend-Authorization' : 'Authorization';
ttsHeaders[headerName] = `Bearer ${bearer}`;
}
const resp = await fetch(`${apiBase}/api/voice/tts`, {
method: 'POST',
Expand Down
7 changes: 6 additions & 1 deletion chat-app/frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ api.interceptors.request.use((config) => {
api.interceptors.request.use(
(config) => {
if (cachedBearerToken && config.headers) {
config.headers.Authorization = `Bearer ${cachedBearerToken}`;
const base = getApiBaseUrl();
const isSameOriginProxy =
typeof window !== 'undefined' &&
new URL(base || '/', window.location.origin).origin === window.location.origin;
const headerName = isSameOriginProxy ? 'X-Backend-Authorization' : 'Authorization';
config.headers[headerName] = `Bearer ${cachedBearerToken}`;
}

return config;
Expand Down
4 changes: 4 additions & 0 deletions chat-app/frontend/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ location /api/ {
set \$backend "${BACKEND_API_URL}";
proxy_pass \$backend;
proxy_set_header Host "${BACKEND_HOST}";
proxy_set_header Authorization \$http_x_backend_authorization;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
Expand All @@ -49,6 +50,9 @@ location /api/ {
proxy_connect_timeout 60s;
proxy_buffering off;

proxy_redirect ~^https?://${BACKEND_HOST}/(.*)\$ /\$1;


# WebSocket support (needed for /api/voice/ws/... connections)
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
Expand Down
2 changes: 1 addition & 1 deletion infra/scripts/post-provision/configure_auth.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function Set-FrontendAuth {
openIdIssuer = "https://login.microsoftonline.com/$TenantId/v2.0"
}
login = @{ loginParameters = @("scope=openid profile email offline_access api://$ApplicationClientId/user_impersonation") }
validation = @{ allowedAudiences = @($ApplicationClientId) }
validation = @{ allowedAudiences = @($ApplicationClientId, "api://$ApplicationClientId") }
}
}
login = @{ tokenStore = @{ enabled = $true } }
Expand Down
2 changes: 1 addition & 1 deletion infra/scripts/post-provision/configure_auth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ configure_frontend() {
auth_uri="https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Web/sites/$app_name/config/authsettingsV2?api-version=2022-09-01"
body_file="$(mktemp)"
trap 'rm -f "$body_file"' RETURN
printf '%s' "{\"properties\":{\"platform\":{\"enabled\":true,\"runtimeVersion\":\"~1\"},\"globalValidation\":{\"requireAuthentication\":false,\"unauthenticatedClientAction\":\"AllowAnonymous\"},\"httpSettings\":{\"requireHttps\":true},\"identityProviders\":{\"azureActiveDirectory\":{\"enabled\":true,\"registration\":{\"clientId\":\"$CLIENT_ID\",\"clientSecretSettingName\":\"$SECRET_SETTING_NAME\",\"openIdIssuer\":\"https://login.microsoftonline.com/$TENANT_ID/v2.0\"},\"login\":{\"loginParameters\":[\"scope=openid profile email offline_access api://$CLIENT_ID/user_impersonation\"]},\"validation\":{\"allowedAudiences\":[\"$CLIENT_ID\"]}}},\"login\":{\"tokenStore\":{\"enabled\":true}}}}" > "$body_file"
printf '%s' "{\"properties\":{\"platform\":{\"enabled\":true,\"runtimeVersion\":\"~1\"},\"globalValidation\":{\"requireAuthentication\":false,\"unauthenticatedClientAction\":\"AllowAnonymous\"},\"httpSettings\":{\"requireHttps\":true},\"identityProviders\":{\"azureActiveDirectory\":{\"enabled\":true,\"registration\":{\"clientId\":\"$CLIENT_ID\",\"clientSecretSettingName\":\"$SECRET_SETTING_NAME\",\"openIdIssuer\":\"https://login.microsoftonline.com/$TENANT_ID/v2.0\"},\"login\":{\"loginParameters\":[\"scope=openid profile email offline_access api://$CLIENT_ID/user_impersonation\"]},\"validation\":{\"allowedAudiences\":[\"$CLIENT_ID\",\"api://$CLIENT_ID\"]}}},\"login\":{\"tokenStore\":{\"enabled\":true}}}}" > "$body_file"
az rest --method put --uri "$auth_uri" --body "@$body_file" --output none
rm -f "$body_file"
trap - RETURN
Expand Down
2 changes: 1 addition & 1 deletion scenario-app/backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ uvicorn[standard]==0.40.0
pydantic[email]==2.11.10
pydantic-settings==2.14.2
python-multipart==0.0.32
PyJWT[crypto]==2.10.1
PyJWT[crypto]==2.15.0

# Azure Services for E-commerce
azure-identity==1.25.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ export const EnhancedChatPanel = ({
const ttsHeaders: Record<string, string> = { 'Content-Type': 'application/json' };
const bearer = getApiBearerToken();
if (bearer) {
ttsHeaders.Authorization = `Bearer ${bearer}`;
const isSameOriginProxy =
typeof window !== 'undefined' && apiBase === window.location.origin;
Comment on lines +147 to +148
const headerName = isSameOriginProxy ? 'X-Backend-Authorization' : 'Authorization';
ttsHeaders[headerName] = `Bearer ${bearer}`;
}
const resp = await fetch(`${apiBase}/api/voice/tts`, {
method: 'POST',
Expand Down
6 changes: 5 additions & 1 deletion scenario-app/frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ api.interceptors.request.use((config) => {
api.interceptors.request.use(
(config) => {
if (cachedBearerToken && config.headers) {
config.headers.Authorization = `Bearer ${cachedBearerToken}`;
const base = getApiBaseUrl();
const isSameOriginProxy =
typeof window !== 'undefined' && base === window.location.origin;
Comment on lines +67 to +68
const headerName = isSameOriginProxy ? 'X-Backend-Authorization' : 'Authorization';
config.headers[headerName] = `Bearer ${cachedBearerToken}`;
}

return config;
Expand Down
12 changes: 8 additions & 4 deletions scenario-app/frontend/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ if [ -n "${BACKEND_API_URL}" ]; then
cat > /etc/nginx/conf.d/api-proxy.conf << PROXYEOF
# Reverse proxy for backend API - WAF private networking deployment
location /api/ {
resolver 168.63.129.16 valid=30s;
set \$backend "${BACKEND_API_URL}";
proxy_pass \$backend;
proxy_set_header Host "${BACKEND_HOST}";
resolver 168.63.129.16 valid=30s;
set \$backend "${BACKEND_API_URL}";
proxy_pass \$backend;
proxy_set_header Host "${BACKEND_HOST}";
proxy_set_header Authorization \$http_x_backend_authorization;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
Expand All @@ -88,6 +89,8 @@ location /api/ {
proxy_connect_timeout 60s;
proxy_buffering off;

proxy_redirect ~^https?://${BACKEND_HOST}/(.*)\$ /\$1;

# WebSocket support (needed for /api/voice/ws/... connections)
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
Expand All @@ -104,6 +107,7 @@ location /chat-api/ {
rewrite ^/chat-api/(.*)\$ /\$1 break;
proxy_pass \$chat_backend;
proxy_set_header Host "${CHAT_BACKEND_HOST}";
proxy_set_header Authorization \$http_x_backend_authorization;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
Expand Down
Loading