Pull to refresh

Comments 35

Вы только в UPS вот так кабель не втыкайте, а то ему будет плохо.
Можно ещё приспособить Microsoft.Owin для встраивания web-сервера. Nuget пакет — «Microsoft.Owin.SelfHost». Вы такой не пробовали?
Owin сильно больше и сложнее, использую его на бекенде с приложениями на asp.net. Мне кажется для такой задачи его многовато. Но работать, конечно, будет.
Стало интересно, а сколько он действительно занимает? Постоянно использую для self-hosting приложений. Сделал на коленке проект самого простого web-сервера:
image

А если выкинуть все xml, то и того меньше:
image

Вроде не очень и много. Просто для себя выяснил и поделился. )))

Вообще, конечно, работать с локальными устройствами напрямую из браузеров даже через CORS вроде как не делают. Если вы решили получить доступ к устройству через браузер, сделали на устройстве web-сервер и добавили туда angular/bootstrap и прочие библиотеки (которые в сумме байт могут занять даже больше чем сам web-браузер), то вроде как и смысла нет загружать какой-то внешний сайт с которого будут идти запросы на локальный http(s)?
А так встраивать web-сервер приложения — очень даже неплохо. Web-сервис всегда может пригодится для доступа извне просто по протоколу http.
Спасибо, что уделили время на исследования. Я тоже проверил: Nancy.dll — 878 KB, Nancy.Hosting.Self.dll — 22 KB. У меня там, правда BouncyCastle.Crypto.dll на 2.5 MB.

Angular не на устройстве, на нём делаем приложение в интернете. А потом вдруг хотим, чтобы пользователи могли подписывать документы в нашем веб-приложении с помощью свей электронной подписи (а подпись по ГОСТ и на аппаратном носителе). Вот тут и возникает необходимость сделать локальную службу, которая слушает обращения от нашего сайта, и делает всю работу с железом и отдаёт подписанный документ (просто REST API, служба без пользовательского интерфейса).

А CORS, чтобы сайты с URL, отличным от нашего, не могли тоже воспользоваться нашей службой.
Ok, понятно. Т.е. схема сейчас такая:
image

А если сделать её такой:
image

Ваше приложение становится прокси сервером и тогда в браузере не надо делать CORS. Что-то принципиально изменится?
В этом случае на локальном web-сервере не надо хранить вообще никакие файлы для интерфейса, а просто обрабатывать запросы — одни отправлять на ключ, другие за файлами на ваш web-сервер.
Тут есть один бонус — если ваше приложение открывается локальной программой, то она может проверить какой номер порта свободен и использовать для работы любой доступный порт, а в вашем случае сайт должен знать какой порт использовать, что в принципе невозможно, кроме заранее прописанного. (Может и мелочь)
Приватный ключ, конечно, надо таскать за собой на аппаратном ключе, но ведь и банки постоянно перевыпускают карты, так и вы можете перевыпускать ключи раз в год, два, три.
По второй схеме будет работать, вот почему сделано по первому варианту:

1. Во внутренних сетях крупных компаний для левой программы часто получить доступ в интернет без танцев с бубном трудно. По крайней мере, там придётся привлекать к этому админов.
2. Но в браузерах обычно сеть настроена, не придётся делать эту работу дважды.
3. Уже специфично для меня — только 20% пользователей сервиса нужна эта функция, остальные работают с обычным веб-приложением.

Ключи мы не выпускаем, их пользователи делают сами, нам просто нужно ими документы подписывать.

С портом легко решается. Пример я не стал этим усложнять, но если мы не можем открыть порт, мы пробуем другой из списка — 10 штук (не подряд). А в браузере опрашиваем их по очереди.
для левой программы часто получить доступ в интернет без танцев с бубном трудно
Скорее это заслуга разработчиков браузеров ))) А так норм. Спасибо, что освежили в памяти CORS. Сам периодически с этим сталкиваюсь, интересно почитать, что у других )))
Подскажите, для какого конкретно СКЗИ применяете это решение? Просто, насколько мне известно, для большинства поставщик сам предоставляет браузерные плагины.
Да, задачу цифровых подписей можно решить готовыми плагинами.

