Задать вопрос
@mxelgin

Как получить client_credential токен через прокси oauth2-proxy?

Сеть настроена через реверс-прокси traefik. Сам траефик не умеет работать с аутентификацией, для этого необходимо прокладывать oauth прокси. появилась задача внутри сети прокинуть токены в заголовки всех приложений без авторизации пользователя. Keycloak настроен и отдает токен. Проблема появилась при конфигурации oauth2-proxy, он работает как autentification_code то есть аутентификация происходит при вмешательстве пользователя, мне нужно получить токен без вмешательства пользователя, так называемый M2M обмен, токен должен быть передан как client_credentials.

Конфигурация oauth2-proxy в traefik
oauth2-cred-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
    container_name: oauth2-cred-proxy
    environment:
      OAUTH2_PROXY_LOG_LEVEL: "debug"
      OAUTH2_PROXY_PROVIDER: "oidc"
      OAUTH2_PROXY_CLIENT_ID: "@oauth2-cred-proxy"
      OAUTH2_PROXY_CLIENT_SECRET: "@secret-oauth2-cred-proxy"
      OAUTH2_PROXY_COOKIE_SECURE: "true"
      OAUTH2_PROXY_COOKIE_SECRET: "@cookie-oauth2-cred-proxy"
      OAUTH2_PROXY_COOKIE_REFRESH: "600s"
      OAUTH2_PROXY_COOKIE_SAMESITE: "none"  # Для кросс-доменных запросов
      OAUTH2_PROXY_COOKIE_DOMAINS: ".example.com"
      OAUTH2_PROXY_PASS_ACCESS_TOKEN: "true"  # Важно: разрешаем прокси передавать токен в заголовке
      OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER: "true"
      OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY: "true"
      OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: "true"
      OAUTH2_PROXY_UPSTREAMS: static://204
      OAUTH2_PROXY_EMAIL_DOMAINS: "*"
      OAUTH2_PROXY_WHITELIST_DOMAINS: ".example.com"
      OAUTH2_PROXY_SET_AUTHORIZATION_HEADER: "true"
      OAUTH2_PROXY_SET_XAUTHREQUEST: "true"
      OAUTH2_PROXY_CODE_CHALLENGE_METHOD: "S256"
      OAUTH2_PROXY_HTTP_ADDRESS: "0.0.0.0:4180"
      OAUTH2_PROXY_REVERSE_PROXY: "true"
      OAUTH2_PROXY_ALLOWED_REDIRECT_DOMAINS: ".example.com"
      OAUTH2_PROXY_SHOW_DEBUG_ON_ERROR: "true"
      # Позволяет проверять только токены без редиректа
      OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS: "false"
      OAUTH2_PROXY_OIDC_PKCE: "false"
      OAUTH2_PROXY_OIDC_ISSUER_URL: "https://keycloak.example.com/realms/example.com-realm"
      OAUTH2_PROXY_OIDC_AUTH_URL: "https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/auth"
      OAUTH2_PROXY_OIDC_TOKEN_URL: "https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/token"
      OAUTH2_PROXY_OIDC_USER_INFO_URL: "https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/userinfo"
    expose:
      - "4180"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.oauth2-cred-proxy-secure.rule=Host(`oauth.example.com`)"
      - "traefik.http.routers.oauth2-cred-proxy-secure.entrypoints=websecure"
      - "traefik.http.routers.oauth2-cred-proxy-secure.tls=true"
      - "traefik.http.routers.oauth2-cred-proxy-secure.tls.certresolver=myresolver" # генерация сертификата
      - "traefik.http.routers.oauth2-cred-proxy-secure.service=oauth2-cred-proxy-secure" 
      - "traefik.http.services.oauth2-cred-proxy-secure.loadbalancer.server.port=4180"
    networks:
      - traefik_my-network</blockquote>


