Skip to content

Conversation

@joshuaNathaniel
Copy link

@joshuaNathaniel joshuaNathaniel commented Nov 29, 2025

What changes did you make? (Give an overview)

This PR adds OAuth2 proxy support by configuring the OAuth2 WebClient to respect JVM system proxy properties. The implementation is minimal and uses Reactor Netty's built-in proxyWithSystemProperties() method.

Key changes:

  • Modified OAuthSecurityConfig to configure OAuth2 WebClient with system proxy support
  • Uses standard JVM proxy properties (-Dhttps.proxyHost, -Dhttps.proxyPort, etc.)
  • No custom configuration required - works automatically when system properties are set
  • Fully backward compatible - no proxy used when properties aren't set

Is there anything you'd like reviewers to focus on?

The implementation is intentionally minimal - just 4 lines of actual code that leverage Reactor Netty's built-in proxy support.

How Has This Been Tested? (put an "x" (case-sensitive!) next to an item)

  • Integration
  • Manually

Checklist (put an "x" (case-sensitive!) next to all the items, otherwise the build will fail)

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings (e.g. Sonar is happy)
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged

Check out Contributing and Code of Conduct

A picture of a cute animal (not mandatory but encouraged)
🦦

Fixes kafbat#196

- Add SimpleOAuthProxyConfig to handle proxy configuration for OAuth2
- Support both system proxy properties and explicit proxy configuration
- Wire proxy-aware WebClient into OAuth2 user services
- Add unit tests following repository patterns

OAuth2 authentication now respects proxy settings when enabled, allowing
Kafbat UI to work behind corporate firewalls. The feature is disabled by
default to maintain backward compatibility.
@joshuaNathaniel joshuaNathaniel requested a review from a team as a code owner November 29, 2025 04:07
@kapybro kapybro bot added status/triage Issues pending maintainers triage status/triage/manual Manual triage in progress status/triage/completed Automatic triage completed and removed status/triage Issues pending maintainers triage labels Nov 29, 2025
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi joshuaNathaniel! 👋

Welcome, and thank you for opening your first PR in the repo!

Please wait for triaging by our maintainers.

Please take a look at our contributing guide.

@Haarolean Haarolean requested a review from Copilot December 1, 2025 07:57
Copilot finished reviewing on behalf of Haarolean December 1, 2025 07:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds OAuth2 proxy support to Kafka UI, allowing authentication requests to be routed through an HTTP proxy. This is particularly useful for environments where direct internet access is restricted.

Key changes:

  • Added SimpleOAuthProxyConfig class for configuring OAuth2 proxy settings with explicit or system proxy properties
  • Integrated proxy-configured WebClient into OAuthSecurityConfig for OAuth2 user services
  • Provided unit and integration tests for the proxy configuration

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
api/src/main/java/io/kafbat/ui/config/auth/SimpleOAuthProxyConfig.java Implements OAuth2 proxy configuration with support for explicit proxy settings or system properties
api/src/main/java/io/kafbat/ui/config/auth/OAuthSecurityConfig.java Integrates proxy-enabled WebClient into OAuth2 user services for both OIDC and standard OAuth2 flows
api/src/test/java/io/kafbat/ui/config/auth/SimpleOAuthProxyConfigTest.java Unit tests validating proxy properties configuration and WebClient creation
api/src/test/java/io/kafbat/ui/config/auth/SimpleOAuthProxyConfigIntegrationTest.java Integration tests attempting to validate proxy behavior, though tests expect failures due to test infrastructure limitations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Simplify OAuth2 authentication to automatically respect JVM proxy settings
(e.g., -Dhttps.proxyHost, -Dhttps.proxyPort). The implementation uses Reactor
Netty's built-in proxyWithSystemProperties() method, which gracefully handles
both proxy and non-proxy scenarios without additional configuration.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Add proxy-aware WebClient configuration for JWT decoder, opaque token
introspection, and OIDC authentication manager. All OAuth2 HTTP calls
now respect JVM system proxy properties.

- Add ReactiveJwtDecoder bean with proxy-aware JWKS fetching
- Add ReactiveOpaqueTokenIntrospector bean with proxy support
- Add ReactiveOAuth2AccessTokenResponseClient for token endpoint
- Configure OidcAuthorizationCodeReactiveAuthenticationManager
- Add WireMock integration tests for with/without proxy scenarios
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@joshuaNathaniel
Copy link
Author

I've setup a manual testing environment with docker compose that sets up kafka-ui, keycloak, and mitmproxy. I've validated that everything is working through the proxy.

