在 Keycloak 中从上游读取响应标头时,上游发送了太大的标头

Cec*_*uez 13 nginx oauth-2.0 openid-connect keycloak

我正在尝试使用我正在构建的 Android 应用程序对 keycloak 服务器进行 OIDC 身份验证/授权。

我收到以下错误,这导致我在我的应用程序中收到 502:

2019/08/15 00:29:04 [error] 31921#31921: *64410338 upstream sent too big header while reading response header from upstream, client: 192.168.4.61, server: stage.example.com, request: "GET /auth/realms/master/protocol/openid-connect/auth?client_id=example-mobile-android&redirect_uri=http%3A%2F%2Flocalhost%3A53978%2F%23%2Flogin&state=a627edff-c1a2-43d3-8c6e-e5635bcc2252&response_mode=fragment&response_type=id_token%20token&scope=openid&nonce=69967773-36ba-49b2-8dd8-a31fd36f412b&prompt=none HTTP/1.1", upstream: "http://192.168.4.147:8080/auth/realms/master/protocol/openid-connect/auth?client_id=example-mobile-android&redirect_uri=http%3A%2F%2Flocalhost%3A53978%2F%23%2Flogin&state=a627edff-c1a2-43d3-8c6e-e5635bcc2252&response_mode=fragment&response_type=id_token%20token&scope=openid&nonce=69967773-36ba-49b2-8dd8-a31fd36f412b&prompt=none", host: "www.example.com", referrer: "http://localhost:53978/"
Run Code Online (Sandbox Code Playgroud)

我已经尝试过这两种方法:

proxy_buffer_size          128k;
proxy_buffers              4 256k;
proxy_busy_buffers_size    256k;
Run Code Online (Sandbox Code Playgroud)

以及完全禁用代理缓冲区。

可能发生什么事?我要进一步扩大缓冲区吗?还有其他我没有发现的错误吗?

Dan*_*nin 9

对于这个错误,罪魁祸首是proxy_buffer_size

我在这里有一篇详细的文章。本质上,如果您没有为 NGINX 分配足够的缓冲区来读取响应标头,那么它将因此错误而失败。

如果您可以完整地重构请求 URL/标头,则可以计算此参数所需的值,例如:

curl -s -w \%{size_header} -o /dev/null https://example.com
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,您都将提高它的默认值,并将其与增加的proxy_busy_buffers_size, 和proxy_buffers结合起来。

如果您无法确定响应标头/正文的大小,那么可以 - 逐渐增加内容,直到解决问题。

不要只是将缓冲区设置为任意高的值,因为这些缓冲区是针对每个连接的,并且会占用更高的 RAM。

出于同样的原因,最好在 NGINX 中创建一个单独的位置并调整缓冲区值,以便仅在此处使用较大的缓冲区,而不会影响 NGINX 的整体 RAM 使用情况。

PS 禁用代理缓冲不会有帮助,因为 NGINX总是缓冲响应标头:)


Reg*_*tos 5

对我来说,@danila-vershinin 的答案是正确的。

不过,我想为那些尝试在 Kubernetes 上配置它的人添加我的 50 美分。我让它在 Keycloak 20.0.3 上工作,如下所示:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: keycloak
  namespace: keycloak
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
spec:
  tls:
    - hosts:
      - my-keycloak.example.com
  rules:
  - host: my-keycloak.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: keycloak
            port: 
              number: 80
Run Code Online (Sandbox Code Playgroud)

注意注释部分。

另外,据我了解, proxy_busy_buffers_size现在是根据 proxy_buffers 的大小计算的。

我希望它有帮助。


Jan*_*raj 2

这取决于添加到访问令牌中的内容。我见过约 1MB 大小的令牌;这是极端的情况,令牌包含大量用于授权的用户组/角色。尝试配置更大的缓冲区大小。