【问题标题】:Identity Server 4 and docker身份服务器 4 和 docker
【发布时间】:2017-06-29 19:30:42
【问题描述】:

我正在尝试使用 docker 配置 IdentityServer4,但无法使其正常工作。首先,我使用了身份服务器文档的客户端凭据示例:Protecting an API using Client Credentials

身份服务器
托管在端口 5000

WebApi
托管在端口 5001

在我的 WebApi 的Startup.cs 文件的Configure 方法中,我做了以下操作(问题可能就在这里):

 app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://web:5000",                
            RequireHttpsMetadata = false,
            ApiName = "api1"
        });

客户
和客户

 // Everything is fine here...
 var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
 var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
 var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api");

 // This does not work
 var client = new HttpClient();
 client.SetBearerToken(tokenResponse.AccessToken);
 var response = await client.GetAsync("http://localhost:5001/identity");

问题可能出在我的 WebApi 上:

1) 如果我将权限设置为 localhost:5000,我会收到内部服务器错误:“无法从以下位置获取配置:'http://localhost:5000/.well-known/openid-configuration'”这是有道理的,因为 localhost:5000 在此容器中是未知的

2) 如果我将权限设置为http://web:5000,则会收到授权错误:“颁发者验证失败。颁发者:'http://localhost:5000'。不匹配:validationParameters.ValidIssuer:'http://web:5000'或validationParameters.ValidIssuers “这也有道理,但我不知道是否可以更改权限名称?我还尝试在 IdentityServer 项目中设置IssuerUri,但没有帮助

【问题讨论】:

标签: c# docker .net-core identityserver4


【解决方案1】:

网络

假设您有两台物理机:C1 和 C2。每台机器都是一个 docker 主机。

C1 运行 Auth 容器。

C2 运行 WebApi 容器。

当您在 Auth dockerfile 中公开端口 5000 时,地址 C1:5000 应该可以从 C2 从 WebApi 容器本身访问。你可能更喜欢IP而不是DNS,没关系。此外,您应该能够向http://C1:5000/.well-known/openid-configuration 发出成功的 GET 请求。

要实现这一点,您可能会面临很多网络问题。例如: What would prevent code running in a Docker container from connecting to a database on a separate server?

发行人验证

发行人验证失败

您客户的授权 URL 与 Auth 主机名不同。默认情况下,授权 URL 应等于 issuer 属性值(此属性在 Identity Server 自动发现文档响应中)。

issuer 属性值取决于您客户端的网络请求:

GET http://127.0.0.1:6000/.well-known/openid-configuration -> "issuer": "http://127.0.0.1:6000"
GET http://localhost:6000/.well-known/openid-configuration -> "issuer": "localhost:6000"

尝试将IssuerUri 设置为开发环境的常量:

services.AddIdentityServer(x =>
{
    x.IssuerUri = "foo";
})

实现一个常量issuer 值。这允许通过任何有效的 URL(使用 IP、机器名或 DNS)调用 Identity Server:

GET http://anything/.well-known/openid-configuration -> "issuer": "foo"

DiscoveryClient 还验证 issuer 值。这是一个简单的相等comparison

public bool ValidateIssuerName(string issuer, string authority)
{
    return string.Equals(issuer, authority, StringComparison.Ordinal);
}

您可以通过以下方式禁用它:

DiscoveryClient.Policy.ValidateIssuerName = false;

仅供参考,IssuerUri 为生产环境设置 is not recommended

IssuerUri 设置将出现在发现中的发行者名称 文档和已发行的 JWT 令牌。建议不要设置 属性,从使用的主机名推断颁发者名称 由客户提供。

【讨论】:

  • 这样做会破坏我客户端的第一部分:var disco = await DiscoveryClient.GetAsync("localhost:5000"); 得到以下异常:错误 =“发行者名称与授权不匹配:foo”`查看我的编辑了解更多信息
  • @Bidou 你确定这是正确的行吗? DiscoveryClient.GetAsync 只是执行 GET 请求并解析响应。发行者名称更改后,所有令牌都必须替换为新令牌。
  • 其实有点奇怪。如果我检查GetAsync 返回的DiscoveryResponse,我可以看到Raw 属性具有其json 响应集(例如,issuer 以及tokenendpoint 都在那里)但Error 属性包含上面提到的消息“发行者名称与权限不匹配:foo”。 TokenEndpoint 属性为 null(即使它在原始 json 中),然后发生 NullPointerException,因为下一行使用此属性来激活 TokenClient....
  • @Bidou 我的错,尝试设置DiscoveryClient.Policy.ValidateIssuerName = false;
  • 如果您想看一下,我在这里问了一个类似的问题:stackoverflow.com/questions/53468074/… +1 参考 IssueURI。
猜你喜欢
  • 2020-11-17
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2021-06-23
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多