services:

  # Keycloak - real OAuth2/OIDC provider
  keycloak:
    image: quay.io/keycloak/keycloak:24.0.5
    container_name: keycloak
    ports:
      - "8090:8080"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_HOSTNAME: localhost
      KC_HOSTNAME_PORT: 8090
      KC_HOSTNAME_STRICT_BACKCHANNEL: true
      KC_HTTP_ENABLED: true
    command:
      - start-dev
      - --import-realm
    volumes:
      - ./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json:ro

  # mitmproxy - transparent proxy that logs all HTTP requests
  mitmproxy:
    image: mitmproxy/mitmproxy:latest
    container_name: mitmproxy
    ports:
      - "3128:8080"
      - "8081:8081"
    environment:
      PYTHONUNBUFFERED: 1
    command: mitmdump --mode regular@8080 --set ssl_insecure=true --showhost -v

  kafka:
    image: confluentinc/cp-kafka:7.8.0
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT'
      KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092'
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_PROCESS_ROLES: 'broker,controller'
      KAFKA_NODE_ID: 1
      KAFKA_CONTROLLER_QUORUM_VOTERS: '1@kafka:29093'
      KAFKA_LISTENERS: 'PLAINTEXT://kafka:29092,CONTROLLER://kafka:29093,PLAINTEXT_HOST://0.0.0.0:9092'
      KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
      KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
      KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
      CLUSTER_ID: 'MkU3OEVBNTcwNTJENDM2Qk'

  kafbat-ui:
    container_name: kafbat-ui
    build:
      context: ../../../api
      dockerfile: Dockerfile
      args:
        JAR_FILE: build/libs/api-0.0.1-SNAPSHOT.jar
    ports:
      - "8080:8080"
    depends_on:
      kafka:
        condition: service_started
      mitmproxy:
        condition: service_started
      keycloak:
        condition: service_started
    environment:
      # Kafka config
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092

      # OAuth2 config pointing to Keycloak
      # Use internal hostname for server-to-server, but browser redirects use localhost via Keycloak's KC_HOSTNAME
      AUTH_TYPE: OAUTH2
      AUTH_OAUTH2_CLIENT_KEYCLOAK_PROVIDER: custom
      AUTH_OAUTH2_CLIENT_KEYCLOAK_CLIENTID: kafka-ui
      AUTH_OAUTH2_CLIENT_KEYCLOAK_CLIENTSECRET: kafka-ui-secret
      AUTH_OAUTH2_CLIENT_KEYCLOAK_SCOPE: openid
      AUTH_OAUTH2_CLIENT_KEYCLOAK_AUTHORIZATIONGRANTTYPE: authorization_code
      AUTH_OAUTH2_CLIENT_KEYCLOAK_AUTHORIZATIONURI: http://localhost:8090/realms/kafka-ui/protocol/openid-connect/auth
      AUTH_OAUTH2_CLIENT_KEYCLOAK_TOKENURI: http://keycloak:8080/realms/kafka-ui/protocol/openid-connect/token
      AUTH_OAUTH2_CLIENT_KEYCLOAK_JWKSETURI: http://keycloak:8080/realms/kafka-ui/protocol/openid-connect/certs
      AUTH_OAUTH2_CLIENT_KEYCLOAK_USERNAMEATTRIBUTE: preferred_username
      AUTH_OAUTH2_CLIENT_KEYCLOAK_CLIENTNAME: Keycloak
      AUTH_OAUTH2_CLIENT_KEYCLOAK_REDIRECTURI: http://localhost:8080/login/oauth2/code/keycloak
      AUTH_OAUTH2_CLIENT_KEYCLOAK_USERINFOURI: http://keycloak:8080/realms/kafka-ui/protocol/openid-connect/userinfo
      AUTH_OAUTH2_CLIENT_KEYCLOAK_LOGOUTURI: http://localhost:8090/realms/kafka-ui/protocol/openid-connect/logout

      # Resource server config (pick one - JWT or Opaque Token)
      # Option 1: JWT validation via JWKS endpoint (default)
      AUTH_OAUTH2_RESOURCESERVER_JWT_JWKSETURI: http://keycloak:8080/realms/kafka-ui/protocol/openid-connect/certs
      # Option 2: Opaque token introspection (uncomment below, comment out JWT above)
      # AUTH_OAUTH2_RESOURCESERVER_OPAQUETOKEN_INTROSPECTIONURI: http://keycloak:8080/realms/kafka-ui/protocol/openid-connect/token/introspect
      # AUTH_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENTID: kafka-ui
      # AUTH_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENTSECRET: kafka-ui-secret

      # Proxy config via JVM system properties
      # Use mitmproxy to see all individual HTTP requests
      JAVA_OPTS: >-
        -Dhttp.proxyHost=mitmproxy
        -Dhttp.proxyPort=8080
        -Dhttp.nonProxyHosts=

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@joshuaNathaniel
Copy link
Author

joshuaNathaniel commented Dec 3, 2025

I believe there my be a flaky pre-existing test here: https://github.com/kafbat/kafka-ui/actions/runs/19882548937/job/56983401628?pr=1540

edit: yup, looks like it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/triage/completed Automatic triage completed status/triage/manual Manual triage in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants