springdockerspring-securitykeycloakconnectionexception

Java.net.ConnectException: Keycloak's Client gets Connection refused on Docker while Auth routing


If I have a Keycloak server running in local docker desktop and a client application running locally (non dockerized scenario), It works fine.

If I have Keycloak server and a client application running in local docker desktop, It throws

Caused by: java.net.ConnectException: Connection refused (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
        at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
        at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.base/java.net.Socket.connect(Socket.java:609)
        at com.mysql.jdbc@8.0.22//com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
        at com.mysql.jdbc@8.0.22//com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63)
        ... 64 more

If I run my client application in a local (non-dockerized) environment and pointing to a dockerized keycloak server of the cloud instance, I get the following error.

2022-02-18 12:59:55.039  WARN 1192 --- [nio-8080-exec-7] o.keycloak.adapters.KeycloakDeployment   : Failed to load URLs from http://XXXX.CLOUD.XXXX:8180/auth/realms/SampleKeycloakApp/.well-known/openid-configuration


java.lang.Exception: Forbidden
        at org.keycloak.adapters.KeycloakDeployment.getOidcConfiguration(KeycloakDeployment.java:233) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.KeycloakDeployment.resolveUrls(KeycloakDeployment.java:182) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.KeycloakDeployment.getAuthUrl(KeycloakDeployment.java:251) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.OAuthRequestAuthenticator.getRedirectUri(OAuthRequestAuthenticator.java:175) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.OAuthRequestAuthenticator.loginRedirect(OAuthRequestAuthenticator.java:213) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:275) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:138) ~[keycloak-adapter-core-16.1.1.jar!/:16.1.1]
        at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:154) ~[keycloak-spring-security-adapter-16.1.1.jar!/:16.1.1]
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96) ~[keycloak-spring-security-adapter-16.1.1.jar!/:16.1.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.1.10.RELEASE.jar!/:5.1.10.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.1.10.RELEASE.jar!/:5.1.10.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]

Sharing the docker-compose file for reference here when I run the both services in docker.

version: "3"

services:   springboot:
    build: .
    container_name: springboot
    ports:
      - 8081:8081
    restart: always
    depends_on:
      - db
      - keycloak
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/todolist
      SPRING_DATASOURCE_USERNAME: admin
      SPRING_DATASOURCE_PASSWORD: admin
      KEYCLOAK_URI: https://keycloak:8443/auth
      REALM: SpringBootKeycloakApp
    networks:
      - common-network    keycloak:
    image: jboss/keycloak:14.0.0
    container_name: keycloak
    ports:
      - "8180:8180"
      - "8443:8443"
    command: ["-Djboss.socket.binding.port-offset=100"]
    environment:
      DB_VENDOR: POSTGRES
      DB_ADDR: postgres
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
      DB_SCHEMA: public
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: admin
    depends_on:
      - postgres
    networks:
      - common-network   db:
    image: mysql:5.7
    ports:
      - "3307:3306"
    restart: always
    environment:
      MYSQL_DATABASE: todolist
      MYSQL_USER: admin
      MYSQL_PASSWORD: admin
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - common-network   postgres:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: password
    networks:
      - common-network networks:   common-network:
    driver: bridge 
    volumes:   
      db-data:
        driver: local   
      postgres_data:
        driver: local

and when I run the client app separately in non-docker env, I run it with java -jar ClientApp.jar

and when I run the client app separately in docker env, I use the following Dockerfile

FROM adoptopenjdk/openjdk11:latest
ARG JAR_FILE=./build/libs/*.jar
COPY ${JAR_FILE} ClientApp.jar
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "ClientApp.jar"]

I would be happy to understand the real root cause behind this and run the keycloak server and the client application in a dockerized cloud instance without any issues. Thx.


Solution

  • If you use both keycloak server and the client in Cloud, use ssl-required=none

      keycloak.ssl-required=none
    

    If you use both keycloak server and the client in localhost, use ssl-required=external

    keycloak.ssl-required=external