如何使用 mod_auth_openidc 将用户的声明传递给上游层?

How to pass user's claim to upstream layer using mod_auth_openidc?

我已经使用 Auth0 和 Google App Oauth 使用 mod_auth_openidc 成功配置了 apache 网络服务器来保护我们的内部仪表板,如本文档中所述: - https://github.com/zmartzone/mod_auth_openidc#openid-connect-sso-with-google-sign-in - https://auth0.com/docs/quickstart/webapp/apache/01-login(不使用 auth0 规则管道)

我的问题是如何将用户的声明作为httpheader传递给上游层(我们内部tools/dashboards)?可能吗?

此致, 阿贡

已更新

我已经尝试过 的建议, 这是我的 /etc/apache2/sites-available/000-default.conf

的片段
<VirtualHost *:443>
ServerName my-host-name
UseCanonicalName on
ProxyPreserveHost on
DocumentRoot /var/www/html


# Pass the user's claim as http headers
OIDCPassClaimsAs "headers"
OIDCPassUserInfoAs "claims"
OIDCPassRefreshToken "On"
<Location />
  AuthType openid-connect

  <RequireAll>
    Require claim email~^(.*)@domain.com$
    Require claim email_verified:true
  </RequireAll>


  ProxyPass http://echo-server.default.svc.cluster.local:8080/
  ProxyPassReverse http://echo-server.default.svc.cluster.local:8080/
  LogLevel debug

</Location>
</VirtualHost>

我正在使用 echoserver (gcr.io/google_containers/echoserver:1.0) 作为 http://echo-server.default.svc.cluster.local:8080 的后端,它不会将任何用户声明打印为 http headers。我的配置有误吗?如何调试这个问题?

这就是模块默认执行的操作:它将传递用户在环境变量和 headers 中的声明,可以使用 OIDCPassClaimsAs 进行配置,如下所述: https://github.com/zmartzone/mod_auth_openidc/blob/v2.3.8/auth_openidc.conf#L668

# Define the way in which the claims and tokens are passed to the application environment:
# "none": no claims/tokens are passed
# "environment": claims/tokens are passed as environment variables
# "headers": claims/tokens are passed in headers (also useful in reverse proxy scenario's)
# "both": claims/tokens are passed as both headers as well as environment variables (default)
# When not defined the default is "both"
# The access token is passed in OIDC_access_token; the access token expiry is passed in OIDC_access_token_expires.
# The refresh token is only passed in OIDC_refresh_token if enabled for that specific directory/location (see: OIDCPassRefreshToken)
#OIDCPassClaimsAs [none|headers|environment|both]

请注意,这些 headers 已添加到传播到应用程序的后端 HTTP 请求中,因此您不会在浏览器中看到它们。

我正在使用 docker 映像 httpd:2.4-buster,安装 libapache2-mod-auth-openidc 来自 Debian 软件包仓库的 2.3.10 版本,并代理对 sub-location(不是/)。我通过将 LogLevel auth_openidc:debug 添加到 httpd.conf 来打开调试,然后我看到了 set-header 和 set-env 要求索赔的痕迹。但是使用上面的设置,我无法观察到任何 OIDC-set headers 到达代理 Python Flask WSGI 应用程序。

我的解决方法是将环境变量转换为 headers。我在 <Location> 块中为 REST API 路径添加了以下配置行,它位于 Apache HTTPD 配置的 <VirtualHost> 块中:

    # module sets REMOTE_USER as env var
    RequestHeader set X-Forwarded-User-Email %{REMOTE_USER}s

    # module sets OIDC_CLAIM_sub as env var
    PassEnv OIDC_CLAIM_sub
    RequestHeader set X-Forwarded-User %{OIDC_CLAIM_sub}e

然后应用程序获取用户名和完全合格的 user@host.domain 作为请求 headers。

更新:通过@https://github.com/zmartzone/mod_auth_openidc/discussions/705

的讨论得到@hans-z的进一步帮助

那个讨论告诉我 WSGI http 服务器会默默地删除名称中包含下划线的所有 headers!另一种解决方案(而不是将环境变量转换为 headers)是在 httpd.conf 文件中像这样更改 mod-auth-openidc 前缀字符串:

OIDCClaimPrefix Oidc-Claim-

然后 mod-auth-openidc 设置的所有 headers 在进入代理 Flask + WSGI 应用程序的过程中幸存下来。