IdentityServer4-与docker-compose不同的行为与手动运行不同 [英] IdentityServer4 - Different behavior from docker-compose than manual run

查看:129
本文介绍了IdentityServer4-与docker-compose不同的行为与手动运行不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.net core 3.1中有三个不同的项目:

I have three different projects in .net core 3.1 :

  • STS
  • 管理界面
  • 管理API

我有一个按项目创建的dockerfile,可以很好地构建我的映像.

I have a dockerfile by project which are building my images well.

如果我使用这些命令手动运行容器,一切正常:

If I run my containers manually with these commands everything is ok :

docker run -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=http://+:80" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -p 5001:80 stsidentity:latest
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=http://+:80" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -p 5003:80 adminapi:latest
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=http://+:80" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -p 9001:80 admin:latest

我的下一步是创建一个docker-compose使其自动化,但是我遇到了一些问题.

My next step was to create a docker-compose to automatized it but I have some issues.

从Visual Studio中,当我执行以下docker-compose时,容器sts和api运行良好.当我尝试访问管理界面时,出现错误"InvalidOperationException:IDX20803:无法从以下位置获取配置:http://localhost:5001/.well-known/openid-configuration".

From Visual Studio, when I execute the docker-compose below, containers sts and api are working well. When I try to access my Admin UI I have an error "InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://localhost:5001/.well-known/openid-configuration'."

如果我手动在浏览器中复制/粘贴该网址,则可以正常访问它.

If manually I copy/paste that Url in my browser I can access it normally.

我不明白为什么docker-compose和我从同一张图片手动运行容器时会有不同的行为.

I don't understand why a different behavior between the docker-compose and when I run containers manually from the same images.

version: "3.4"

services:
  admin:
     image: ${DOCKER_REGISTRY-}admin:latest
     ports:
       - "9001:80"
     build:
       context: .
       dockerfile: src/IdentityServer/Admin/Dockerfile
     container_name: IS4-admin
     environment:
       - ASPNETCORE_ENVIRONMENT=Development
       - ASPNETCORE_URLS=http://+:80
       - DOTNET_USE_POLLING_FILE_WATCHER=1
     depends_on:
      - sts.identity
      - admin.api

  admin.api:
    image: ${DOCKER_REGISTRY-}admin-api:latest
    ports:
      - "5003:80"
    build:
      context: .
      dockerfile: src/IdentityServer/Admin.Api/Dockerfile
    container_name: IS4-admin-api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - DOTNET_USE_POLLING_FILE_WATCHER=1
    depends_on:
      - sts.identity

  sts.identity:
    image: ${DOCKER_REGISTRY-}sts-identity:latest
    ports:
      - "5001:80"
    build:
      context: .
      dockerfile: src/IdentityServer/STS.Identity/Dockerfile
    container_name: IS4-sts-identity
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - DOTNET_USE_POLLING_FILE_WATCHER=1

这可能很明显,但我看不到.

It's probably something obvious but I don't see it.

-

-编辑

-

我读到它可能是与本地主机有关的问题.因此,我尝试使用Traefik容器作为反向代理,最后我遇到了同样的问题.

I read it was a problem possibly related to localhost. So I tried to use a Traefik container as a reverse proxy and at the end I have the same issue.

我开始认为我的问题可能与容器无关,而仅仅是在与我在IISExpress上的本地主机不同的地方执行它的事实.

I'm starting to think that my problem is maybe not related to containers but just with the fact to execute it in something different than my localhost on IISExpress.

从我在IdentityServer4上阅读的内容来看,它可能来自证书问题.我想我将所有内容都放在HTTP中,但我不明白为什么我在HTTP中会遇到问题.

From what I read on IdentityServer4 it could come from a problem with a certificate. I think I put everything in HTTP and I don't understand why I would have a problem with it in HTTP.

我成功获得了更详细的错误消息:

I succeed to obtain a more detailed error message :

IOException: IDX20807: Unable to retrieve document from: 'http://login.traefik.me/.well-known/openid-configuration'. HttpResponseMessage: 'StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Date: Wed, 08 Jul 2020 13:21:07 GMT
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SameOrigin
Referrer-Policy: no-referrer
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/ https://fonts.gstatic.com/;font-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/
Content-Length: 0
}', HttpResponseMessage.Content: ''.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)

InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://login.traefik.me/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.ConfigurationManager<T>.GetConfigurationAsync(CancellationToken cancel)

预先感谢

祝你有美好的一天

推荐答案

这与我从Docker Compose解决方案中获得的完全相同.

This is exactly the same than the one I was getting with my Docker Compose solution.

这是该解决方案的简化概述:

