skip to Main Content

hi i trying to learn identity server 4 . i tried a simple project with api client id4 api-gateway …. but now i try the same project with docker container. my client app at the beginning must redirect to identity server login page but throw error

SocketException: Connection refused
System.Net.Sockets.Socket+AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)

HttpRequestException: Connection refused (identityserver4:9001)
System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(string host, int port, HttpRequestMessage initialRequest, bool async, CancellationToken cancellationToken)

IOException: IDX20804: Unable to retrieve document from: 'http://identityserver4:9001/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)

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

Identiti server client configuration in Config.cs

new Client
                {
                     ClientId = "razorClient",
                     ClientName = "RAZOR Client App",
                     AllowedGrantTypes= GrantTypes.Hybrid,
                     RequirePkce = false,
                     AllowRememberConsent = false,
                     RedirectUris = new List<string>()
                     {
                         "http://clientapp:5001/signin-oidc"
                     },
                     PostLogoutRedirectUris = new List<string>()
                     {
                         "http://clientapp:5001/signout-callback-oidc"
                     },
                     ClientSecrets = new List<Secret>
                     {
                        new Secret("secret".Sha256())
                     },
                     AllowedScopes = new List<string>()
                     {
                         IdentityServerConstants.StandardScopes.OpenId,
                         IdentityServerConstants.StandardScopes.Profile,
                         "MYAPI"

                     },
                     AllowAccessTokensViaBrowser = true
                     
                }

IdentityServer program.cs

using IdentityServer;

var builder = WebApplication.CreateBuilder(args);

Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

builder.Services.AddControllersWithViews();

builder.Services.AddIdentityServer()
    .AddInMemoryClients(Config.Clients)
    .AddInMemoryIdentityResources(Config.IdentityResources)
    //.AddInMemoryApiResources(Config.ApiResources)
    .AddInMemoryApiScopes(Config.ApiScopes)
    .AddTestUsers(Config.TestUsers)
    .AddDeveloperSigningCredential();


var app = builder.Build();

if (!app.Environment.IsDevelopment())
{


    app.UseHttpsRedirection();


}



app.UseStaticFiles();
app.UseRouting();


app.UseIdentityServer();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
});

app.Run();

client app program.cs

using ClientApp.Data;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Mvc.Authorization;

var builder = WebApplication.CreateBuilder(args);

Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>(); 


builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{

    options.Authority = "http://identityserver4:9001";
    options.MetadataAddress = "http://identityserver4:9001/.well-known/openid-configuration";


    //options.Authority = "http://localhost:9001";
    //options.MetadataAddress = "http://localhost:9001/.well-known/openid-configuration";

    options.RequireHttpsMetadata = false;

    options.ClientId = "razorClient";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("MYAPI");

    options.SaveTokens = true;

    options.GetClaimsFromUserInfoEndpoint = true;

});


builder.Services.AddMvcCore(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});



var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");

    app.UseHttpsRedirection();
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();


app.UseAuthentication();
app.UseAuthorization();


app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

docker-compose.override

version: '3.4'

services:

  identityserver4:
    container_name: identityserver4
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      
    ports:
      - "9001:80"


  clientapp:
    container_name: clientapp
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "5001:80"
    depends_on:
      - identityserver4


  apiresource:
    container_name: apiresource
    environment:
      - ASPNETCORE_ENVIRONMENT=Development 
    ports:
      - "8001:80"

and this is the test project repo

EDIT: i edited the question based on simple project contains api and client and identityserver4

2

Answers


  1. Looks like a container communication issue. The Exception occurs when the OpenId handler tries to parse the response from the discovery to an object. It’s probably because the expected json is not being returned.

    System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'.
     at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
    

    Ensure you reach the discovery endpoint from your web app. You are using the url of your service available from the docker host (localhost):

    options.Authority = "http://localhost:3300";
    options.MetadataAddress = "http://localhost:3300/.well-known/openid-configuration";
    

    But you need to configure a network to communicate both containers and use the service name instead of localhost:

    gewebapp:
      container_name: gewebapp
      environment:
        - ASPNETCORE_ENVIRONMENT=Development
      depends_on:
        - identityserver
      ports:
        - "3002:80"
        - "3003:443"
      networks:
        - mynet
    
    identityserver:
      container_name: identityserver
      environment:
        - ASPNETCORE_ENVIRONMENT=Development
      ports:
        - "3300:80"
      networks:
        - mynet
    

    And in the handler configuration:

    options.Authority = "http://identityserver:3300";
    options.MetadataAddress = "http://identityserver:3300/.well-known/openid-configuration";
    
    Login or Signup to reply.
  2. You should change all urls based on the ip address of the computer where docker is running. e.g.:

    Client app:

    options.Authority = "http://192.168.8.202:9001";
    options.MetadataAddress = "http://192.168.8.202:9001/.well-known/openid-configuration";
    

    IdentityServer config:

    RedirectUris = new List<string>()
    {
        "http://192.168.8.202:5001/signin-oidc"
    },
    PostLogoutRedirectUris = new List<string>()
    {
        "http://192.168.8.202:5001/signout-callback-oidc"
    },
    

    You can find your computer’s ip address with ipconfig command in windows cmd or ifconfig in linux terminal.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search