You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Rails通过unixODBC用externalbrowser认证连接Snowflake SSO失败问题?

问题描述

我搭建了一个Rails 7.0.4应用,使用ruby-odbc、sequel及sequel-snowflake连接器对接Snowflake数据库,采用SSO登录Snowflake,因此在DSN配置中将认证方式设置为externalbrowser。前端由React处理,同时使用rack-cors。该应用在Windows上运行正常,但部署到AlmaLinux 9系统中后出现问题。

我选择使用unixODBC,已配置好DSN,通过isql可正常连接:浏览器窗口打开,重定向到localhost并携带SAML token,提示认证成功,且能在isql shell中正常执行SQL命令。但启动Rails应用时,在重定向到localhost环节失败,提示"This site can't be reached / localhost refused to connect"。

我尝试了多种方法但均无效:

  • 更换不同浏览器(Firefox、Chrome、Brave)
  • 在cors.rb中添加URL到origins配置项
  • 关闭浏览器中的HSTS
  • 在application.rb中设置config.force_ssl为false
  • 使用Passenger替代Puma

对比正常工作的isql日志与Rails日志,发现Rails在浏览器认证启动前一切正常,但出现如下错误:

2023-01-31T13:12:17Z.699                [thread-7067]   Info    Connection #0 to host xxxxx.west-europe.azure.snowflakecomputing.com left intact.
2023-01-31T13:12:17.699 INFO  7067 sf::RestRequest::httpPerform: http request headers: Content-Type: application/json
Accept: application/json

2023-01-31T13:12:17.699 TRACE 7067 sf::CurDesc::reset: cleanup 0
2023-01-31T13:12:17.699 TRACE 7067 sf::CurDesc::reset: curl_easy_reset 0x42b2d50
2023-01-31T13:12:17.699 TRACE 7067 sf::CurlDescPool::freeCurlDesc: Free curl descriptor 0x42b1bf0(curl=0x42b2d50) back to subpool 0x428de20
2023-01-31T13:12:17.699 TRACE 7067 sf::RestRequest::~RestRequestState: Freed descriptor to pool
2023-01-31T13:12:17.699 DEBUG 7067 sf::AuthenticatorExternalBrowser::getSSOUrl: SSO URL: https://login.microsoftonline.com/52d....7e/saml2?SAMLRequest=nZJB....%2FkL&RelayState=58393
Initiating login request with your identity provider. A browser window should have opened for you to complete the login. If you can't see it, check existing browser windows, or your OS settings. Press CTRL+C to abort and try again...
2023-01-31T13:12:17.822 ERROR 7067 sf::AuthWebServer::startAccept: Failed to receive SAML token. Could not accept a request. err: Interrupted system call
2023-01-31T13:12:17.822 TRACE 7067 Simba::Snowflake::SFConnection::connect: Simba::Support::ErrorExceptionUnformatted ErrorException: {MessageKey="SFAuthWebBrowserFailed" ComponentID=102' RowNumber=UNKNOWN ColumnNumber=UNKNOWN DiagState=63 MessageParameters=["Permission denied"]}
2023-01-31T13:12:17.823 TRACE 7067 Simba::Snowflake::SFConnection::SetProperty: Setting property (167) with type 2
/home/mwinter/.rvm/gems/ruby-3.1.2/gems/sequel-5.64.0/lib/sequel/adapters/odbc.rb:17:in `drvconnect': ODBC::Error: S1000 (38) [Snowflake][Snowflake] (38)  (Sequel::DatabaseConnectionError)
      Failed to authenticate a user by external browser: Permission denied.

请问是否有办法让Rails像isql一样通过unixODBC连接数据库?

解决方案

1. 检查端口权限与本地回环规则

日志中的Permission denied和Interrupted system call指向Rails进程无权限监听本地端口,或本地回环通信被阻止:

  • 确认Rails运行用户(如部署用的nginx、Passenger用户)有权限绑定大于1024的非特权端口(Snowflake驱动默认使用这类端口)。
  • 检查firewalld规则,确保允许本地回环接口通信:
    firewall-cmd --add-interface=lo --permanent
    firewall-cmd --reload
    
  • 临时关闭防火墙测试:systemctl stop firewalld,若能正常认证,再调整规则而非长期关闭。

2. 显式指定回调端口与地址

修改ODBC配置文件(/etc/odbc.ini或用户目录下的.odbc.ini),添加固定回调参数,避免驱动随机选端口时触发权限问题:

[YourSnowflakeDSN]
AUTHENTICATOR=externalbrowser
BROWSER_REDIRECT_PORT=8080
BROWSER_REDIRECT_HOST=127.0.0.1
# 其他原有配置...

3. 同步进程环境变量

isql能正常运行,说明环境变量配置正确,但Rails进程可能缺失关键配置:

  • 确保Rails进程能读取ODBC配置文件,设置环境变量:ODBCINI=/etc/odbc.ini
  • 检查LD_LIBRARY_PATH包含unixODBC和Snowflake驱动的库路径,比如:
    export LD_LIBRARY_PATH=/usr/lib64:/opt/snowflake/snowflakeodbc/lib64:$LD_LIBRARY_PATH
    
  • 若用systemd启动Rails,在服务配置文件中显式添加这些环境变量,避免环境继承不全。

4. 切换无浏览器依赖的认证模式(备选)

如果externalbrowser认证始终无法适配服务器环境,可改用更适合服务器部署的认证方式:

  • OAuth认证:预先获取OAuth token,在DSN中配置AUTHENTICATOR=oauth和TOKEN=your_oauth_token
  • JWT密钥认证:生成密钥对,配置AUTHENTICATOR=JWT、PRIVATE_KEY_FILE=/path/to/key.p8等参数,无需浏览器交互

内容的提问来源于stack exchange,提问作者Marc W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:46:34