0

I am using this guide https://www.baeldung.com/spring-boot-keycloak. I am trying to connect my bff application to my reverse proxy, but I keep getting this error: The Issuer "http://localhost:8080/auth/realms/baeldung" provided in the configuration metadata did not match the requested issuer "http://localhost:7080/auth/realms/baeldung".

I believe I set up my keycloak configuration incorrectly. How can I fix the issue with the proxy?

I have tried changing my keycloak configurations, and the settings my reverse proxy and bff.

This is my Bff YML:

# Custom properties to ease configuration overrides
# on command-line or IDE launch configurations
scheme: http
hostname: localhost
reverse-proxy-port: 7080
reverse-proxy-uri: ${scheme}://${hostname}:${reverse-proxy-port}
authorization-server-prefix: /auth
issuer: http://localhost:7080${authorization-server-prefix}/realms/baeldung
client-id: baeldung-confidential
client-secret: secret
username-claim-json-path: $.preferred_username
authorities-json-path: $.realm_access.roles
bff-port: 7081
bff-prefix: /bff
resource-server-port: 7084
audience:

server:
  port: ${bff-port}
  ssl:
    enabled: false

spring:
  cloud:
    gateway:
      routes:
        - id: bff
          uri: ${scheme}://${hostname}:${resource-server-port}
          predicates:
            - Path=/api/**
          filters:
            - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
            - TokenRelay=
            - SaveSession
            - StripPrefix=1
  security:
    oauth2:
      client:
        provider:
          baeldung:
            issuer-uri: ${issuer}
        registration:
          baeldung:
            provider: baeldung
            authorization-grant-type: authorization_code
            client-id: ${client-id}
            client-secret: ${client-secret}
            scope: openid,profile,email,offline_access

com:
  c4-soft:
    springaddons:
      oidc:
        ops:
          - iss: ${issuer}
            authorities:
              - path: ${authorities-json-path}
            aud: ${audience}
        # SecurityFilterChain with oauth2Login() (sessions and CSRF protection enabled)
        client:
          client-uri: ${reverse-proxy-uri}${bff-prefix}
          security-matchers:
            - /api/**
            - /login/**
            - /oauth2/**
            - /logout/**
          permit-all:
            - /api/**
            - /login/**
            - /oauth2/**
            - /logout/connect/back-channel/baeldung
          post-logout-redirect-host: ${hostname}
          csrf: cookie-accessible-from-js
          oauth2-redirections:
            rp-initiated-logout: ACCEPTED
          back-channel-logout:
            enabled: true
            # internal-logout-uri: ${reverse-proxy-uri}${bff-prefix}/logout
            # should work too,  but there is no reason to go through the reverse proxy for this internal call
            internal-logout-uri: ${scheme}://localhost:${bff-port}/logout
        # SecurityFilterChain with oauth2ResourceServer() (sessions and CSRF protection disabled)
        resourceserver:
          permit-all:
            - /login-options
            - /error
            - /v3/api-docs/**
            - /swagger-ui/**
            - /actuator/health/readiness
            - /actuator/health/liveness

management:
  endpoint:
    health:
      probes:
        enabled: true
  endpoints:
    web:
      exposure:
        include: '*'
  health:
    livenessstate:
      enabled: true
    readinessstate:
      enabled: true

logging:
  level:
    root: INFO
    org:
      springframework:
        boot: INFO
        security: TRACE
        web: INFO

---
spring:
  config:
    activate:
      on-profile: ssl
server:
  ssl:
    enabled: true
scheme: https

---
spring:
  config:
    activate:
      on-profile: cognito
issuer: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_RzhmgLwjl
client-id: 12olioff63qklfe9nio746es9f
client-secret: change-me
username-claim-json-path: username
authorities-json-path: $.cognito:groups
com:
  c4-soft:
    springaddons:
      oidc:
        client:
          oauth2-logout:
            baeldung:
              uri: https://spring-addons.auth.us-west-2.amazoncognito.com/logout
              client-id-request-param: client_id
              post-logout-uri-request-param: logout_uri

---
spring:
  config:
    activate:
      on-profile: auth0
issuer: https://dev-ch4mpy.eu.auth0.com/
client-id: yWgZDRJLAksXta8BoudYfkF5kus2zv2Q
client-secret: change-me
username-claim-json-path: $['https://c4-soft.com/user']['name']
authorities-json-path: $['https://c4-soft.com/user']['roles']
audience: bff.baeldung.com
com:
  c4-soft:
    springaddons:
      oidc:
        client:
          authorization-params:
            baeldung:
              audience: ${audience}
          oauth2-logout:
            baeldung:
              uri: ${issuer}v2/logout
              client-id-request-param: client_id
              post-logout-uri-request-param: returnTo
0

1 Answer 1

1

Apparently, you are opting for the option of putting everything behind the reverse proxy. This is optional but gives more flexibility for displaying the login forms (Keycloak UI can easily be included in an iframe of the page displaying the SPA if the two share the same origin).

Even if this would result in the same value, to make this more visible in the conf, I'd change:

issuer: http://localhost:7080${authorization-server-prefix}/realms/baeldung

to:

issuer: ${reverse-proxy-uri}${authorization-server-prefix}/realms/baeldung

You did not include your Keycloak configuration in your question. My guess is that your problem is due to a misconfiguration there: as you are serving Keycloak through a reverse proxy running on http://localhost:7080, you have to set:

  • hostname-url=http://localhost:7080/auth
  • hostname-admin-url=http://localhost:7080/auth
  • hostname-strict-backchannel=true

Please note the values value using the reverse proxy instead of the socket on which the Keycloak container is exposed.

In a Docker compose file, that would be:

  keycloak:
    container_name: baeldung-bff.auth
    image: quay.io/keycloak/keycloak:24.0.0
    command:
    - start-dev
    - --import-realm
    ports:
    - 8080:8080
    volumes:
      - ./keycloak/import/:/opt/keycloak/data/import/
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
      KC_HTTP_PORT: 8080
      KC_HOSTNAME_URL: http://localhost:7080/auth
      KC_HOSTNAME_ADMIN_URL: http://localhost:7080/auth
      KC_HOSTNAME_STRICT_BACKCHANNEL: true
      KC_HTTP_RELATIVE_PATH: /auth/
      KC_HTTP_ENABLED: true
      KC_HEALTH_ENABLED: true
      KC_METRICS_ENABLED: true
      #KC_LOG_LEVEL: DEBUG
    extra_hosts:
    - "host.docker.internal:host-gateway"

Note that there were some breaking changes regarding hostname since Keycloak 24.0.0. So, if using the latest images, refer to the Keycloak documentation to set hostname, hostname-admin, and hostname-strict instead of the above.

As a side note, the build.sh from the companion project replaces the default compose file with one pointing to the reverse proxy using your hostname. So, if you had run it as instructed in section 3.2 of the tutorial, you wouldn't have had this problem ;).

Another option is to serve Keycloak with a different origin than the BFF and SPA (if you don't care about the login forms in an iframe, that's just fine), and to change your BFF and resource server configurations instead of Keycloak's one (set issuer: http://localhost:8080${authorization-server-prefix}/realms/baeldung).

At the end of the day, what is required by the OIDC discovery and OpenID token validation specifications is that all configurations and token payloads have the exact same value for the Issuer Identifier (case, scheme, hostname, port, path, trailing slash if any, etc.).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.