простой способ веб-аутентификации пользователей сетей Wi-Fi
Это краткое руководство будет полезно начинающим сисадминам, перед которыми стоит задача быстро и с минимальными затратами развернуть систему Wi- Fi доступа с аутентификацией и авторизацией. Это может быть, например, небольшая беспроводная сеть, предоставляющая платную услугу использования интернета для мобильных абонентов. В интернет-кафе ставка обычно делается не на организацию безопасных каналов связи, а на простоту пользования услугой. Ничего удивительного нет – практика показывает, что значительная часть современных пользователей интернета вообще не предполагают, что в основе лежит некая среда передачи, протоколы и т.п. Они просто «заходят в интернет», то бишь открывают веб-браузер. Были случай, когда человек для доступа в интернет купил модем и уже, было, собрался окунуться в пучину всемирной паутины, как вдруг совершенно неожиданно для себя выяснил, что для этого еще и телефонная линия нужна! «Странно», — подумал мужик, — «а говорили, что нужен только модем».
Поэтому широкую популярность приобрела так называемая веб-аутентификация, которая является альтернативой более сложным VPN-туннелям и полностью отвечает юзерским представлениям – «браузер=интернет». Суть технологии в следующем: пользователь, подключившись к Wi-Fi сети, первоначально не имеет выхода в интернет. Открыв браузер и набрав произвольный URL в адресной строке, он попадает на страницу аутентификации, где ему предлагается ввести логин и пароль (или номер карты и пин-код). Доступ к интернет-ресурсам будет открыт только после успешной авторизации. В данном механизме на стороне клиента не требуется специального программного обеспечения или какой-либо предварительной настройки.
На сегодняшний день веб-аутентификацию поддерживают большинство точек доступа, однако использовать ее совместно с автоматизированной системой расчетов часто не представляется возможным из-за отсутствия полноценной поддержки RADIUS. Точки доступа, лишенные этого недостатка, как правило, стоят довольно дорого. Ниже описано решение, позволяющее реализовать веб-аутентификацию на UNIX-маршрутизаторе (том же сервере, где, например, установлена биллинговая система), что позволит сэкономить на выборе точек доступа.
Кроме стоимости, к недостаткам существующих решений, в полной мере поддерживающих RADIUS-аутентификацию (802.1х или встроенную поддержку RADIUS Web based auth) и позволяющих тарифицировать Wi-Fi соединения, стоит отнести функционирование этих решений на втором (канальном) уровне модели OSI. Из этого имеются исключения, например, решение Cisco Systems (LWAPP), которому, однако, в полной мере присущ первый недостаток — цена. Однако у большинства из изученных устройств имеется ограничение на расположение контроллера и выноса (у разных производителей под выносом понимаются одни и те же устройства, но по-разному именуемые: радио-порты (HP ProCurve Secure Access 700wl Series совместно с ProCurve Switch xl Access Controller Module), облегченные точки (SonicWall) и т.д. Такие решения чрезвычайно сложно развертывать в IP-сетях, где нет возможности поместить точку и контроллер в один Ethernet-сегмент.
Между сетью общего пользования и точкой доступа, работающей в режиме моста или маршрутизатора без NAT, вклинивается обычный PC-маршрутизатор. В нашем примере он будет работать под управлением Linux.
Все функции аутентификации Wi-Fi клиентов переносятся на сервер, что позволяет до минимума снизить требования к используемым точкам доступа. Если нужен сервис DHCP, то он может быть запущен как на AP (Access Point, точка доступа), так и на сервере. Второй вариант оправдан только в случае, когда необходимо централизованно раздавать IP-адреса в Wi-Fi сети, построенной на нескольких AP.
Функции пограничного UNIX-маршрутизатора:
— биллинговая система (например, LANBilling в комплектации LBcore, LBcd (Ethernet-агент);
— перенаправление HTTP/HTTPS-запросов на собственный веб-сервер и блокировка прочего трафика для неавторизованных пользователей;
— исполнение дополнительного скрипта аутентификации, работающего с базой данных биллинга;
— открытие доступа пользователям, прошедшим аутентификацию;
— блокировка пользователя при исчерпании баланса, по запросу или завершению сессии.
правила файрволла
Перенаправлять HTTP-трафик можно при помощи механизма iptables REDIRECT. При старте системы должны быть выполнены следующие условия: разрешены только DNS-запросы, весь веб-трафик перенаправляется на сервер, остальное, фигурально выражаясь, идет в /dev/null, то бишь заблокировано. Конфигурационный файл iptables для стартового состояния будет выглядеть примерно следующим образом (это файл, сохраненный iptables-save, так что пусть вас не смущают описания цепочек со счетчиками пакетов/байтов в квадратных скобках):
*nat
:PREROUTING ACCEPT [97569:16395666]
:POSTROUTING ACCEPT [26991:1834572]
:OUTPUT ACCEPT [27006:1835736]
-A PREROUTING -p udp -m udp --dport 53 -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 80
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 443
-A PREROUTING -j DROP
COMMIT
Как видим, все правила было решено задать в таблице nat, цепочке PREROUTING. Хоть это не единственный вариант записи (часть этих правил можно содержать и в FORWARD), так определенно удобнее с точки зрения администрирования.
Если кто не в курсе, используются такие «конфиги» совместно с программой iptables-restore. Впрочем, никто не мешает вам задавать правила файрволла способом, к которому вы привыкли.
Список заданных правил будет иметь следующий вид:
# iptables -t nat -nL PREROUTING
Chain PREROUTING (policy ACCEPT)
Target prot opt source destination
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 80
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 redir ports 443
DROP all -- 0.0.0.0/0 0.0.0.0/0
После успешной аутентификации пользователя, например, с IP-адресом 192.168.10.10, к правилам фильтра, относящимся к той же таблице nat и цепочке PREROUTING, в начало дописываем разрешающее правило (естественно, не руками дописываем, а поручаем это управляющему скрипту, пример которого см. ниже). В результате должно получиться приблизительно следующее:
# iptables -t nat -nL PREROUTING
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
ACCEPT all — 192.168.10.10/32 0.0.0.0/0
ACCEPT udp — 0.0.0.0/0 0.0.0.0/0 udp dpt:53
REDIRECT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 80
REDIRECT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 redir ports 443
DROP all — 0.0.0.0/0 0.0.0.0/0
Добавление в начало цепочки разрешающего правила (ACCEPT) фактически останавливает просмотр остальных правил для адреса 192.168.10.10, и в результате перенаправление и блокировка трафика для него не работают.
управляющие скрипты
Для динамического управления правилами iptables необходимы 2 скрипта: script_start, добавляющий разрешающее правило для данного IP-адреса в начало цепочки, и script_stop, удаляющий правило.
#!/bin/bash
# param $1 — ip
# param $2 — netmask
/sbin/iptables -t nat -I PREROUTING 1 -s $1/$2 -j ACCEPT
#!/bin/bash
# param $1 — ip
# param $2 — netmask
/sbin/iptables -t nat -D PREROUTING -s $1/$2 -j ACCEPT
Как видите, значения IP-адреса и маски подсети поступают в скрипт как параметры коммандной строки — $1 и $2 соответственно.
Вобщем-то это может быть и один скрипт, принимающий аргументы start и stop на манер System V init.
Помимо динамического управления правилами файрволла для корректного начала и завершения пользовательской сессии в базе данных необходимо поддерживать актуальное соответствие между пользователем и его текущим IP-адресом. Поэтому вышеописанные скрипты нужно немного усложнить, либо создать промежуточные, выполняющие запросы к биллингу. Или переложить большую часть работы на биллинг, одна из подсистем которого будет вызывать описанные выше скрипты как внешние модули. Вариантов, в общем, бездна.
Собственно веб-аутентификацию будет выполнять некий CGI- или PHP-скрипт на стороне сервера. Его задача проста — проверить логин и пароль. Если такой логин не найден, он попытается активировать карту, рассматривая введенный логин как номер карты. Для удобства все служебные запросы, необходимые для проверки подлинности, можно вынести в хранимую SQL-процедуру.
Если авторизация успешно пройдена, скрипт должен инициировать запуск скрипта script_start. Как он это будет делать – вам решать. Не забудьте только, что изменение правил файрволла (чем, собственно, и занимается script_start) требует root-привилегий. Веб-скрипт может также открывать в браузере пользователя дополнительное окно с формой, позволяющей отправить запрос на завершение сессии.
настройка apache
Потребуется небольшое дополнение к основной конфигурации. В httpd.conf нужно добавить строку:
ErrorDocument 404 /authorize.php
«Почему ErrorDocument?» – спросите вы. А потому, что если юзер вводит любой URL – например http://www.vasya-
pupkin.info/bestbb/index.php?xxx=yyy, вряд ли на вашем сервере, куда был перенаправлен этот запрос, найдется данная страница (вот будет прикол,если найдется! 😉
Кроме того, не мешает поправить DirectoryIndex в директории, описанной как DocumentRoot (если вы решили положить свой скрипт именно в корневую директорию):
Options Indexes FollowSymLinks
DirectoryIndex authorize.php
AllowOverride None
Order allow,deny
Allow from all
Все это необходимо для того, чтобы любой HTTP-запрос, перенаправленный на этот сервер, приводил к запуску скрипта аутентификации.
Можно, конечно, было привлечь к решению проблемы «тяжелую артиллерию» вроде mod_rewrite, но это имеет смысл только тогда, когда на данном веб- сервере есть какой-то другой, не относящийся к авторизации контент.
Необходимость прерывания пользовательской сессии возникает в следующих случаях:
— пользователь исчерпал свой баланс;
— административный запрос на блокировку.
— пользователь хочет закрыть сессию по окончании работы, дабы пресечь возможный несанкционированный доступ с использованием его IP-адреса; — разрыв сессии по таймауту при отсутствии активности с данного IP-адреса в течение заданного времени.
Во всех случаях для разрыва сессии необходимо запустить script_stop с нужными параметрами. Запуск скрипта в первых двух случаях должен инициироваться вашим биллингом. Пользовательский запрос (3-й случай) обычно выполняется через браузер (в предыдущем разделе упоминалось, что скрипт аутентификации должен открывать в браузере соотвествующее окно). Содержимое формы отправляется в тот же скрипт, он же может запускать и script_stop. Полагаю, что получение в PHP- или CGI-скрипте IP-адреса запрашивающего не является для вас проблемой.
Для обработки 4-го случая необходима переодическая проверка активных сессий. Для этих целей можно написать шелл-скрипт, который будет запускаться с заданным интервалом (через cron).
Alice D. Saemon, по материалам компании «Сетевые решения», производителя биллинговой системы LANBilling
Сетевые решения. Статья была опубликована в номере 09 за 2006 год в рубрике sysadmin
Использование сетей Wi-Fi с авторизацией на устройстве iPhone или iPad
Узнайте, как использовать сети Wi-Fi с авторизацией, которые являются общедоступными подписными или платными сетями.
Что такое сеть с авторизацией?
Такие сети еще называют «подписными» или «точками доступа Wi-Fi». Часто эти сети Wi-Fi действуют в кафе, интернет-кафе, гостиницах, аэропортах и других общественных местах. В некоторых странах и регионах операторы сотовой связи бесплатно предоставляют и обслуживают подписные сети.
Подключение к подписной сети Wi-Fi
- Нажмите «Настройки» > Wi-Fi.
- Нажмите имя сети и подождите, пока откроется экран входа. Можно также нажать кнопку «Подробнее» рядом с названием сети, а затем выбрать «Подключиться к сети».
- Если появится запрос, введите имя пользователя и пароль, введите адрес электронной почты или примите общие положения и условия.
После выполнения входа вы сможете получить доступ к Интернету. При использовании сетей Wi-Fi могут взиматься сборы и другие платежи. Чтобы получить дополнительную информацию, обратитесь к оператору связи.
Если подключение к сети отменяется до входа в сеть
При нажатии кнопки «Отмена» на экране входа устройство отключается от подписной сети Wi-Fi.
Если вы подключились к сети с экрана Wi-Fi, нажав кнопку «Подробнее» , то появится сообщение о том, что сеть не подключена к Интернету. Выберите один из приведенных ниже вариантов.
- «Исп. без Интернета». При выборе этого варианта закрывается экран приветствия, отключается автоматический вход для сети. Устройство остается зарегистрированным в сети, благодаря чему доступны другие способы использования сетевых ресурсов.
- «Другая сеть». При выборе этого варианта закрывается экран приветствия, отменяется регистрация устройства в сети. Снова открывается экран настроек Wi-Fi, где можно выбрать другую сеть.
- «Отмена». При выборе этого варианта произойдет возврат к экрану приветствия.
Если не удается автоматически подключиться к сети
Устройство iPhone или iPad может запомнить подписную сеть Wi-Fi и необходимую информацию для входа, чтобы автоматически подключаться к ней при попадании в зону действия.
Если устройство не подключается автоматически к подписной сети Wi-Fi, выполните следующие действия:
- Нажмите «Настройки» > Wi-Fi.
- Нажмите кнопку «Подробнее» рядом с названием сети.
- Убедитесь, что включена функция автоподключения к сети.
Если не требуется подключаться автоматически, отключите параметр «Автоподключение». Чтобы при следующем подключении к сети появился экран приветствия, отключите параметр «Автовход».
Информация о продуктах, произведенных не компанией Apple, или о независимых веб-сайтах, неподконтрольных и не тестируемых компанией Apple, не носит рекомендательного или одобрительного характера. Компания Apple не несет никакой ответственности за выбор, функциональность и использование веб-сайтов или продукции сторонних производителей. Компания Apple также не несет ответственности за точность или достоверность данных, размещенных на веб-сайтах сторонних производителей. Обратитесь к поставщику за дополнительной информацией.
Платный доступ к Wi-Fi
Организуйте у себя на объекте Premium Wi-Fi с платным доступом.
Создайте свой тариф с пакетами интернета в личном кабинете и подключите в настройках хотспота.

При подключении к WiFi гость выбирает пакет и оплачивает его с помощью банковской карты.
Отчёты по всем совершенным операциям доступны в личном кабинете.
В зависимости от месячного оборота мы взимаем комиссию на вывод средств.
В комиссию уже включены транзакционные сборы, онлайн обработка платежей и т.д.
Выплаты производятся по истечении календарного месяца.
Минимальная сумма для выплаты — 5 000 рублей.
| Месячный оборот | до 50 000 рублей | до 200 000 рублей | до 500 000 рублей | от 500 000 рублей |
|---|---|---|---|---|
| Комиссия оператора | 25% | 20% | 15% | По согласованию |
Пример расчёта №1:
За декабрь месяц Вы собрали платежей на 40 000 рублей. Комиссия на обслуживание составит 25%. Выплата в январе Вам составит 30 000 рублей.
Пример расчёта №2:
За май месяц Вы собрали платежей на 300 000 рублей. Комиссия на обслуживание составит 15%. Выплата в июне Вам составит 255 000 рублей.
Внимание! Выплаты производятся на расчётный счёт организации.
Премиум + Free доступ
Организуйте у себя на объекте комбинированный Wi-Fi:
- Бесплатный с авторизацией по номеру телефона и возможными ограничениями (по скорости и количеству бесплатных подключений в течении месяца)
- Премиум доступ с платными пакетами интернета (задайте скорость, длительность и цену в каждом пакете)
Пример настройки хотспота Premium Free.
Создадим Premium тариф со следующими пакетами:
- 10 мбит/с на 1 час за 30 рублей
- 10 мбит/с на 24 часа за 100 рублей
- 10 мбит/с на 30 дней за 300 рублей

В настройках хотспота зададим ограничение скорости 1 мбит/с — для бесплатных подключений.

В дополнительных настройках выберем созданный тариф для Premium и укажем количество бесплатных подключений в месяц с одного MAC устройства — 5.
В качестве способа доставки пользователю данных выберем Email+SMS

Запуская хотспот с такими настройками, получим следующее:
1. При подключении к хотспоту на странице авторизации будет выбор между бесплатным и платным доступом.

2. При выборе «Бесплатный доступ» — гость авторизуется по номеру телефона, при этом тратит одну бесплатную попытку.

3. После использования пяти бесплатных авторизаций — на странице будут отображаться только пакеты платного интернета.

Несколько примеров использования этого тарифа:
Торговый Центр.
Гости обычно не чаще нескольких раз в месяц посещают Торговый Центр. Им будет хватать бесплатных авторизаций. Продавцы и владельцы торговых точек могут злоупотреблять гостевым Wi-Fi и вместо отдельного интернет подключения — пользоваться только бесплатным. Владельцам Торгового Центра это не выгодно. Ограничения на бесплатные подключения вынудит торговые точки подключать себе отдельную линию с интернетом или приобретать платный пакет.
Удалённые базы отдыха.
На удалённых от инфраструктуры объектах зачастую интернет обходится недешево. Используя комбинированную схему Premium Free, владельцы таких заведений могут частично покрыть затраты на интернет. Бесплатно выдавать доступ на медленной скорости. А любителям хорошей скорости — придется заплатить за дополнительный комфорт.
Парковые зоны отдыха.
Нередко интернет-провайдеры в парках и общественных местах города устанавливают точки доступа с бесплатным Wi-Fi. Premium Free можно использовать не только для маркетинговых целей, но и для продажи высокоскоростного доступа.
Автоматическая аутентификация Android-устройства в Wi-Fi Московского Метро
Как известно, практически во всех вагонах Московского Метро действуют Wi-Fi точки доступа, с помощью которых пользователи могут получить доступ в интернет и приятно скоротать время поездки в метро с работы домой: почитать новости, проверить почту, посмотреть котиков на YouTube и т.д.
Каждому устройству, прежде чем ему будет предоставлен доступ к сети интернет, необходимо аутентифицироваться. В первый раз пользователю на указанный номер телефона посылается СМС с кодом, после чего система запоминает MAC-адрес устройства и в дальнейшем пользователю для аутентификации требуется только нажать на ссылку «Войти в интернет» и немного подождать.
Неудобством такой организации системы является то, что даже если пользователю не нужен браузер, а он, например, хочет залезть в почту или почитать твиттер с помощью специализированного приложения, ему все равно необходимо запустить браузер, попытаться получить доступ к какой-нибудь странице, дождаться переадресации, нажать ссылку, дождаться загрузки страницы приветствия (опционально: посмотреть рекламный ролик) и только после этого он сможет воспользоваться искомым приложением.
Если в метро вы не частый гость, то подобная схема может и не вызвать у вас раздражения, однако при ежедневном использовании она все таки надоедает, поэтому, как говорил один известный и харизматичный политик: «Хватит это терпеть!», сегодня мы будем автоматизировать аутентификацию в Московском метро.
В первую очередь нам понадобится приложение Tasker. Раздобыть его можно тут (за небольшую денежку), ну или где-нибудь тут (на свой страх и риск). Лично я предпочел первый вариант и не пожалел.
Tasker — приложение, которое позволяет в зависимости от определенных условий (дата/время/местоположение/состояние устройств/показания датчиков и т.д.) производить определенные действия (отправку сообщений/вывод уведомлений/включение-отключение устройств/отрисовка простеньких интерфейсов и т.д.). Списки и условий, и действий просто огромны и зависят от версии Android и аппаратного оснащения устройства, так что приводить их полностью смысла нет.
- Profiles — профили управляют связью между состоянием устройства/различными событиями и задачами;
- Tasks — задачи описывают последовательность действий, которые необходимо выполнить;
- Scenes — сцены это как бы самодельные формы, которые задачи могут создавать и настраивать, и контролы на которых могут запускать задачи;
- Vars — список глобальных переменных, которые могут быть использованы для хранения данных между запусками задач.
Перейдем на закладку Tasks и создадим новую задачу, назвав ее Metro Auth:

В открывшемся окне нам необходимо для начала определить несколько переменных. Переменные определяются следующим образом:

- Variable name — имя переменной, должно начинаться с символа % и состоять из строчных букв. Если в имени переменной будет хоть одна заглавная буква, то переменная станет глобальной, а нам это ни к чему;
- To — значение переменной.
- %url — содержит ссылку на страницу, по которой мы будем тестировать нужна ли аутентификация или нет. Чем меньше объем передаваемых данных при этом — тем лучше (тело страницы все равно не нужно). С протоколом HTTPS возможны проблемы, так что лучше использовать HTTP;
- %forms — содержит список идентификаторов HTML-форм, которые мы будем использовать для аутентификации. На момент написания статьи корректное значение — ‘auth-form,hidden_form‘, однако если ребята из московского метро вдруг что-то изменят, я хотел бы показать как составить такой список самостоятельно, так что пока в качестве значения поставим один пробел (пустые переменные недопустимы);
- %debug — эта переменная, при задании значения, отличного от нуля, будет вызывать показ дополнительной отладочной информации, которая поможет нам составить вышеупомянутый список форм.

Здесь необходимо выставить максимальный Timeout выполнения скрипта — 50 секунд, просто на всякий случай. Галочка Auto Exit отвечает за автоматическое завершения действия после завершения основного потока скрипта. В случае если используются асинхронные запросы (наш случай) или функция setTimeout, эту галочку необходимо снимать, а завершение действия определять самостоятельно с помощью функции exit();.
Сам скрипт я представлю в двух вариантах форматирования: приличное форматирование нужно если хочется рассмотреть скрипт, не сломав глаза, и форматирование под узкий экран позволяет скрипту выглядеть более-менее прилично на узком экране телефона. Изначально скрипт набирался на телефоне в «узком» варианте, и уже потом я переформатировал его для статьи:
Скрипт в приличном форматировании
function getUrl(url1,url2) < url1=url1.split('?')[0]; return url2.length? (/^http(s?):\/\//i.test(url2)?url2: (url2[0]=='/'?url1.split('/').slice(0,3).join('/')+url2:url1.split('/').slice(0,-1).join('/')+'/'+url2) ):url1; >function getVars(form,tag) < vars=''; fields=form.getElementsByTagName(tag); for(i=0;ifunction submit(xhr,request,form) < request.url=getUrl(request.url,form.action); request.method=form.method; vars1=getVars(form,'input'); vars2=getVars(form,'textarea'); request.vars=vars1||vars2?(vars1?vars1:'')+(vars1&&vars2?'&':'')+(vars2?vars2:''):null; getPage(request,processPage,xhr); >function processPage(xhr,request)< redir=xhr.getResponseHeader('Location'); if(redir)< if(redir==request.url) finalize('Ошибка: циклическое перенаправление'); else< log('Перенаправление\n\n'); getPage(,processPage,xhr); > > else < forms=local('forms').split(','); for(i=0;ielse finalize('Аутентификация успешна'); > > function checkConn(xhr,request)< redir=xhr.getResponseHeader('Location'); if(redir)< log('Перенаправление\n\n'); getPage(,processPage,xhr); > else < log('Аутентификация не требуется'); finalize(); >> function log(txt) < logs=logs+(txt?txt:''); >function requestToText(request) < return 'URL: '+request.url+'\nMethod: '+request.method+', Vars: '+request.vars+'\n\n'; >function finalize(txt) < log(txt); if(Number(local('debug'))) alert(logs); else if(txt) flashLong(txt); exit(); >function getPage(request,func,xhr) < if(!request.method) request.method='GET'; if(!request.vars) request.vars=null; if(!xhr)< xhr=new XMLHttpRequest(); xhr.responseType="document"; xhr.timeout=20*1000; >xhr.open(request.method,request.url,true); xhr.onload=function() < if(xhr.status==200 || xhr.status==401)< log (requestToText(request)+'HTTP status: '+xhr.status+' '+xhr.statusText+'\n'); func(xhr,request); >else < log(requestToText(request)); finalize('Ошибка HTTP: '+xhr.status+' '+xhr.statusText); >> xhr.onerror=function() < log(requestToText(request)); finalize('Ошибка: отсутствует соединение'); >xhr.ontimeout=function() < log(requestToText(request)); finalize('Ошибка: таймаут соединения'); >xhr.send(request.vars); > logs=''; getPage(,checkConn);
Скрипт в форматировании под узкий экран
function getUrl(url1,url2) < url1=url1.split('?')[0]; return url2.length? (/^http(s?):\/\//i.test(url2)? url2: (url2[0]=='/'? url1.split('/').slice(0,3).join('/')+url2: url1.split('/').slice(0,-1).join('/')+ '/'+url2) ):url1; >function getVars(form,tag) < vars=''; fields=form.getElementsByTagName( tag); for(i=0;ifunction submit(xhr,request,form) < request.url=getUrl(request.url, form.action); request.method=form.method; vars1=getVars(form,'input'); vars2=getVars(form,'textarea'); request.vars=vars1||vars2? (vars1?vars1:'')+ (vars1&&vars2?'&':'')+ (vars2?vars2:'') :null; getPage(request,processPage,xhr); >function processPage(xhr,request)< redir=xhr.getResponseHeader( 'Location'); if(redir)< if(redir==request.url) finalize('Ошибка: циклическое '+ 'перенаправление'); else< log('Перенаправление\n\n'); getPage(,processPage, xhr); > > else < forms=local('forms').split(','); for(i=0;ielse finalize( 'Аутентификация успешна'); > > function checkConn(xhr,request)< redir=xhr.getResponseHeader( 'Location'); if(redir)< log('Перенаправление\n\n'); getPage(,processPage, xhr); > else < log('Аутентификация не '+ 'требуется'); finalize(); >> function log(txt) function requestToText(request) < return 'URL: '+request.url+ '\nMethod: '+request.method+ ', Vars: '+request.vars+'\n\n'; >function finalize(txt) < log(txt); if(Number(local('debug'))) alert(logs); else if(txt) flashLong(txt); exit(); >function getPage(request,func,xhr) < if(!request.method) request.method='GET'; if(!request.vars)request.vars=null; if(!xhr)< xhr=new XMLHttpRequest(); xhr.responseType="document"; xhr.timeout=20*1000; >xhr.open(request.method, request.url,true); xhr.onload=function() < if(xhr.status==200 || xhr.status==401)< log (requestToText(request)+ 'HTTP status: '+xhr.status+' '+ xhr.statusText+'\n'); func(xhr,request); >else < log(requestToText(request)); finalize('Ошибка HTTP: '+ xhr.status+' '+xhr.statusText); >> xhr.onerror=function() < log(requestToText(request)); finalize('Ошибка: отсутствует '+ 'соединение'); >xhr.ontimeout=function() < log(requestToText(request)); finalize('Ошибка: таймаут '+ 'соединения'); >xhr.send(request.vars); > logs=''; getPage(,checkConn);
- Пытаемся загрузить страницу, указанную в переменной %url
- Если в ответе нет HTTP-заголовка Location, значит нас не перенаправляют, а значит в данный момент аутентификация не нужна, выход
- Загружаем страницу, на которую нас направили.
- Если есть заголовок Location, возвращаемся к п.3
- Если на странице есть форма из списка в переменной %forms, изображаем ее submit и возвращаемся к п.3
- В остальных случаях — мы успешно прошли аутентификацию
После завершения ввода скрипта, у нас получилась вот такая задача:

С помощью первой иконки в нижнем ряду можно попробовать ее запустить. Теперь самое время спускаться в метро, чтобы настроить ее!
В метро, подключившись к точке доступа, пробуем запустить задачу. Если нет явных проблем с доступностью серверов, то мы увидим сообщение, похожее на то, что изображено на следующем рисунке слева. Внизу мы видим идентификатор формы, которая есть на последней загруженной странице — auth-form. Эта форма — явно наш клиент, вносим ее название в переменную %forms и запускаем задачу еще раз, получаем примерно то, что изображено на следующем рисунке в центре. Новый идентификатор формы — hidden_form. Добавляем ее в переменную %forms, теперь ее значение будет ‘auth-form,hidden_form‘. Запускаем задачу еще раз и видим примерно то, что изображено на следующей рисунке справа — либо будет форма без идентификатора, либо пометка «отсутствуют» (зависит от ветки метро). Если теперь запустить браузер, будет понятно, что аутентификацию мы прошли. Присваиваем переменной %debug значение «0», и закрываем задачу — тут мы закончили.

Теперь дело за малым — настроить автоматический запуск задачи при подключении к нужной точке доступа. Переходим на закладку Profiles и создаем новый профиль, который будет активироваться после подключения к точке доступа московского метро. После того, как закончим формировать описание точки доступа, Tasker спросит нас с какой задачей связывать это профиль, выбираем, естественно, Metro Auth.

Еще одни нюанс: хотя и редко, но аутентификация все таки слетает, хотя отключения от точки и не происходило. Если не было отключения, не было и переподключения, а значит Tasker не запустит задачу повторно, поэтому мы настроим Tasker так, чтобы аутентификация автоматически проверялась каждые 2 минуты (минимальный возможный интервал), для этого нам надо долгим нажатием на уже сконфигурированное условие вызвать меню, в котором добавить временное условие, в котором установить интервал.

- Включить Wi-Fi;
- Дождаться сообщения «Аутентификация завершена» на экране;
- Загадочно улыбнуться и заняться своими делами.
UPD: По совету Self_Perfection я экспортировал проект и выложил одним файлом. Этот файл нужно скачать и положить в папку /sdcard/Tasker/projects, потом запустить Tasker, долгим нажатием на иконку домика в нижнем левом углу вызвать меню и выбрать Import. В этой версии я вынес проверку раз в две минуты в отдельный профиль — так должно расторопнее работать.