'Spring Security 5 OAuth2 App with Keycloack 17 gets "Connection Refused" when run in Docker container with docker-compose
I have a super simple Spring Boot app with Spring Security 5 that authenticates over OAuth2 with a Keycloak 17 instance running in Docker.
Everything works fine when I start the app locally from Intellij.
But when I run the app from a Docker container with docker-compose I get:
[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for "http://localhost:80/realms/Demo/protocol/openid-connect/token": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
when I input the credentials on the keycloak login page. But there is a session created for that user in keycloak.
System:
- MacBook with Monteray 12.0.1
- Docker Desktop 4.5 with Kubernetes 1.22.5
docker-compose.yml
version: '3.9'
networks:
network_keycloak_postgres_app:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
volumes:
keycloak_postgres_data:
driver: local
services:
postgres:
container_name: postgres
image: postgres
volumes:
- keycloak_postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak_db_admin
POSTGRES_PASSWORD: keycloak_db_password
ports:
- "5432:5432"
networks:
- network_keycloak_postgres_app
keycloak:
container_name: keycloak
hostname: keycloak
image: quay.io/keycloak/keycloak:17.0.0
command: ["start-dev", "--log-level=debug"]
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: change_me
KC_DB: postgres
KC_DB_USERNAME: keycloak_db_admin
KC_CACHE: local
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_PASSWORD: keycloak_db_password
ports:
- "80:8080"
- "443:8443"
depends_on:
- postgres
networks:
- network_keycloak_postgres_app
demo_app:
container_name: demo_app
hostname: demoapp
build:
context: ../
dockerfile: Dockerfile
environment:
SPRING_PROFILES_ACTIVE: default
ports:
- "4242:4242"
depends_on:
- keycloak
networks:
- network_keycloak_postgres_app
Dockerfile (made sure to run 'mvn clean package' before build)
FROM openjdk:11.0.11-jre-slim
COPY ./target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 4242
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
application.yml
server:
port: 4242
logging:
level:
root: DEBUG
org.springframework.web: DEBUG
org.springframework.security: DEBUG
# org.springframework.boot.autoconfigure: DEBUG
spring:
thymeleaf:
cache: false
security:
oauth2:
client:
registration:
keycloak:
client-id: demo-app
client-secret: 5cuxTUgiLJATP4pMpw7j8HZieekdOBsM
client-name: Keycloak
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
scope:
- openid
- profile
- email
provider:
keycloak:
authorization-uri: http://localhost:80/realms/Demo/protocol/openid-connect/auth
token-uri: http://localhost:80/realms/Demo/protocol/openid-connect/token
user-info-uri: http://localhost:80/realms/Demo/protocol/openid-connect/userinfo
jwk-set-uri: http://localhost:80/realms/Demo/protocol/openid-connect/certs
user-name-attribute: preferred_username
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.kressing</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Spring Security 5 OAuth2 Client and Keycloak sample</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
What I have already tried:
- giving the app and keycloak container hostnames
- running the app container in another docker-compose
- using "http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:8080" instead of localhost
- using other openjdk image to build from
Thanks in advance for any hints and help!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
