I want to be able to authenticate from Identity Server (STS) outside and inside the docker machine.
I am having trouble setting up the correct authority, which works both inside and outside the container. If I set permissions on the internal name mcoidentityserver:5000 , then the API can authenticate, but the client cannot receive the token, since the client is outside the docker network. If I set the permissions on the external name localhost:5000 , then the client can get the token, but the API does not recognize the name of the permissions (since localhost is the host machine in this case).
What do I need to configure for this body? Or maybe I need to set up a docker network?
Diagram
The red arrow is the part that I'm having problems with. 
Detail
I am setting up a Windows 10 docker development environment that uses the ASP.NET Core API (on Linux), Identity Server 4 (ASP.NET Core on Linux), and the PostgreSQL database. PostgreSQL is not a problem included in the diagram for completeness. It is mapped to 9876 because at the moment I also have a PostgreSQL instance running on the host. mco is the abbreviated name of our company.
I follow the instructions for Identity Server 4 to start and start.
the code
I do not include docker-compose.debug.yml because it ran commands that were specific to working in Visual Studio.
Docker-compose.yml
version: '2' services: mcodatabase: image: mcodatabase build: context: ./Data dockerfile: Dockerfile restart: always ports: - 9876:5432 environment: POSTGRES_USER: mcodevuser POSTGRES_PASSWORD: password POSTGRES_DB: mcodev volumes: - postgresdata:/var/lib/postgresql/data networks: - mconetwork mcoidentityserver: image: mcoidentityserver build: context: ./Mco.IdentityServer dockerfile: Dockerfile ports: - 5000:5000 networks: - mconetwork mcoapi: image: mcoapi build: context: ./Mco.Api dockerfile: Dockerfile ports: - 56107:80 links: - mcodatabase depends_on: - "mcodatabase" - "mcoidentityserver" networks: - mconetwork volumes: postgresdata: networks: mconetwork: driver: bridge
Docker-compose.override.yml
This is created by the Visual Studio plugin to enter additional values.
version: '2' services: mcoapi: environment: - ASPNETCORE_ENVIRONMENT=Development ports: - "80" mcoidentityserver: environment: - ASPNETCORE_ENVIRONMENT=Development ports: - "5000"
Dockerfile API
FROM microsoft/aspnetcore:1.1 ARG source WORKDIR /app EXPOSE 80 COPY ${source:-obj/Docker/publish} . ENTRYPOINT ["dotnet", "Mco.Api.dll"]
Identity Server Dock File
FROM microsoft/aspnetcore:1.1 ARG source WORKDIR /app COPY ${source:-obj/Docker/publish} . EXPOSE 5000 ENV ASPNETCORE_URLS http://*:5000 ENTRYPOINT ["dotnet", "Mco.IdentityServer.dll"]
API Startup.cs
Where we say the API to use the identity server and set permissions.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions {
Identity Server Startup.cs
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddTemporarySigningCredential() .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } }
Identity Server Config.cs
public class Config { public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("api1", "My API") }; } public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "client",
Client
Running in a console application.
var discovery = DiscoveryClient.GetAsync("localhost:5000").Result; var tokenClient = new TokenClient(discovery.TokenEndpoint, "client", "secret"); var tokenResponse = tokenClient.RequestClientCredentialsAsync("api1").Result; if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return 1; } var client = new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken); var response = client.GetAsync("http://localhost:56107/test").Result; if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = response.Content.ReadAsStringAsync().Result; Console.WriteLine(JArray.Parse(content)); }
Thanks in advance.