конфигурация keycloak
{
  "clientId": "@oauth2-cred-proxy",
  "name": "@oauth2-cred-proxy",
  "description": "",
  "rootUrl": "",
  "adminUrl": "",
  "baseUrl": "",
  "surrogateAuthRequired": false,
  "enabled": true,
  "alwaysDisplayInConsole": false,
  "clientAuthenticatorType": "client-secret",
  "secret": "@secret-oauth2-cred-proxy",
  "redirectUris": [
    "*"
  ],
  "webOrigins": [
    "https://keycloak.example.com",
    "https://echo.example.com",
    "+"
  ],
  "notBefore": 0,
  "bearerOnly": false,
  "consentRequired": false,
  "standardFlowEnabled": true,
  "implicitFlowEnabled": true,
  "directAccessGrantsEnabled": false,
  "serviceAccountsEnabled": true,
  "authorizationServicesEnabled": true,
  "publicClient": false,
  "frontchannelLogout": true,
  "protocol": "openid-connect",
  "attributes": {
    "realm_client": "false",
    "oidc.ciba.grant.enabled": "true",
    "client.secret.creation.time": "1753858235",
    "backchannel.logout.session.required": "true",
    "standard.token.exchange.enabled": "true",
    "frontchannel.logout.session.required": "true",
    "oauth2.device.authorization.grant.enabled": "true",
    "display.on.consent.screen": "false",
    "pkce.code.challenge.method": "S256",
    "backchannel.logout.revoke.offline.tokens": "false"
  },
  "authenticationFlowBindingOverrides": {},
  "fullScopeAllowed": true,
  "nodeReRegistrationTimeout": -1,
  "defaultClientScopes": [
    "service_account",
    "web-origins",
    "acr",
    "grant_type_scope",
    "roles",
    "profile",
    "basic",
    "email"
  ],
  "optionalClientScopes": [
    "address",
    "phone",
    "organization",
    "offline_access",
    "microprofile-jwt"
  ],
  "access": {
    "view": true,
    "configure": true,
    "manage": true
  }
}


запрос токена из keycloak напрямую отдает access_token
docker run --rm curlimages/curl -i -X POST   -d "client_id=@oauth2-cred-proxy"   -d "client_secret=@secret-oauth2-cred-proxy"   -d "grant_type=client_credentials"   -d "scope=openid"  https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/token


запрос токена из keykloak через oauth2-proxy отдает заголовки без access_token
docker run --rm --network traefik_my-network curlimages/curl curl -i http://oauth2-cred-proxy:4180


root@www:~# docker run --rm --network traefik_my-network curlimages/curl curl -i http://oauth2-cred-proxy:4180
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 302 Found
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Content-Type: text/html; charset=utf-8
Expires: Thu, 01 Jan 1970 00:00:00 UTC
Location: https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/auth?approval_prompt=force&client_id=oauth2-cred-proxy&code_challenge=qldLKr4qsT_idKXnBetxkV4AeY4JBNSvWO9b7bOlX_U&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fkeycloak.example.com%2Frealms%2Fexample.com-realm%2Fprotocol%2Fopenid-connect%2Ftoken&response_type=code&scope=openid+email+profile&state=prEDLzhcPSAgcB6PYBHLzsjnLADT19ARaBotVVABHLo%3A%2F
Set-Cookie: _oauth2_proxy_csrf=Op5su9atPad2h1twvnAlzS8F1QCdCIsCvDTRvlqrZX_QH_rCObPxLO2oQ1qrqiDCH4KQB9y9EJfZQGflJt1z7RXJxdGLdbCvdGCkMQvss70K80P4PSKIB66CU_5MoCDPr-sKFSEUyVnF2MOJXHGTaaqJ9nRX9IVGbSBLTuKUwU-ExTDZWAFmPsgxcFiAU3GxZcUmCgtrpmTqH2XDcLOYeb-3_NRpxQG-1g19Gfgt5zkhSc-NmkHN6IvvCEEh8w==|1753892954|TZMWEOiw8wWGWPSJ4ty__tsYiuePhFsaKYl3fkRHjNQ=; Path=/; Domain=example.com; Expires=Wed, 30 Jul 2025 16:44:14 GMT; HttpOnly; Secure; SameSite=None
100   484  100   484    0     0  10437      0 --:--:-- --:--:-- --:--:-- 10521
X-Accel-Expires: 0
Date: Wed, 30 Jul 2025 16:29:14 GMT
Content-Length: 484

<a href="https://keycloak.example.com/realms/example.com-realm/protocol/openid-connect/auth?approval_prompt=force&amp;client_id=oauth2-cred-proxy&amp;code_challenge=qldLKr4qsT_idKXnBetxkV4AeY4JBNSvWO9b7bOlX_U&amp;code_challenge_method=S256&amp;redirect_uri=https%3A%2F%2Fkeycloak.example.com%2Frealms%2Fexample.com-realm%2Fprotocol%2Fopenid-connect%2Ftoken&amp;response_type=code&amp;scope=openid+email+profile&amp;state=prEDLzhcPSAgcB6PYBHLzsjnLADT19ARaBotVVABHLo%3A%2F">Found</a>.


Думаю, для знатоков oauth2-proxy настройка такой конфигурации должна быть простой.
  • Вопрос задан
  • 20 просмотров
Подписаться 1 Средний 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы