1

サーバーに対してダイジェスト認証を行い、結果の HTML を nokogiri で解析しようとしています。URL 接続を行うために net-http-digest_auth gem (https://github.com/drbrain/net-http-digest_auth) を使用しています。digest_auth コード (20 行目) を開始するまでは問題ありません。「不明なアルゴリズム「MD5」エラー」がスローされます..

コンソールからの完全なエラー メッセージ: ~/.rvm/gems/ruby-1.9.3-p194@rails32/gems/net-http-digest_auth-1.2.1/lib/net/http/digest_auth.rb:105:in 'auth_header': unknown algorithm ""MD5"" (Net::HTTP::DigestAuth::Error) from ./server_connection.rb:20:in '<main>'

行 20 は認証行です。 auth = digest_auth.auth_header uri, res['www-authenticate'], 'GET'

これが私の完全なコードです(githubリンクで使用されているサンプルコードからほぼ完全にそのままです):

#!/usr/bin/env ruby
require 'uri'
require 'net/http'
require 'net/http/digest_auth'

digest_auth = Net::HTTP::DigestAuth.new

uri = URI.parse 'http://url/controlpage?name=_internal_variables_&asList=1&useJS=True'
uri.user = 'username'
uri.password = 'password'

h = Net::HTTP.new uri.host, uri.port

req = Net::HTTP::Get.new uri.request_uri

res = h.request req

# res is a 401 response with a WWW-Authenticate header
auth = digest_auth.auth_header uri, res['www-authenticate'], 'GET'

# create a new request with the Authorization header
req = Net::HTTP::Get.new uri.request_uri
req.add_field 'Authorization', auth

# re-issue request with Authorization
res = h.request req

if res.code == "200"
  page = Nokogiri::HTML(res)
  isDaylight = page.css('.controlTitle:contains("isDaylight") ~ .controlValue');
  puts isDaylight.content
end

この質問を更新して、Chrome の開発ツールを介してリクエスト ヘッダーを含めます。

GET /_getupdatedcontrols?name=_internal_variables_&asList=True&folderFilter=0&changeCount=479&serverState=idle HTTP/1.1
Host: url
Connection: keep-alive
Cache-Control: no-cache
Authorization: Digest username="username", realm="Indigo Control Server", nonce="71079e9f29f7210325ae451d0f423f07", uri="/_getupdatedcontrols?name=_internal_variables_&asList=True&folderFilter=0&changeCount=479&serverState=idle", algorithm=MD5, response="bc056cc472d35f7967973cb51c5b1a65", qop=auth, nc=00005649, cnonce="18dfcf3e4a7b809d"
X-Indigo-Web-Server-Version: 1
X-Prototype-Version: 1.6.0.3
X-Requested-With: XMLHttpRequest
Pragma: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.17 Safari/536.11
Accept: text/javascript, text/html, application/xml, text/xml, */*
Referer: http://url/controlpage?name=_internal_variables_&asList=1&useJS=True
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
4

2 に答える 2

1

Seth さん、Ruby でスクリプトを作成しているときに、同じ問題に遭遇しました。私はRubyを初めて使用しますが、いくつかのGoogle検索とCharles Proxyで何が起こっているかを示した後、HTTP実装がAuthヘッダーのalgorithm="MD5"部分に引用符を含めるのが一般的であることがわかりましたが、これは正しくありません仕様によると(引用符なしでアルゴリズム= MD5にする必要があります)。Chrome devtools からの更新されたヘッダー ログは、サーバーの応答が仕様を尊重していることを示していますが、その応答文字列を解釈するとき、Ruby ライブラリはそうではありません。これは、

サーバーの 401 応答には次のものが含まれていました。

アルゴリズムに注意してください = MD5

Authorization: Digest username="username", realm="Indigo Control Server", nonce="71079e9f29f7210325ae451d0f423f07", uri="/_getupdatedcontrols?name=_internal_variables_&asList=True&folderFilter=0&changeCount=479&serverState=idle", algorithm=MD5, response="bc056cc472d35f7967973cb51c5b1a65", qop=auth, nc=00005649, cnonce="18dfcf3e4a7b809d"

しかし、この Ruby ライブラリを使用した最初のリクエストのコンソール出力には、次のように表示されます。

algorithm=\"MD5\"に注意してください

<- "GET /some/request HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: 10.1.0.15\r\n\r\n"
-> "HTTP/1.1 401 Unauthorized\r\n"
-> "Content-Length: 530\r\n"
-> "Server: SomeServer/5.0\r\n"
-> "Allow: GET, HEAD, POST, PUT\r\n"
-> "Date: Sun, 27 Jan 2013 00:29:23 GMT\r\n"
-> "Content-Type: text/html;charset=utf-8\r\n"
-> "Www-Authenticate: Digest realm=\"Some Realm\", nonce=\"5a8b8b46cfb84466431baf454eb9ddb9\", algorithm=\"MD5\", qop=\"auth\"\r\n"

元の投稿のスクリプト例では、次の 2 行を挿入します。

www_auth_response = res['www-authenticate']
www_auth_response["algorithm=\"MD5\""] = "algorithm=MD5"

3 行目を次のように変更します。

auth = digest_auth.auth_header uri, www_auth_response, 'GET'

次のように:

...

res = h.request req

# res is a 401 response with a WWW-Authenticate header
www_auth_response = res['www-authenticate']
www_auth_response["algorithm=\"MD5\""] = "algorithm=MD5"
auth = digest_auth.auth_header uri, www_auth_response, 'GET'

# create a new request with the Authorization header
req = Net::HTTP::Get.new uri.request_uri
req.add_field 'Authorization', auth

...

ここで重要なことは、(この Ruby ライブラリによって解釈された) 最初の無許可の 401 要求から返される www-authenticate 文字列を変更していることです。変更されたヘッダー文字列 (www_auth_response) を digest_auth.auth_header メソッドに送信しても、エラーは発生しません。少なくとも、私のスクリプトではうまくいきました。

それが役立つことを願っています!

マット

于 2013-01-27T01:03:40.363 に答える