Skip to content
Merged
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
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}`;
Comment thread
Copilot marked this conversation as resolved.
}
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}`;
Comment thread
Copilot marked this conversation as resolved.
}

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
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;
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;
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