IdentityServer4 AddLocalApiAuthentication 在反向代理子路径后面托管时未使用正确的颁发者 uri
IdentityServer4 AddLocalApiAuthentication not using the right issuer uri when hosting behind reverse proxy subpath
我在根 url (example.com/subpath
) 的子路径上的反向代理后面托管身份服务器。
对于同一代理 (example.com/apisubpath
) 后面的外部 api,令牌验证工作正常。
现在,我在托管 IdentityServer 的同一服务上添加了一个 api,如
Adding more API endpoints.
请求范围为 IdentityServerApi
的令牌工作正常,在没有反向代理的情况下在我的本地开发环境中测试它时,我成功调用了 api。
在反向代理后面我得到一个错误:Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10205: Issuer validation failed. Issuer: 'https://example.com/subpath'. Did not match: validationParameters.ValidIssuer: 'https://example.com' or validationParameters.ValidIssuers: 'null'.
所以它从请求中获取了正确的域,但是当 'registering' 看起来 validationParameters.ValidIssuer
时它不包含子路径。
有没有办法手动设置 validationParameters.ValidIssuer
还是我做错了什么?
感谢您的帮助
有几种方法可以使用 Identity Server 4
- 如果没有在 Identity Server 上设置明确的 Issuer,它将检查来自客户端请求的
Host
header。否则只需在 Identity Server 4 上显式设置 Issuer:
// This one was on the Identity server
services.AddIdentityServer(opts => opts.IssuerUri = "The explicit Url came here!")
- 不想在服务器上显式设置 Issuer,而是让 Identity Server 自己找出 Issuer?
// This one was on the other services, If not set to the same instance of Identity Server
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false, // If set to true, It's gonna take care of the issuer
ValidIssuer = "If we just have a single Issuer, set it here",
ValidIssuers = new []{"Multiple", "Issuer", "Came", "Here"}
};
});
- 你现在的情况应该是从服务器取出token时,对
connect/token
的请求有Host
header个https://example.com/subpath
,而应该是https://example.com
, 所以...就选择上面最适合的选项
首先,部署策略之间没有这样具体的 check/relation,这完全取决于您如何验证令牌。由于您尚未发布 ID4 验证
中间件配置我将只解释验证令牌时到底发生了什么。
- 令牌创建:
我认为关于 ID4 颁发者验证存在很多混淆,所以让我们深入研究一下。默认情况下,ID4 包含作为颁发者的托管路径,假设您在 IIS 中部署了一个 ID4 应用程序并且其虚拟路径为 https://localhost/IdentityServer
,那么该路径将是您在令牌中的颁发者。 Here 您可以验证您的令牌。因此,由于它将发行者作为您的托管应用程序路径,这意味着发行者对于部署在不同环境中的每个 IdS4 实例都是不同的(当您不想与多个环境(暂存和生产)或实例共享您的令牌时,它会很有帮助).但是您仍然可以通过设置以下选项在 ID4 应用程序中设置此发行者 URL。
services.AddIdentityServer(options => {
options.IssuerUri = "https://MyDNS/Common"
});
通过这样做,您应该能够跨环境或 IdS4 实例验证您的令牌。如果您不想要一个可能导致安全漏洞的静态发行者,用户可以在其中使用您的预生产环境令牌来调用生产 API 那么您可能对下一节感兴趣,即消费者中的中间件配置 API.
- 中间件配置使用
.AddJwtBearer
:
IdS4 团队自己开发了另一个中间件 (.AddIdentityServerAuthentication()
),但他们不再维护代码,根据他们建议的最新文档 .AddJwtBearer()
。
在上一节中,我们介绍了令牌提供者的配置(在我们的例子中是 IdS4)以设置静态发行者,但如果您不想这样做,因为它会引发安全问题,那么消费者配置将是您的下一个要遵循的步骤。下面的代码片段是验证令牌所需的基本最低配置。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://MyID4Domain/"
options.RequireHttpsMetadata = false; // Non-PROD
options.TokenValidationParameters.ValidateAudience = false;
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Log.Logger.Error($"Authentication failed. {context.Exception.InnerException}");
return Task.CompletedTask;
}
};
});
如果你使用上面的代码保护了你的 WebApi,那么 .AddJwtBearer()
中间件默认期望 options.Authority
URL 作为发行者,在我们的例子中它是 https://MyID4Domain/
,但是你可以使用您的令牌中预期的有效发行人覆盖该检查。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters.ValidIssuer = "SomeOtherIssuer"; // If you have different issuer than your Authority url.
**OR**
options.TokenValidationParameters.ValidIssuers = ["Issuer1", "issuer2", "issuer3"]; // In case deployed on multiple instances and wanted to validate token which is generated from any of these instance.
// Kind of multi-tenant support. I know there is a different mechanism that is coming along with ID5.
**OR**
options.TokenValidationParameters.ValidateIssuer = false; // If you don't want to validate issuer at all.
}
编码愉快!
我在根 url (example.com/subpath
) 的子路径上的反向代理后面托管身份服务器。
对于同一代理 (example.com/apisubpath
) 后面的外部 api,令牌验证工作正常。
现在,我在托管 IdentityServer 的同一服务上添加了一个 api,如 Adding more API endpoints.
请求范围为 IdentityServerApi
的令牌工作正常,在没有反向代理的情况下在我的本地开发环境中测试它时,我成功调用了 api。
在反向代理后面我得到一个错误:Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10205: Issuer validation failed. Issuer: 'https://example.com/subpath'. Did not match: validationParameters.ValidIssuer: 'https://example.com' or validationParameters.ValidIssuers: 'null'.
所以它从请求中获取了正确的域,但是当 'registering' 看起来 validationParameters.ValidIssuer
时它不包含子路径。
有没有办法手动设置 validationParameters.ValidIssuer
还是我做错了什么?
感谢您的帮助
有几种方法可以使用 Identity Server 4
- 如果没有在 Identity Server 上设置明确的 Issuer,它将检查来自客户端请求的
Host
header。否则只需在 Identity Server 4 上显式设置 Issuer:
// This one was on the Identity server
services.AddIdentityServer(opts => opts.IssuerUri = "The explicit Url came here!")
- 不想在服务器上显式设置 Issuer,而是让 Identity Server 自己找出 Issuer?
// This one was on the other services, If not set to the same instance of Identity Server
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false, // If set to true, It's gonna take care of the issuer
ValidIssuer = "If we just have a single Issuer, set it here",
ValidIssuers = new []{"Multiple", "Issuer", "Came", "Here"}
};
});
- 你现在的情况应该是从服务器取出token时,对
connect/token
的请求有Host
header个https://example.com/subpath
,而应该是https://example.com
, 所以...就选择上面最适合的选项
首先,部署策略之间没有这样具体的 check/relation,这完全取决于您如何验证令牌。由于您尚未发布 ID4 验证 中间件配置我将只解释验证令牌时到底发生了什么。
- 令牌创建:
我认为关于 ID4 颁发者验证存在很多混淆,所以让我们深入研究一下。默认情况下,ID4 包含作为颁发者的托管路径,假设您在 IIS 中部署了一个 ID4 应用程序并且其虚拟路径为 https://localhost/IdentityServer
,那么该路径将是您在令牌中的颁发者。 Here 您可以验证您的令牌。因此,由于它将发行者作为您的托管应用程序路径,这意味着发行者对于部署在不同环境中的每个 IdS4 实例都是不同的(当您不想与多个环境(暂存和生产)或实例共享您的令牌时,它会很有帮助).但是您仍然可以通过设置以下选项在 ID4 应用程序中设置此发行者 URL。
services.AddIdentityServer(options => {
options.IssuerUri = "https://MyDNS/Common"
});
通过这样做,您应该能够跨环境或 IdS4 实例验证您的令牌。如果您不想要一个可能导致安全漏洞的静态发行者,用户可以在其中使用您的预生产环境令牌来调用生产 API 那么您可能对下一节感兴趣,即消费者中的中间件配置 API.
- 中间件配置使用
.AddJwtBearer
:
IdS4 团队自己开发了另一个中间件 (.AddIdentityServerAuthentication()
),但他们不再维护代码,根据他们建议的最新文档 .AddJwtBearer()
。
在上一节中,我们介绍了令牌提供者的配置(在我们的例子中是 IdS4)以设置静态发行者,但如果您不想这样做,因为它会引发安全问题,那么消费者配置将是您的下一个要遵循的步骤。下面的代码片段是验证令牌所需的基本最低配置。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://MyID4Domain/"
options.RequireHttpsMetadata = false; // Non-PROD
options.TokenValidationParameters.ValidateAudience = false;
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Log.Logger.Error($"Authentication failed. {context.Exception.InnerException}");
return Task.CompletedTask;
}
};
});
如果你使用上面的代码保护了你的 WebApi,那么 .AddJwtBearer()
中间件默认期望 options.Authority
URL 作为发行者,在我们的例子中它是 https://MyID4Domain/
,但是你可以使用您的令牌中预期的有效发行人覆盖该检查。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters.ValidIssuer = "SomeOtherIssuer"; // If you have different issuer than your Authority url.
**OR**
options.TokenValidationParameters.ValidIssuers = ["Issuer1", "issuer2", "issuer3"]; // In case deployed on multiple instances and wanted to validate token which is generated from any of these instance.
// Kind of multi-tenant support. I know there is a different mechanism that is coming along with ID5.
**OR**
options.TokenValidationParameters.ValidateIssuer = false; // If you don't want to validate issuer at all.
}
编码愉快!