Here is a simplified overview of the solution:

  • Api
  • 管理员
  • IdentityServer4
  • 特拉菲克

我配置Traefik将"api.localhost"上的请求转发到Api容器,将"admin.localhost"上的请求转发到Admin容器,并将对"identity.localhost"的请求转发到IdentityServer4容器.

I configured Traefik to forward requests on 'api.localhost' to the Api container, requests on 'admin.localhost' to be forwarded to the Admin container and request to 'identity.localhost' to be forwarded to the IdentityServer4 container.

像您一样,对"api.localhost","admin.localhost"和"identity.localhost"的请求在浏览器中都可以正常工作.

Like you, request on both 'api.localhost', 'admin.localhost' and 'identity.localhost' are working fine in a browser.

当我尝试登录Api或Admin容器时出现问题,因为容器间的通信不是由Traefik处理的.此外,诸如"* .localhost"之类的DNS是在容器本身中处理的,因为它是环回DNS,因此无法按应有的方式进行解析.

The problem appears when I try to login on the Api or the Admin containers, because inter-container communication are not handled by Traefik. Furthermore, DNS such as '*.localhost' are handled in the container itself, for it is a loopback DNS, and is therefore not resolved as it should.

我的使其达到预期效果的解决方案如下:

My solution to make it work as expected is the following:

步骤1:在docker-compose文件中创建一个新网络.创建该网络是为了添加您自己的子网,并因此为您的Traefik容器指定一个静态IP.

STEP 1: Create a new network in your docker-compose file. That network is created to add your own subnet, and therefore specify a static IP for your Traefik container.

networks:
  traefik:
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/16 #replace by your desired subnet

步骤2:配置Traefik容器的静态IP地址:

STEP 2: Configure the Traefik container's static IP address:

networks:
  default: #required to talk to containers
  traefik:
    ipv4_address: 127.30.1.1 #can be any address compatible with the subnet defined at step 1

步骤3:将新创建的网络添加到所有依赖IdentityServer4的容器中,不要忘记也添加默认"网络.此外,我们将按照Traefik中的配置,创建与IdentityServer4容器的DNS对应的额外主机.这些额外的主机将指向Traefik容器的静态IP地址.

STEP 3: Add the newly created network to all the containers that rely on IdentityServer4, and do not forget to add the 'default' network too. We will, in addition, create extra hosts corresponding to the DNS of our IdentityServer4 container, as configured in Traefik. Those additional hosts will point to the static IP address of the Traefik container.

admin:
  image: ...
  environment: ...
  labels: ...
  networks:
    traefik:
    default:
  extra_hosts:
    - "identity.localhost: 127.30.1.1 #replace by the configured traefik static address

这时,如果Admin容器尝试解析"identity.localhost" DNS,它将被转发到Traefik,后者又将重定向到IdentityServer4容器:yaaai!

At this point, if the Admin container tries to resolve the 'identity.localhost' DNS, it will be forwarded to Traefik, which in turn will redirect to the IdentityServer4 container: yaaai!

但是,如果您对其进行测试,则仍然会遇到一些与HTTPS相关的问题(强烈建议您启用和配置)

If you test it out, however, you will still run in a couple of issues, all related to HTTPS (which I strongly recommend you enable and configure)

这些问题是:

  1. 您的容器可能不信任您在Traefik中配置的SSL证书.如果是这样,请确保在容器的"/etc/ssl/certs"目录中添加根CA(如果使用自签名证书).

为此,您必须装入一个卷,如以下示例所示:

To do so, you have to mount a volume, such as in the following example:

admin:
  image: ...
  environment: ...
  labels: ...
  networks:
    traefik:
    default:
  extra_hosts:
    - "identity.localhost: 127.30.1.1
  volumes:
    - "./localPathToMyCACertificateFiles/:/etc/ssl/certs/"
  

  1. 当Admin或Api容器尝试在IdentityServer上检索众所周知的配置时,它可能会抱怨配置端点位于http而不是https中.要解决此问题,您将需要为IdentityServer4容器和所有依赖它的容器配置转发的标头.检查如果您不知道该怎么做.重要的一点是确保将" RequireHeaderSymmetry "设置为false.
  1. When Admin or Api containers will try to retrieve the well known configuration on the IdentityServer, it will probably complain that configuration endpoints are in http, instead of https. To fix this issue, you will need to configure forwarded headers for the IdentityServer4 containers and all containers relying on it. Check this out if you don't know how to do so. An important point is to make sure that 'RequireHeaderSymmetry' is set to false.

这应该可以解决问题.

这篇关于IdentityServer4-与docker-compose不同的行为与手动运行不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