Мы поддерживаем КриптоПро CSP и ViPNet CSP, оба могут работать с КриптоПро ЭЦП Browser plug-in. Почему мы не стали его использовать:

  • Нам нужно подписывать pdf и docx, на c# нам это сделать намного дешевле и быстрее, чем на JavaScript (TypeScript). Там был код, который можно повторно использовать. Причем Word от 2007 до самого нового должен понимать наши подписи.
  • При необходимости в программе можно авторизоваться и подписывать документы не на той машине, на которой запущен браузер.
  • Настройка плагина тоже нетривиальная


Ну а сам подход можно применять не только для ЭЦП, а вообще для любой работы с железом, например со считывателями карт.
А если выкинуть все xml, то и того меньше
Пара xml осталось. И pdb можно не включать.
Да, точно, не заметил. В общем-то pdb для работы особо и не нужен. Он только для отладки.
Речь в статье не об этом. Я рассказываю о локально запущенном сервере, к API которого хочу получить доступ с сайта app.example.com.
Т.е. из скрипта на странице app.example.com мне надо сделать запрос по адресу localhost
Кроме того,
Locally delivered files such as localhost and file:// paths are considered to have been delivered securely.

это по ссылке с MDN. В статье я пишу, что в IE 11 и Edge это не работает.
У автора стоит цель сделать портабельное приложение, а не приложение, которое работает только в последней версии Хрома на вашем Маке.
Работа сайта по протоколу HTTPS добавляет немножко проблем.
Поясните пожалуйста, какого рода проблемы (бек, фронт)? У меня вообще ни разу ни одной проблемы не возникло, более того, для Angular все проблемы давно решены через концфигурацию запуска аргументами командной строки, proxy. Для бека вообще все ок, генерируете, используете, в крайнем случае NGINX, Apache вам в помошь, конфигурируются элементарно
Речь не о сложностях работы angular в браузере, а о том, что с работающего по HTTPS сайта нельзя сделать ajax-запрос на любой API, работающий по HTTP.
Спасибо за замечание, пожалуй уберу эту фразу, раз она смущает.
Не понял, почему не выпустить валидный сертефикат для local.example.com и тогда ничего не нужно будет распространять с программой.
Тогда надо встроить в программу приватный ключ от этого сертификата, что вроде как небезопасно.
Тут несколько причин.
1. Самая главная, как Sabubu уже написал, придётся распространять этот сертификат с закрытым ключом вместе с программой. Иначе она не сможет шифровать SSL-трафик с использованием этого сертификата, не имея закрытого ключа.
2. Срок действия платных сертификатов 1 год (видел, что можно сделать на 3 года максимум). Значит, программу нужно будет ежегодно обновлять — это просто лишняя работа.
3. За платные сертификаты нужно будет платить деньги.
4. Let's encrypt не подойдёт, там сертификаты валидны всего 3 месяца, придётся часто обновлять их.
5. Самоподписанному сертификату можем сделать срок службы хоть сто лет.
6. Неизвестно как поведут себя разные DNS-серверы, при попытке разрешить доменное имя на 127.0.0.1.
Все равно считаю это лучшим решением, проблемы обновиться нету, закрытые ключи, да, но кому они нужны. При просрочки сертификата, можно использовать ваш текущий метод.
UFO just landed and posted this here

У такого способа есть и недостатки:


  1. прослушивание запросов через HTTP.SYS требует настройки прав (которая, кстати, тут не показана);
  2. два экземпляра программы от разных пользователей так запустить не получится, так что это решение получается несовместимым с терминальными серверами и с быстрым переключением пользователей;
  3. нужно придумывать уникальные имена для конечных точек — иначе сайт сможет по-ошибке начать работать с чужой программой аналогичного назначения;
  4. порт 80 обычно у всех занят Скайпом.
