微服务架构下基于JWT的授权问题咨询(含服务配置)
问题1:ResourceService是否需要每次调用IdentityService来验证令牌?
不需要每次调用。JWT是自包含令牌,本身携带了用户身份、权限等核心信息,而且带有签名。ResourceService只要拿到IdentityService用于签名JWT的公钥/证书,就能在本地完成令牌的签名有效性、过期时间、受众(Audience)等校验,完全不用每次请求都去调用IdentityService。
只有当你有实时校验令牌是否被吊销的需求(比如用户主动登出、权限临时变更),才需要额外调用IdentityService的令牌 introspection 接口,但这不是JWT验证的默认流程。
你碰到的IDX20803错误,是因为ResourceService的JWT中间件默认会通过OIDC发现机制,去Authority配置的地址拉取/.well-known/openid-configuration配置文件(里面包含公钥、端点信息等),但你的IdentityService没提供这个端点,导致拉取失败,进而无法完成本地验证,最终触发授权失败。
问题2:为验证JWT令牌,我是否需要在IdentityService中实现.well-known端点?
是的,必须实现——如果你想用ASP.NET Core JWTBearer中间件的默认OIDC发现机制的话。
如果不想折腾完整的OIDC发现端点,也可以绕开自动发现,手动给ResourceService的JWTBearer配置验证参数:
- 直接指定
TokenValidationParameters里的IssuerSigningKey(填IdentityService签名JWT用的公钥) - 手动设置
ValidIssuer、ValidAudience - 关闭自动拉取配置的逻辑
手动配置示例(ResourceService)
services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Audience = "https://resource"; options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = "https://identity", // 必须和IdentityService发JWT时的Issuer一致 ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, // 替换成你实际的公钥,比如用RSA公钥或者JWK格式 IssuerSigningKey = new JsonWebKey("你的IdentityService公钥JSON字符串"), }; // 关闭自动元数据拉取,用静态配置替代 options.ConfigurationManager = new StaticConfigurationManager<OpenIdConnectConfiguration>( new OpenIdConnectConfiguration() ); });
另外提一句:你的IdentityService当前配置里加了JwtBearer认证,但主要用的是Cookie和Google登录,别忘了在用户通过Google认证后,要正确生成并颁发JWT令牌,而且必须用固定的密钥/证书签名,这样ResourceService才能用对应的公钥验证令牌的合法性。
内容的提问来源于stack exchange,提问作者Dr. Strangelove

