Неизвестный алгоритм MD5 с использованием net-http-digest_auth
Я пытаюсь выполнить дайджест авторизацию на сервере, а затем проанализировать полученный HTML с помощью nokogiri. Я использую гем net-http-digest_auth (https://github.com/drbrain/net-http-digest_auth), чтобы установить соединение с URL. Все хорошо, пока я не начну код 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
2 ответа
Я закончил тем, что использовал гем httpclient для достижения той же цели.
Окончательный код, чтобы сделать именно то, что я был после:
#!/usr/bin/env ruby
require 'httpclient'
require 'nokogiri'
c = HTTPClient.new
c.debug_dev = STDOUT
c.set_auth("http://domain.com", "username", "password")
doc = Nokogiri::HTML(c.get_content("http://domain.com"))
isDaylight = "";
doc.css('.controlTitle:contains("isDaylight") ~ .controlValue').each do |var|
isDaylight = var.content
end
if (!isDaylight)
system("curl -X PUT --digest -u username:password -d isOn=1 http://domain.com")
else
system("curl -X PUT --digest -u username:password -d isOn=0 http://domain.com")
end
Я надеюсь, что это поможет другим, которые могут работать с сервером домашней автоматизации и нуждаются в простой аутентификации на основе дайджеста.
Сет, я столкнулся с этой же проблемой, работая над сценарием в ruby. Я новичок в ruby, но после нескольких поисков в Google и некоторых прокси-серверов Charles, показывающих мне, что происходит, я вижу, что для реализаций HTTP характерно включать кавычки в часть алгоритма ="MD5" заголовка Auth, что неверно согласно спецификации (это должен быть алгоритм =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 показывает:
обратите внимание на алгоритм =\"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"
Для примера сценария в оригинальном посте я вставил бы следующие две строки:
www_auth_response = res['www-authenticate']
www_auth_response["algorithm=\"MD5\""] = "algorithm=MD5"
И измените третью строку:
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
...
Здесь важно то, что мы модифицируем строку www-authenticate, которая возвращается из вашего первоначального неавторизованного запроса 401 (как интерпретируется этой библиотекой ruby). Отправка измененной строки заголовка (www_auth_response) в метод digest_auth.auth_header не приводит к ошибкам. По крайней мере, это сработало для меня в моем сценарии!
Надеюсь, это поможет!
Matt