如何验证JWT令牌来自指定应用?基于TokenValidationParameters的选型咨询
验证特定AAD应用调用API的正确方式
要确保只有指定的单个AAD应用能调用你的API,你需要组合基础JWT验证和应用身份校验,无需完全自定义授权,利用TokenValidationParameters结合声明校验即可实现,具体如下:
1. 基础必填验证字段
这些是保障令牌合法性的核心配置,必须启用:
- Signature Key:设置
ValidateIssuerSigningKey = true,并加载AAD的公钥(可通过AAD元数据端点自动获取),确保令牌由AAD签发且未被篡改。 - Issuer:配置
ValidIssuers为你的AAD租户签发地址(格式通常为https://login.microsoftonline.com/{租户ID}/v2.0),拦截来自其他租户的非法令牌。 - Audience:设置
ValidAudiences为你的API的客户端ID(即AAD中注册的API的Application ID),确保令牌是发给你的API的,而非其他服务。
2. 限制特定应用的核心校验
要锁定单个应用,需验证令牌中的**azp(Authorized Party)声明**(或appid声明,视OAuth流而定):
- 当应用使用**客户端凭证流(Client Credentials)**调用API时,
azp和appid的值均为该应用的客户端ID; - 当应用使用授权码流代表用户调用API时,
azp是调用应用的客户端ID,appid是签发令牌的应用ID,此时azp更能准确标识实际调用方。
代码实现示例
配置TokenValidationParameters后,添加令牌验证后的事件逻辑,检查azp声明是否匹配目标应用的客户端ID:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuers = new[] { "https://login.microsoftonline.com/你的租户ID/v2.0" }, ValidateAudience = true, ValidAudiences = new[] { "你的API的客户端ID" }, ValidateIssuerSigningKey = true, IssuerSigningKeys = new JsonWebKeySet("https://login.microsoftonline.com/你的租户ID/discovery/v2.0/keys").GetSigningKeys(), ValidateLifetime = true }; options.Events = new JwtBearerEvents { OnTokenValidated = context => { var azp = context.Principal.Claims.FirstOrDefault(c => c.Type == "azp")?.Value; var allowedAppId = "允许调用的应用的客户端ID"; if (azp != allowedAppId) { context.Fail("Invalid application caller"); } return Task.CompletedTask; } }; });
为什么不需要完全自定义授权?
上述方式已能精准锁定单个应用:基础验证确保令牌合法,azp声明校验确保调用者是指定应用,完全满足你的需求,无需额外构建复杂的自定义授权逻辑。
内容的提问来源于stack exchange,提问作者Joe Defill
相关产品推荐
相关产品推荐