Спасибо за ценные замечания.
прослушивание запросов через HTTP.SYS требует настройки прав (которая, кстати, тут не показана);
Не требует, т.к. мы не слушаем никого снаружи, только сами себя. А если нужно слушать снаружи, Nancy умеет сама делать биндинг, повышение прав нужно один раз.
Слушаем запросы снаружи с помощью Nancy
hostConfigs.RewriteLocalhost = true;


два экземпляра программы от разных пользователей так запустить не получится, так что это решение получается несовместимым с терминальными серверами и с быстрым переключением пользователей;
Если делать программу службой Windows, то нужен только один экземпляр.
нужно придумывать уникальные имена для конечных точек — иначе сайт сможет по-ошибке начать работать с чужой программой аналогичного назначения;
Согласен.
порт 80 обычно у всех занят Скайпом.
Поэтому 80 порт, как и 443 не используется, там пул из десяти портов, разбросанных в диапазоне 10000-45000. Мы их по очереди прощупываем, вдруг какие-то из них тоже заняты. В примере используются порты 40850 для HTTPS и 40849 для HTTP.
Не требует, т.к. мы не слушаем никого снаружи, только сами себя.

А в чём разница? Хоть сами себя, хоть снаружи — всё равно нужны права на прослушивание префикса.


Если делать программу службой Windows, то нужен только один экземпляр.

А, ну если службой — тогда да. Кстати, вот и источник прав нашёлся.


Поэтому 80 порт, как и 443 не используется

Но в статье-то вы именно его и использовали...


Кстати, раз уж вы ещё и порт уникальный выбрать пытаетесь — то можно менять не только номер порта, но и IP-адрес. Любой адрес вида 127.x.y.z должен работать столь же хорошо как и 127.0.0.1.

А в чём разница? Хоть сами себя, хоть снаружи — всё равно нужны права на прослушивание префикса.
URL ACL не нужны, когда мы биндимся к localhost:port вместо +:port. Эту же магию использует IIS Express, ему тоже не нужны права.
Также с Nancy можно использовать Kestrel, он не использует HTTP.SYS
А вы попробуйте забиндить IIS Express к адресу 127.0.0.1:80. Без админских прав это не сработает.
Да, порты меньше 1024 считаются привилегированными, и для их прослушивания нужны права администратора. Порты от 1025 можно прослушивать без прав администратора. Зря я не уточнил это в статье. Спасибо за дополнение.
4 — собрать приложение со встроенным браузером, и в нем открывать сайт, который требует обращения к оборудованию. Взаимодействие встроенного браузера и остальной части программы делается очень просто.
Приказом по организации все используют только его для работы с определённым кругом задач.
А что у нас на сегодняшний день используют для встраивания браузеров, не подскажите?
А для работы с веб-сокетами тоже нужны заморочки с сертификатами? У меня есть аналогичная задача и танцы с разными браузерами мне не нравятся. Хотелось бы унификации.
Проверил ASP.NET Core SignalR по HTTP: в Chrome и Edge работает, в Firefox и IE 11 нет. Похоже, WebSocket только добавит проблем. Пока некоторые браузеры игнорируют стандарт, танцев с бубном не избежать (пока не умрёт IE 11).
WebSockets — это НЕ HTTP, это просто общение по TCP. Вроде бы должно работать, хотя первый запрос идёт как раз с использованием HTTP…
The WebSocket connection starts its life with an HTTP or HTTPS handshake. When the page is accessed through HTTP, you can use WS or WSS (WebSocket secure: WS over TLS). However, when your page is loaded through HTTPS, you can only use WSS — browsers don't allow to «downgrade» security.
отсюда
sarcasm_mode_on

Хех, обожаю браузерописателей за идеальное следование стандартам и отсутствие вынужденного велосипедостроения от остальных разработчиков. :)
Sign up to leave a comment.

Articles