Azure应用网关代理URL在301重定向中丢失的问题排查
问题描述
我在Azure App Service的虚拟路径上托管了一个Angular Web应用,同时使用Azure Application Gateway(AAG)代理一个优先级高于azurewebsites.net的自定义域名。
访问不带尾部斜杠的虚拟路径时,会触发301重定向,但通过AAG访问时会丢失代理域名:
- 直接访问Azure原生域名:
some-app-service.azurewebsites.net/SomeVirtualPath→ 正常重定向到some-app-service.azurewebsites.net/SomeVirtualPath/ - 通过AAG代理访问:
some-proxy-domain.net/SomeVirtualPath→ 错误重定向到some-app-service.azurewebsites.net/SomeVirtualPath/,代理域名被替换为Azure原生域名
已尝试的排查与配置
- 确认AAG会携带包含目标代理域名的
X-ORIGINAL-HOST请求头,但App Service未正确利用该头信息生成重定向URL - 尝试通过Bicep配置认证正向代理,指定
X-ORIGINAL-HOST作为自定义Host头,但重定向并非由认证环节触发,配置无效 - 也尝试过配置
X-FORWARDED-HOST,同样未解决问题
相关Bicep配置片段:
resource authsettingsV2 'Microsoft.Web/sites/config@2022-09-01' = { name: 'authsettingsV2' kind: 'app' parent: appService properties: { platform: { enabled: true } httpSettings: { forwardProxy: { convention: 'Custom' customHostHeaderName: 'X-ORIGINAL-HOST' } } globalValidation: { requireAuthentication: true unauthenticatedClientAction: 'AllowAnonymous' } } }
相关资源配置
App Service简化Bicep代码
resource appService 'Microsoft.Web/sites@2022-09-01' = { name: 'some-app-service' location: location identity: { // ... } kind: 'app' properties: { serverFarmId: appServicePlan.id httpsOnly: true siteConfig: { use32BitWorkerProcess: false appSettings: [ // ... ] virtualApplications: [ { virtualPath: '/' physicalPath: 'site\\wwwroot' } { virtualPath: '/SomeVirtualPath' physicalPath: 'site\\wwwroot\\SomeVirtualPath' } ] } publicNetworkAccess: 'Disabled' virtualNetworkSubnetId: outboundSubnet.id } }
ADO部署流水线YAML片段
- task: AzureRmWebAppDeployment@4 displayName: Client - Deploy inputs: ConnectionType: AzureRM azureSubscription: $(SomeAzureSubscription) appType: webApp WebAppName: some-app-service deployToSlotOrASE: true ResourceGroupName: some-resource-group SlotName: production VirtualApplication: SomeVirtualPath packageForLinux: $(Pipeline.Workspace)/Artifacts
Angular生成的web.config
<configuration> <system.webServer> <staticContent> <remove fileExtension=".woff2" /> <mimeMap fileExtension=".woff2" mimeType="font/woff2" /> </staticContent> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> <add name="X-Frame-Options" value="SAMEORIGIN" /> <add name="X-Content-Type-Options" value="nosniff" /> <add name="X-XSS-Protection" value="1; mode=block" /> <add name="Cache-Control" value="no-cache, no-store, must-revalidate" /> <add name="Pragma" value="no-cache" /> </customHeaders> </httpProtocol> <rewrite> <rules> <rule name="Main Rule"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="/SomeVirtualPath/" /> </rule> </rules> </rewrite> <caching> <profiles> <add extension=".js" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" /> <add extension=".css" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" /> <add extension=".html" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" /> </profiles> </caching> </system.webServer> </configuration>
寻求解决方案
目前已无更多排查思路,请问还有什么其他可行的解决方案?
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

