Blazor WA托管版部署Azure AppService授权触发401令牌签发方无效问题
问题根本原因
- 本地开发环节没有反向代理层,应用直接通过Kestrel对外提供服务,请求的协议、主机头可被直接读取,IdentityServer生成的访问令牌里携带的
iss(签发者)声明、JwtBearer中间件校验令牌时的预期签发者地址完全一致,因此不会出现校验失败。 - 生产环境跑在Linux版Azure App Service时,平台自带的反向代理会完成SSL终止,之后以HTTP协议把请求转发到应用容器内部。由于服务端没有配置转发头识别逻辑,应用无法感知原始请求的HTTPS协议、外网域名Host信息,最终导致地址推导错位:
- IdentityServer处理浏览器端发起的授权流程时,可通过请求头拿到正确的外网Host,生成带
https://blazorfun2.azurewebsites.net签发者声明的访问令牌; - 但JwtBearer中间件初始化校验规则时,会基于应用内部感知到的容器监听地址(比如内网HTTP地址)配置预期的签发者,和令牌里实际携带的外网签发者地址不匹配,最终触发
invalid_token的401错误。
- IdentityServer处理浏览器端发起的授权流程时,可通过请求头拿到正确的外网Host,生成带
- 硬编码修改
IssuerUri确实可以让两侧的签发者值统一,但属于静态写死的方案,一旦更换部署域名、迁移运行环境,就需要修改代码重新发布,无法适配动态部署的场景,所以不是最优解。
最优解决方案
这套方案不需要硬编码任何域名地址,可自动适配反向代理环境的请求信息,从根源解决地址推导错位的问题:
- 服务端项目Startup.cs中,首先引入转发头处理的命名空间:
using Microsoft.AspNetCore.HttpOverrides; - 在
ConfigureServices方法最开头,注册转发头配置,清空默认的可信代理列表(因为Azure App Service的反向代理出口IP是动态变化的,无法提前枚举):
services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 清空默认可信网络和代理列表,适配Azure App Service动态代理IP场景 options.KnownNetworks.Clear(); options.KnownProxies.Clear(); });
- 在
Configure方法的HTTP管道配置最开头(必须放在其他中间件之前,保证后续所有组件拿到的都是正确的原始请求信息),启用转发头处理中间件:
app.UseForwardedHeaders();
- 配置完成后,应用会正确解析来自Azure App Service代理的
X-Forwarded-Proto(原始请求协议)、X-Forwarded-Host(原始请求域名)头信息,不管是IdentityServer生成令牌时的签发者地址,还是JwtBearer校验令牌时的预期签发者地址,都会自动和实际的外网访问地址保持一致,全程不需要硬编码任何域名即可通过校验。
内容的提问来源于stack exchange,提问作者Alamakanambra
相关产品推荐
相关产品推荐

