带有 NGINX 代理服务器的 Keycloak 未验证 rest api

Posted

技术标签:

【中文标题】带有 NGINX 代理服务器的 Keycloak 未验证 rest api【英文标题】:Keycloak with NGINX proxy server not authenticating rest api 【发布时间】:2018-07-08 20:50:08 【问题描述】:

我有一个示例应用程序,可以在没有 nginx 的情况下在本地正确保护其余 api。现在,当我将它放在 nginx 代理后面的生产中时,它不起作用。没有错误。它允许所有请求。

带有ssl的前端服务器是https://frontend.com

带有ssl的后端服务器是https://backend.com

Keycloak 代理转发为真

前端服务器(9000 上的节点服务器) NGINX Keycloak(在 8180 上运行)

nginx 文件示例

upstream keycloak_server 
  server localhost:8180;


upstream node_server 
  server localhost:9000;


location /auth/ 
  proxy_pass http://keycloak_server;
  proxy_http_version 1.1;
  proxy_set_header Host              $host;
  proxy_set_header X-Real-IP         $remote_addr;
  proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  
location / 
  proxy_pass http://node_server;
  proxy_http_version 1.1;
  proxy_set_header Host              $host;
  proxy_set_header X-Real-IP         $remote_addr;
  proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

前端服务器使用 Angular 调用后端 api。 REST api 调用看起来像 https://backend.com/callTest

后端服务器(在tomcat上运行) NGINX Spring Boot(带keycloak)

nginx 示例

location / 
  proxy_pass http://127.0.0.1:8080/dt-1.0/;
  proxy_http_version 1.1;
  proxy_set_header Host               $host;
  proxy_set_header X-Real-IP          $remote_addr;
  proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto  $scheme;
  

在 angular keycloak.json 中看起来像


  "realm": "demo",
  "auth-server-url": "https://frontend.com/auth",
  "ssl-required": "none",
  "resource": "tutorial-frontend",
  "public-client": true

在 spring boot keycloak 属性看起来像

  keycloak.auth-server-url=https://frontend.com/auth
  keycloak.realm=demo
  keycloak.resource=tutorial-frontend
  keycloak.public-client=true
  keycloak.bearer-only = true
  keycloak.cors = true
  keycloak.security-constraints[0].authRoles[0]=user
  keycloak.security-constraints[0].securityCollections[0].patterns[0]=/*

请告诉我如何纠正这个问题。我真的很感激。

【问题讨论】:

将适配器的日志级别设置为 DEBUG:logging.level.org.keycloak=DEBUG 看看发生了什么。 应该在属性文件中添加这个吗? 您可以在属性文件中添加或将其作为环境变量传递:docs.spring.io/spring-boot/docs/current/reference/html/… tomcat 没有记录任何信息 @ksernow:你的问题解决了吗?让我知道你是否可以。我有同样的情况。 【参考方案1】:

三年后,我也遇到了同样的问题。也许你已经解决了,但我想还有很多人和我一样遇到过这个问题。我的解决方案是使用openresty。你会发现很多 openresty 的教程或代码片段。这里就不多说了。

我只是在openresty认证通过后把access_token放在请求头中,就这样

local opts = 
    redirect_uri_path = "/redirect_uri",
    discovery = "https://a.b.c.d:8093/auth/realms/xxx/.well-known/openid-configuration",
    client_id = "client_id",
    client_secret = "client_secret",
    redirect_uri_scheme = "https",
    logout_path = "/logout",
    redirect_after_logout_uri = "https://a.b.c.d:8093/auth/realms/xxx/protocol/openid-connect/logout?redirect_uri=https://a.b.c.d:8093/",
    scope = "openid email",
    access_token_expires_leeway = 0,
    accept_none_alg = false,
    accept_unsupported_alg = false,
    renew_access_token_on_expiry = true,
    session_contents = access_token=true, id_token = true

local res, err = require("resty.openidc").authenticate(opts)
if err then
    ngx.status = 403
    ngx.say(err)
    ngx.exit(ngx.HTTP_FORBIDDEN)
end
ngx.req.set_header("Authorization", "Bearer " .. res.access_token)

在nginx配置文件中,我是这样做的

    location /auth/ 
        proxy_pass http://keycloak:8080/auth/;
        proxy_set_header Host $host:$server_port;
    

    location / 
        access_by_lua_block 
            require("oidc/acc")()
        
        try_files $uri $uri/ /index.html;
        index  index.html;
    

    location  /api/ 
        access_by_lua_block 
            require("oidc/acc")()
        
        proxy_set_header  Host  $host:$server_port;
        proxy_pass http://gateway:8881/api/;
    

【讨论】:

以上是关于带有 NGINX 代理服务器的 Keycloak 未验证 rest api的主要内容,如果未能解决你的问题,请参考以下文章

如何在 keycloak 和 nginx 上配置 cors?

使用 nginx 作为反向代理和 keycloak 作为上游服务器的组合失败

Keycloak NGINX 反向代理问题

使用 nginx 反向代理后面的 keycloak 保护 nodejs 中的路由

为啥带有 Netflix Zuul 反向代理的 Keycloak OAUTH2 不传递令牌

使用 nginx 的 Keycloak 重定向 url 将转到 http 而不是 https