Search code examples
javareactjsspringdockerkeycloak

Keycloak Invalid token issuer in docker


I have problem with keycloak. So, I have spring-microservices with keycloak. If it start in locally, then good work. But if I start spring and keycloak in docker, then i have problem with security. I get 401 error: (Bearer realm="bingo", error="invalid_token", error_description="Invalid token issuer. Expected 'http://keycloak:8080/realms/bingo', but was 'http://localhost:8090/realms/bingo'"). I dont understand, how I can send request to localhost keycloak:8080. Help me, please.

Application.properties in spring-app:

keycloak.auth-server-url=http://keycloak:8080
keycloak.realm=bingo
keycloak.resource=user
keycloak.ssl-required=external
keycloak.public-client=true
keycloak.bearer-only=true
keycloak.use-resource-role-mappings=true
keycloak_auth.password=FXpJokhP8ACMo9h53Hl6NSJXHSk395YG

My docker-compose for keycloak:

  keycloak:
    container_name: 'keycloak'
    image: quay.io/keycloak/keycloak:18.0
    environment:
      DB_VENDOR: POSTGRES
      DB_ADDR: kc_postgres
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_SCHEMA: public
      DB_PASSWORD: password
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - '8090:8080'
    depends_on:
      - kc_postgres
    command: start-dev
    networks:
      - spring
      - kc_postgres

So, i get token from react-app. My file for configure keyclaok - keycloak.json:

{
  "realm": "bingo",
  "auth-server-url": "http://localhost:8090/",
  "ssl-required": "external",
  "resource": "user",
  "public-client": true,
  "credentials": {
    "secret": "FXpJokhP8ACMo9h53Hl6NSJXHSk395YG"
  }
}

const keycloak = new Keycloak("keycloak.json");


Solution

  • You need to have the same Keycloak server url between applications.
    The problem is that you are running the Spring application in the same network as Keycloak (using keycloak:8080 to access it) while the React app is using localhost:8090.

    If you try to run the Spring app locally with

    keycloak.auth-server-url=http://localhost:8090
    

    it should work.

    To run the Spring application in the docker-compose file, you can try with this configuration

    keycloak:
        container_name: 'keycloak'
        image: quay.io/keycloak/keycloak:18.0
        environment:
          DB_VENDOR: POSTGRES
          DB_ADDR: kc_postgres
          DB_DATABASE: keycloak
          DB_USER: keycloak
          DB_SCHEMA: public
          DB_PASSWORD: password
          KEYCLOAK_ADMIN: admin
          KEYCLOAK_ADMIN_PASSWORD: admin
          KC_HTTP_PORT: 8090
        ports:
          - '8090:8090'
        depends_on:
          - kc_postgres
        command: start-dev
        networks:
          - spring
          - kc_postgres
    

    then change the Spring property

    keycloak.auth-server-url=http://keycloak:8090
    

    and React property

    auth-server-url": "http://keycloak:8090/",
    

    and finally set 127.0.0.1 keycloak in your /etc/hosts file (Linux) or C:\Windows\System32\drivers\etc\hosts (Windows) so it can be resolved by the React app.

    The best thing to do however is to define a DNS entry for Keycloak and then set KC_HOSTNAME and KC_HOSTNAME_PORT to the Keycloak external address.