How can I use IdentityServer4 from inside and outside a docker machine?

后端 未结 2 1038

I want to be able to authenticate against an Identity Server (STS) from outside and inside a docker machine.

I am having trouble with setting the correct authority

相关标签:
2条回答
  • 2020-12-23 10:30

    Ensure IssuerUri is set to an explicit constant. We had similar issues with accessing Identity Server instance by the IP/hostname and resolved it this way:

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

    P.S. Why don't you unify the authority URL to hostname:5000? Yes, it is possible for Client and API both call the same URL hostname:5000 if:

    • 5000 port is exposed (I see it's OK)
    • DNS is resolved inside the docker container.
    • You have access to hostname:5000 (check firewalls, network topology, etc.)

    DNS is the most tricky part. If you have any trouble with it I recommend you try reaching Identity Server by its exposed IP instead of resolving hostname.

    0 讨论(0)
  • 2020-12-23 10:43

    To make this work I needed to pass in two environment variables in the docker-compose.yml and setup CORS on the identity server instance so that the API was allowed to call it. Setting up CORS is outside the remit of this question; this question covers it well.

    Docker-Compose changes

    The identity server needs IDENTITY_ISSUER, which is name that the identity server will give itself. In this case I've used the IP of the docker host and port of the identity server.

      mcoidentityserver:
        image: mcoidentityserver
        build:
          context: ./Mco.IdentityServer
          dockerfile: Dockerfile
        environment:
          IDENTITY_ISSUER: "http://10.0.75.1:5000"
        ports:
           - 5000:5000
        networks:
         - mconetwork
    

    The API needs to know where the authority is. We can use the docker network name for the authority because the call doesn't need to go outside the docker network, the API is only calling the identity server to check the token.

      mcoapi:
        image: mcoapi
        build:
          context: ./Mco.Api
          dockerfile: Dockerfile
        environment:
          IDENTITY_AUTHORITY: "http://mcoidentityserver:5000"
        ports:
           - 56107:80
        links:
         - mcodatabase
         - mcoidentityserver
        depends_on:
         - "mcodatabase"
         - "mcoidentityserver"
        networks:
         - mconetwork
    

    Using these values in C#

    Identity Server.cs

    You set the Identity Issuer name in ConfigureServices:

        public void ConfigureServices(IServiceCollection services)
        {
            var sqlConnectionString = Configuration.GetConnectionString("DefaultConnection");
    
            services
                .AddSingleton(Configuration)
                .AddMcoCore(sqlConnectionString)
                .AddIdentityServer(x => x.IssuerUri = Configuration["IDENTITY_ISSUER"])
                .AddTemporarySigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddCorsPolicyService<InMemoryCorsPolicyService>()
                .AddAspNetIdentity<User>();
        }
    

    API Startup.cs

    We can now set the Authority to the environment variable.

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = Configuration["IDENTITY_AUTHORITY"],
            RequireHttpsMetadata = false,
            ApiName = "api1"
        });
    

    Drawbacks

    As shown here, the docker-compose would not be fit for production as the hard coded identity issuer is a local IP. Instead you would need a proper DNS entry that would map to the docker instance with the identity server running in it. To do this I would create a docker-compose override file and build production with the overridden value.

    Thanks to ilya-chumakov for his help.

    Edit

    Further to this, I have written up the entire process of building a Linux docker + ASP.NET Core 2 + OAuth with Identity Server on my blog.

    0 讨论(0)
提交回复
热议问题