【问题标题】:OpenUri causing 401 Unauthorized error with HTTPS URLOpenUri 导致 HTTPS URL 出现 401 Unauthorized 错误
【发布时间】:2012-12-07 12:47:13
【问题描述】:

我正在添加从需要使用带有身份验证的 HTTPS 连接的源中抓取 XML 页面的功能。我正在尝试使用 Ryan Bates 的 Railscast #190 解决方案,但遇到了 401 身份验证错误。

这是我的测试 Ruby 脚本:

require 'rubygems'
require 'nokogiri'
require 'open-uri'

url = "https://biblesearch.americanbible.org/passages.xml?q[]=john+3:1-5&version=KJV"
doc = Nokogiri::XML(open(url, :http_basic_authentication => ['username' ,'password']))
puts doc.xpath("//text_preview")

这是我运行脚本后控制台的输出:

/usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `connect'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:744:in `start'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:306:in `open_http'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:775:in `buffer_open'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:203:in `block in open_loop'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:201:in `catch'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:201:in `open_loop'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:146:in `open_uri'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:677:in `open'
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/open-uri.rb:33:in `open'
from scrape.rb:6:in `<main>'

在我的研究中,我看到一篇帖子建议在 1.9.3 中可以使用以下选项:

doc = Nokogiri::XML(open(url, :http_basic_authentication => ['username' ,'password'], :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE))

但是,这也不起作用。我希望能对解决这一挑战有一些见解。

【问题讨论】:

  • 小心使用:ssl_verify_mode =&gt; OpenSSL::SSL::VERIFY_NONE。这会禁用 SSL 证书检查,以确保连接的完整性,帮助避免中间人攻击。

标签: ruby authentication https screen-scraping


【解决方案1】:

你可以这样做,它也应该可以工作:

open(url, :http_basic_authentication => [user, pass] ) doc = Nokogiri::HTML(open(url, :http_basic_authentication => [user, pass] ))

然后,您可以根据需要解析文档。 通过在第二个请求中再次传递标头中的 http_basic_authentication,您将弥补第一个请求中已删除的标头。 希望这对你有用。

http://http-basic-authentication-nokogiri.blogspot.com/2014/08/http-basic-authentication-using-nokogiri.html

【讨论】:

    【解决方案2】:

    给定的 URL 将被重定向到 /v1/KJV/passages.xml?q[]=john+3%3A1-5,HTTP 状态代码为 302 Found。 OpenURI 理解重定向,但出于安全原因自动删除身份验证标头(可能)。 (*)

    如果你直接访问"http://biblesearch.americanbible.org/v1/KJV/passages.xml?q[]=john+3%3A1-5",你会得到预期的结果。 :-)

    (*) 可以在open-uri.rb:

    if redirect
      ### snip ###
      if options.include? :http_basic_authentication
        # send authentication only for the URI directly specified.
        options = options.dup
        options.delete :http_basic_authentication
      end
    

    【讨论】:

    • 如果我没记错的话,当从安全 URL 重定向到非安全 URL 时,必须删除安全标头。这是几年前发现并在客户端中修复的漏洞或漏洞,而不仅仅是 OpenURI。它应该由 OpenURI 自动处理。
    • 基本身份验证标头将被删除即使从 HTTPS 重定向到 HTTPS,从 ruby​​ 1.9.3p286(最新稳定版本)开始。详情请查看 open-uri.rb。
    • 谢谢@HIRATA Yasuyuki!我现在看到只读不需要身份验证,只有 RESTful 写入需要。指向您指定的 URL 现在可以正常工作。感谢您的帮助。
    【解决方案3】:

    你说你需要使用 HTTPS,但你使用的是 HTTP 协议:

    url = "http://biblesearch...."
    

    OpenURI 可以理解 HTTP 和 HTTPS。如果要使用 HTTPS 连接,请将 URL 中的协议更改为 HTTPS,然后进行连接:

    url = "https://biblesearch...."
    

    【讨论】:

    • 是的,对不起。我更新了代码和输出。现在似乎存在验证证书的问题。正在研究...
    猜你喜欢
    • 2022-10-20
    • 1970-01-01
    • 2021-05-01
    • 2020-10-25
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多