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
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.
Ensure you reach the discovery endpoint from your web app. You are using the url of your service available from the docker host (localhost):
But you need to configure a network to communicate both containers and use the service name instead of localhost:
And in the handler configuration:
You should change all urls based on the ip address of the computer where docker is running. e.g.:
Client app:
IdentityServer config:
You can find your computer’s ip address with
ipconfig
command in windows cmd orifconfig
in linux terminal.