我尝试使用docker配置IdentityServer4,但我无法使其工作。首先,我获取了身份服务器文档的Client Credential示例:Protecting an API using Client Credentials
IdentityServer
托管在5000港口
的WebAPI
托管在港口5001
在我的WebApi的Configure
文件的Startup.cs
方法中,我执行了以下操作(问题可能在这里):
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
,但它没有帮助
答案 0 :(得分:10)
网络强>
假设你有两台物理机器:C1和C2。每台机器都是一个泊坞主机。
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令牌。建议不要设置它 property,根据使用的主机名推断颁发者名称 由客户。