如何配置 Identity Server 以在 Azure App Slot Switch 之后正确验证 JWT 令牌?
How can I configure Identity Server to correctly validate JWT tokens after an Azure App Slot Switch?
我有一个核心托管 API,它使用 IdentityServer 并向我的基于桌面的客户端发出 JwtBearer 令牌。这通常可以正常工作,我可以按预期登录并使用该应用程序。
但是,在使用 Azure 部署槽时,我 运行 由于 Issuer 验证而遇到问题。
交换插槽时,azure 不会交换 运行ning 代码,而只是交换指向 url,以便预热的 运行ning 应用程序可以立即为请求提供服务。但是,Identity Server 实现似乎保留了对旧插槽 URL 的引用,并将其用作颁发者验证的一部分。
这意味着一旦插槽被交换,不仅所有客户端都有效注销(这已经够糟糕了),而且当客户端再次登录时,Identity Server 提供的令牌甚至无效因为发行者的 URI 错误。
这会导致错误:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:
IdentityServerJwtBearer was not authenticated. Failure message:
IDX10205: Issuer validation failed. Issuer:
'https://my-app-name.azurewebsites.net'. Did not match:
validationParameters.ValidIssuer:
'https://my-app-name-deployment.azurewebsites.net' or
validationParameters.ValidIssuers: 'null'.
我试图通过在设置中这样做来禁用发行者验证:
services.AddAuthentication(options =>
{
})
.AddCookie()
.AddJwtBearer(options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
})
.AddIdentityServerJwt();
但这似乎没有任何区别。我在错误的地方设置了这个变量吗?是否还需要配置其他设置来绕过此检查?
我还尝试将 ValidIssuers 列表设置为同时包含 'https://my-app-name.azurewebsites.net' 和 'https://my-app-name-deployment.azurewebsites.net',希望其中任何一个都能被接受并允许令牌由任一插槽验证,但同样如此好像没什么区别。
或者,有没有一种方法可以防止 IdentityServer 缓存 Issuer Url - 或者有一种方法可以在不重新启动应用程序的情况下刷新该缓存?目前,一旦插槽被交换,我可以让桌面应用程序访问 API 的唯一方法是重新启动 API 应用程序,然后再次登录(只是注销并登录仍然会导致服务器无法验证的令牌,即使服务器刚刚发出它也是如此)。
我觉得我一定遗漏了一些非常明显的东西,但我看不到它是什么...
要配置 IdentityServer JWT Bearer,您可以使用配置调用:
services.Configure<JwtBearerOptions>(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
});
通过这种方式,ValidateIssuer 标志设置在 IdentityServerJwt 上,而不是设置新 JwtBearer 的原始代码,它与 IdentityServer 完全分开。
在正确的服务上设置配置后,还可以使用 ValidIssuers 数组来包含应该被接受的 Asure Slot Urls。
我有一个核心托管 API,它使用 IdentityServer 并向我的基于桌面的客户端发出 JwtBearer 令牌。这通常可以正常工作,我可以按预期登录并使用该应用程序。
但是,在使用 Azure 部署槽时,我 运行 由于 Issuer 验证而遇到问题。
交换插槽时,azure 不会交换 运行ning 代码,而只是交换指向 url,以便预热的 运行ning 应用程序可以立即为请求提供服务。但是,Identity Server 实现似乎保留了对旧插槽 URL 的引用,并将其用作颁发者验证的一部分。
这意味着一旦插槽被交换,不仅所有客户端都有效注销(这已经够糟糕了),而且当客户端再次登录时,Identity Server 提供的令牌甚至无效因为发行者的 URI 错误。
这会导致错误:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: IdentityServerJwtBearer was not authenticated. Failure message: IDX10205: Issuer validation failed. Issuer: 'https://my-app-name.azurewebsites.net'. Did not match: validationParameters.ValidIssuer: 'https://my-app-name-deployment.azurewebsites.net' or validationParameters.ValidIssuers: 'null'.
我试图通过在设置中这样做来禁用发行者验证:
services.AddAuthentication(options =>
{
})
.AddCookie()
.AddJwtBearer(options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
})
.AddIdentityServerJwt();
但这似乎没有任何区别。我在错误的地方设置了这个变量吗?是否还需要配置其他设置来绕过此检查?
我还尝试将 ValidIssuers 列表设置为同时包含 'https://my-app-name.azurewebsites.net' 和 'https://my-app-name-deployment.azurewebsites.net',希望其中任何一个都能被接受并允许令牌由任一插槽验证,但同样如此好像没什么区别。
或者,有没有一种方法可以防止 IdentityServer 缓存 Issuer Url - 或者有一种方法可以在不重新启动应用程序的情况下刷新该缓存?目前,一旦插槽被交换,我可以让桌面应用程序访问 API 的唯一方法是重新启动 API 应用程序,然后再次登录(只是注销并登录仍然会导致服务器无法验证的令牌,即使服务器刚刚发出它也是如此)。
我觉得我一定遗漏了一些非常明显的东西,但我看不到它是什么...
要配置 IdentityServer JWT Bearer,您可以使用配置调用:
services.Configure<JwtBearerOptions>(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
});
通过这种方式,ValidateIssuer 标志设置在 IdentityServerJwt 上,而不是设置新 JwtBearer 的原始代码,它与 IdentityServer 完全分开。
在正确的服务上设置配置后,还可以使用 ValidIssuers 数组来包含应该被接受的 Asure Slot Urls。