Hey I am trying to set up .NET api authentication with use of keycloak. Authentication works fine when API is not inside of the container but when I run it with use of docker-compose the result is always 401. I am quite new to docker so I used the docker-compose and docker file creation with use of VisualStudio and then I tried to do it myself, but in both cases request always returned 401.
API is created with .NET 6
Docker version is 20.10.22
Keycloak version is 20.0.3
Here are some images of my basic setup:
Program.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Test.OrderApi.Settings;
var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
{
o.Authority = "http://host.docker.internal:8080/realms/test";
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
o.RequireHttpsMetadata = false;
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Dockerfile for the API
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["tests/TestDummyMicroservices/Test.Order.Api/Test.OrderApi.csproj", "tests/TestDummyMicroservices/Test.Order.Api/"]
RUN dotnet restore "tests/TestDummyMicroservices/Test.Order.Api/Test.OrderApi.csproj"
COPY . .
WORKDIR "/src/tests/TestDummyMicroservices/Test.Order.Api"
RUN dotnet build "Test.OrderApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Test.OrderApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Test.OrderApi.dll"]
docker-compose
version: '3.4'
services:
test.orderapi:
container_name: order-api
image: ${DOCKER_REGISTRY-}testorderapi
build:
context: .
dockerfile: tests/TestDummyMicroservices/Test.Order.Api/Dockerfile
networks:
- keycloak_network
postgres_keycloak:
container_name: postgres-keycloak
image: postgres:14.6
command: postgres -c 'max_connections=200'
volumes:
- pgdata_keycloak:/var/lib/postgressql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
healthcheck:
test: "exit 0"
ports:
- "5436:5432"
networks:
- keycloak_network
keycloak:
container_name: keycloak
image: quay.io/keycloak/keycloak:20.0.3
command: start-dev
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres_keycloak
KC_DB_URL_DATABASE: keycloak
KC_DB_PASSWORD: password
KC_DB_USERNAME: keycloak
KC_DB_SCHEMA: public
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KEYCLOAK_FRONTEND_URL: test.orderapi
links:
- test.orderapi
depends_on:
postgres_keycloak:
condition: service_healthy
ports:
- "8080:8080"
networks:
- keycloak_network
volumes:
pgdata_keycloak:
networks:
keycloak_network:
driver: bridge
docker-compose.override
version: '3.4'
services:
test.orderapi:
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "80"
test.gateway:
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "80"
How it looks inside of docker
Result of sending request
If you need any more information please let me know
I try to authenticate .NET web API with use of Keycloak
2
Answers
Ok I figured this one out you have to add ValidIssuers where you specify host.docker.internal and localhost so then authentication can see them
So I added KeyckloakSettings class which takes configuration:
Added settings to the config
Then added new array of TokenValidationParameters.ValidIssuers to the JwtBearer in Program.cs
Your application runs on posts 5201 (http) and 7201 (https).
In your docker compose file you need to forward the proper ports for http/https
And also set keycloack in the same port in docker or adapt your connection strings to use new port (5436)