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:
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:
Thanks in advance for any hints and help!
It's working now. I added a reverse-proxy and changed the ports of the provider urls to the internal docker port.