Search code examples
spring-bootdockerkeycloaknetflix-zuul

Spring Boot - Unable to get response of Keycloak authorized api via Zuul proxy


I using spring boot microservices and docker for my application. I have expose all endpoint via Zuul proxy. And also I have used keycloak to secure my api endpoints. Which I configured in application.properties file as show in bellow. Currently I am unable to get the response of my microservice's api which is authorized using keycloak.securityConstraints.

Please note that I have also change subnet and gateway of docker0 to 169.254.0.1/24 and 169.254.0.1. Please find following files of my application.

docker-compose.yml without specify a subnet

version: "3"
services:
    eureka-naming-server:
        image: eureka-naming-server
        ports:
            - "8761:8761"
        container_name: eureka-naming-server
    zuul-proxy-service:
        image: zuul-proxy-service
        ports:
            - "8765:8765"
        links:
            - eureka-naming-server
        container_name: zuul-proxy-service
    user-service:
        image: user-service
        ports:
            - "8082:8082"
        links:
            - eureka-naming-server
        container_name: user-service
    keycloak:
        image: jboss/keycloak
        container_name: keycloak
        environment:
            KEYCLOAK_USER: user
            KEYCLOAK_PASSWORD: user_password
        ports:
            - 8080:8080

docker-compose.yml with a specify default subnet

version: "3"
services:
    eureka-naming-server:
        image: eureka-naming-server
        ports:
            - "8761:8761"
        container_name: eureka-naming-server
    zuul-proxy-service:
        image: zuul-proxy-service
        ports:
            - "8765:8765"
        links:
            - eureka-naming-server
        container_name: zuul-proxy-service
    user-service:
        image: user-service
        ports:
            - "8082:8082"
        links:
            - eureka-naming-server
        container_name: user-service
    keycloak:
        image: jboss/keycloak
        container_name: keycloak
        environment:
            KEYCLOAK_USER: user
            KEYCLOAK_PASSWORD: user_password
        ports:
            - 8080:8080
networks:
    default:
        ipam:
            config:
                - subnet: "169.254.3.0/24"

application.yml of Zull proxy

server:
  port: 8765

eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-naming-server:8761/eureka/
  instance:
    prefer-ip-address: true
    metadataMap:
      instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}}
    instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}}

zuul:
  prefix: /api
  sensitive-headers:
  add-proxy-headers: false
  routes:
    user-service:
      path: /user/**
      service-id: USER-SERVICE

application.yml of user-service

spring.application.name=user-service
keycloak.realm=master
keycloak.resource=my-client
keycloak.auth-server-url=http://<ip>/auth
keycloak.public-client=true
keycloak.principal-attribute=preferred_username
keycloak.securityConstraints[0].authRoles[0]=admin
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/change-password

Here is my problem

1) When I am not using zuul proxy (i.e. http//:8082/change-password) i can successfully get response using valid keycloak token. But when using http//:8765/api/user/change-password and docker-compose.yml with a specify default subnet i can not get the responce.

I always get following responce headers with 200 status for a valid token.

 cache-control: private 
 date: Wed, 21 Aug 2019 11:02:02 GMT 
 expires: Thu, 01 Jan 1970 00:00:00 GMT 
 transfer-encoding: chunked

And following log created in user-service logs.

2019-08-21 03:18:26.191  WARN [-,,,] 1 --- [nio-8087-exec-2] o.k.adapters.RequestAuthenticator        : SSL is required to authenticate. Remote address 169.254.0.4 is secure: false, SSL required for: EXTERNAL .

However when i used invalid token i am getting 401 error (As expected).

Do i need to use a route filter for this issue???

Any help would be grateful !


Solution

  • It appears that SSL is required for all external requests. This can be set e.g. via the admin console in Realm Settings -> Login -> Require SSL (https://www.keycloak.org/docs/5.0/server_admin/index.html#_ssl_modes). For testing purposes, you can try and set it to None. Never do this on a production system.

    The same thing can be done for the client (in application.yml of the user-service):

    keycloak.ssl-required = none
    

    (https://www.keycloak.org/docs/latest/securing_apps/index.html#_java_adapter_config)