配置Nginx、Keycloak与Spring Boot应用,解决端口跳转异常问题
问题解决:反向代理下Keycloak跳转端口异常的配置调整
核心问题根源
当前问题是由于反向代理未传递正确的外部访问头部、应用与Keycloak客户端未配置代理后的真实地址,导致登录跳转、回调都指向了后端服务的原始端口(8180/8081),而非Nginx对外开放的80端口。以下是分模块的修正方案:
一、调整Nginx配置:传递代理头部
在Nginx的location块中添加代理头部,让后端Spring Boot和Keycloak识别外部的真实访问地址:
server { listen 80; server_name 127.0.0.1; root D:/webreport/static; set $onMaintanence false; location / { # 简化跳转逻辑,自动适配协议和主机 return 301 $scheme://$host/gui; } location /gui/ { if ($onMaintanence = "true") { return 503; } error_page 503 502 @maintenance; proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600; # 关键:传递外部访问的真实信息给Spring Boot 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; proxy_set_header X-Forwarded-Port $server_port; proxy_pass http://127.0.0.1:8081; } location /keycloak/ { # 同样传递头部给Keycloak 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; proxy_set_header X-Forwarded-Port $server_port; proxy_pass http://$host:8180; } }
二、修正Spring Boot应用配置(application.yml)
更新Keycloak地址为Nginx代理后的80端口地址,并配置Tomcat信任代理头部:
server: port: "8081" servlet: context-path: /gui forward-headers-strategy: framework # 配置Tomcat识别代理传递的头部信息 tomcat: remoteip: remote-ip-header: X-Forwarded-For protocol-header: X-Forwarded-Proto port-header: X-Forwarded-Port keycloak: auth-server-url: "http://127.0.0.1/keycloak" # 改为Nginx代理后的Keycloak地址(无需8180) realm: "MyRelam" resource: "MyClient" publicClient: true proxy-url: "http://127.0.0.1/keycloak" # 重写回调地址,替换8081端口为80 redirect-rewrite-rules: "^http://127.0.0.1:8081/gui/(.*)$": "http://127.0.0.1/gui/$1"
三、调整Keycloak客户端配置
登录Keycloak管理控制台(通过http://127.0.0.1/keycloak访问),进入MyRelam下的MyClient配置页面:
- Settings标签页:
- 将
Valid Redirect URIs修改为http://127.0.0.1/gui/*(替换原8081端口的地址) - 将
Web Origins设置为http://127.0.0.1(生产环境建议限制具体域名,测试可临时用*)
- 将
- 保存配置。
四、修正Spring Security的登出处理器
注意原代码中KyecloakLogoutSuccessHandler的拼写错误,并配置登出地址为代理后的Keycloak地址:
@Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); String roles = String.join(",", authConfig.roles()); // 配置正确的Keycloak登出处理器 KeycloakLogoutSuccessHandler logoutSuccessHandler = new KeycloakLogoutSuccessHandler(); logoutSuccessHandler.setLogoutUri("http://127.0.0.1/keycloak/realms/MyRelam/protocol/openid-connect/logout"); http .csrf().disable() .authorizeRequests() .antMatchers("/vaadinServlet/UIDL/**").permitAll() .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll() .antMatchers("/") .hasAnyRole(roles) .anyRequest() .permitAll() .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler()) .and().logout().logoutUrl("/logout") .logoutSuccessHandler(logoutSuccessHandler) .deleteCookies("auth_code", "OAuth_Token_Request_State", "JSESSIONID") .clearAuthentication(true) .invalidateHttpSession(true) .permitAll(); }
验证步骤
- 重启Nginx、Spring Boot应用
- 访问
http://127.0.0.1,会自动跳转到http://127.0.0.1/gui - 未登录时会引导至
http://127.0.0.1/keycloak的登录页(而非8180端口) - 登录成功后自动回调至
http://127.0.0.1/gui,登出流程也会保持在80端口
内容的提问来源于stack exchange,提问作者Axel HK
相关产品推荐
相关产品推荐

