Monday, September 22, 2008

Single Sign-On в интеграционных проектах IIS и Java

Описание проблемы


Для одного из наших проектов нужно было разработать несколько новых компонентов для существующего решения - web-портала.

Портал написан на ASP (даже не ASP.NET) с MS SQL Server 2000 и до сих пор поддерживается - периодически выходят новые версии.

Одним из требований заказчика была поддержка функции Single Sign-On между существующими и разрабатываемыми компонентами.

В этом посте я хочу рассказать о тем чем я руководствовался при разработке архитектуры решения и как в итоге был реализован механизм SSO. Забегая вперед, отмечу, что данное решение может подойти для интеграционных проектов, в которых есть необходимость организовать SSO между существующими web-приложениями (ASP/PHP) и вновь разрабатываемыми на Java EE компонентами.

Выбор инструмента


Платформа


Из соображений лицензионной чистоты и снижения лицензионных отчислений было принято решение разрабатывать новые компоненты с использованием стека Open Source решений и, в частности, на платформе Java. Если кому-то интересно почему Java - обращайтесь в комментарии - это не тема для данного поста :)

В последнее время мне очень нравится Open Source линейка OpenX, поддерживаемая открытым сообществом dev.java.net во главе с Sun Microsystems. Особенно привлекает NetBeans, который является по-настоящему мощной и, поправьте если я не прав, первой в мире и единственной бесплатной Open Source RAD для разработки Java-приложений (включая Java ME/SE/EE), чем не может похвастаться ни одна другая IDE (включая Eclipse и IDEA).

Eclipse, как IDE, мне нравится больше NetBeans, особенно JDT и его Java Editor, который в разы превосходит NetBeans по функциональности. Но Eclipse очень сильно проигрывает NetBeans в плане RAD. Многие знают, что на базе Eclipse есть разные реализации RAD (от IBM, ориентированная на линейку WebSphere; от SAP для NetWeaver), но все они платные и, поэтому, не идут ни в какое сравнение с NetBeans.

Что мне особенно нравится у NetBeans - это набор его WYSIWYG-редакторов GUI и различные мастера конфигураций, которые очень сильно сокращают время разработки. Именно этим мы и хотели воспользоваться.

Single Sign-On


На тот момент я был знаком лишь с одним фреймворком, поддерживающим SSO - это JOSSO.

JOSSO позволяет организовать SSO между веб-приложениями, физически расположенными в рамках одного сервера приложений. После того, как пользователь прошел аутентификацию в одном из "партнерских" приложений JOSSO, серверный агент JOSSO запоминает его логин и членство в ролях. При последующих обращениях пользователя к партнерским приложениям, агент автоматически пытается аутентифицировать пользователя, избавляя его от повторного ввода пароля. Эта схема работает на Tomcat. Существуют агенты и для других серверов приложений.

Но именно из-за того, что JOSSO не поддерживает Glassfish, я побоялся остановить на нем свой выбор - Glassfish еще слишком молодой и не имеет большой поддержки со стороны Open Source сообщества.

В линейке OpenX есть продукт Open SSO, поддерживающий Glassfish, но реализованного агента для IIS у этого продукта не было.

У JOSSO есть агент для IIS, но, как потом выяснилось, и JOSSO, в дополнение к вышесказанному, и Open SSO под Single Sign-On понимают немного другую схему аутентификации - схему основанную на токенах.

В этой схеме приложение, проводя процедуру аутентификации пользователя, получает у Identity Provider'а токен - сессионный ключ. Этот ключ может передаваться между партнерскими приложениями, например, через Cookies. В такой схеме, имея сессионный токен пользователя, приложение самостоятельно может запросить у централизованного сервиса права пользователя и провести процедуру авторизации.

В нашем случае это означало бы полностью переписать функции аутентификации и авторизации портала по новой схеме, что было бы крайне нежелательно, так как требовало бы больших усилий при разработке и применении новых обновлений портала. Кроме того ASP и MS SQL Server 2000 - это устаревшие технологии и никаких новых стратегических компетенций мы бы не получили с этого проекта.

Исходя из всего вышесказанного было принято решение в качестве сервера приложений выбрать Apache Tomcat - наиболее распространенный и широко поддерживаемый открытым сообществом Open Source сервер приложений (я знаю, что там только web-контейнер, нам больше не надо :). Решение было принято из расчета на то, что если и можно сделать SSO на Java, то на Tomcat это решение заработало бы с вероятностью 99.999%.

Описание решения


В основе найденного решения лежит The Apache Tomcat Connector - "мостик", который используется для запуска Tomcat за web-серверами, такими как Apache HTTPD и Microsoft IIS.

В этой схеме весь HTTP-трафик пользователя проходит через web-сервер (в нашем случае IIS) и передается Tomcat'у, который обрабатывает запрос и возвращает результат.

Это возможно за счет ISAPI-фильтра, который отвечает за перенаправление всех HTTP-запросов. Такое перенаправление возможно за счет поддержки Tomcat'ом бинарного протокола AJP13, по которому происходит эта передача. Возможно другие сервера также поддерживают AJP13 и для них можно организовать аналогичную схему - я не пробовал, но если у кого-то получится, большая просьба отметиться в комментариях.

Особенности решения


Аутентификация пользователей в портале ASP осуществляется путем сохранения информации об имени пользователя и его членства в ролях, которая сохраняется в объекте ASP Session (сессия приложения).

Если бы аутентификация осуществлялась стандартными средствами, например, HTTP Basic Authentication, то в Java EE приложении имя пользователя можно было бы получить через интерфейс HttpServletRequest.getRemoteUser(...).

Но так как сессия лежит за границами протокола HTTP, из Java непосредственно нельзя получить к ней доступ. Однако в HTTP-заголовках передаются Cookies, в которых сохраняются сессионные ключи приложений (JSESSIONID, PHPSESSIONID, ASPSESSIONIDxxx).

Благодаря этому мы можем обратиться к приложению по протоколу HTTP, передав сессионный ключ и попасть в контекст нужной сессии, где нам будет доступна вся необходимая информация.

Реализация


Для этого в партнерское приложение достаточно добавить страницу sessioninfo.asp следующего содержания:

UserID=<%=Session("UserID")%>
UserType=<%=Session("UserType")%>


Соответственно, из Java приложения, чтобы получить информацию о пользователе (в данном случае это его идентификатор и тип, на основании которых можно сделать запрос к БД и получить всю дополнительную информацию, если это необходимо), достаточно обратиться по адресу, например, http://localhost/asp-portal/sessioninfo.asp и рас-parse-ить результат:

01: <%@ page contentType="text/html; charset=iso-8859-1" language="java" %>
02: <%@ page import="java.net.*"%>
03: <%@ page import="java.io.*"%>
04: <%@ page import="java.util.Properties"%>
05:
06: <%
07: Cookie[] cookies = request.getCookies();
08:
09: String value = "";
10:
11: for (int i = 0; i < cookies.length; i++) {
12: Cookie cookie = cookies[i];
13: value += cookie.getName() + "=" + cookie.getValue() + ";";
14: }
15:
16: URL url = new URL("http://localhost/asp-portal/sessioninfo.asp");
17:
18: URLConnection c = url.openConnection();
19:
20: c.setRequestProperty("Cookie", value);
21:
22: InputStreamReader in = new InputStreamReader(c.getInputStream());
23:
24: Properties p = new Properties();
25: p.load(in);
26:
27: in.close();
28: %>


При таком подходе на каждый запрос к Java-компоненту идет обратный дополнительный запрос к ASP-порталу. Вопрос производительности для нас не был критичным, но в несколько миллисекунд обратный запрос укладывался.

Остается отметить, что чтобы браузер передавал Cookies Java-приложению они должны быть в одном домене (URL) с порталом. Для других проектов это может быть ограничением, но в нашем случае это было скорее требованием.

Источники информации


Инструкцию по настройке Tomcat и IIS можно найти здесь: How To Configure IIS 6.0 and Tomcat with the JK 1.2 Connector. Мне пришлось немного изменить описанный сценарий, моя установка отказалась принимать приведенный там в примере файл workers.properties и я написал свой, руководствуясь вот этой документацией.

Thursday, September 11, 2008

0xCAFEBABE

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

Думаю программистам будет интересно узнать, что сигнатура *.class-файла начинается с байтов 0xCAFEBABE :)



P.S.
Навеяно предыдущим постом :)

Get Her With Java



Hibernate порадовали :)

Wednesday, September 03, 2008

7 показателей эффективного управления личными финансами

Для начала небольшая предыстория вопроса.

Ленивые могут пролистать пост вниз, прямо к скриншоту, и попытаться разобраться самостоятельно, но сразу предупрежу, что без собственной такой предыстории и разбирательств в вопросе управления личными финансами вы вряд ли осознаете необходимость и практическую значимость того, что там увидите.

Итак, прошло уже больше двух месяцев, как мы с Настей начали планировать домашний бюджет. За основу мы решили взять советы Макса Крайнова и его идею о "4 конвертах".

Почему именно ее? Потому что приблизительно в то время я наткнулся на блог Макса и попал на период, когда он только начал развивать идею с конвертами. Кажется это был апрель-май.

У меня заняло около месяца на знакомство с идеей 4 конвертов и вообще знакомством идеи ведения домашнего бюджета.

Еще через месяц появился его online-сервис www.4konverta.com, который стал эталонной реализацией идеи "4 конверта". При работе с этим сервисом я очень скоро уперся в его функциональные ограничения (в нем еще попросту не было нужных функций, некоторые и сейчас находятся на стадии активной разработки), не удивительно - ведь сервис еще только набирает обороты, привлекая все больше людей.

Этот момент совпал с нашим очередным переездом на новую квартиру, где у меня попросту не было интернета. У меня не было даже тех 30 секунд в день для заполнения ежедневных трат, про которые так часто говорит Макс.

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

Одновременно с этим стало понятно, что без актуальной первичной информации в "конвертах", то есть данных о ежедневных тратах, я не смогу получить достоверную картину и, следовательно, не смогу доверять данным сервиса.

Задолго до 4 конвертов мы с Настей пытались собирать чеки, чтобы хотя бы примерно попытаться построить прогноз - сколько мы тратим и на что. Но из-за того, что очень часто чеки либо терялись, либо мы просто забывали их брать этот прогноз получался очень неточным (около 30% месячного дохода терялось в неизвестном направлении). Логичным решением был отказ от сбора чеков и переход на 4 конверта, то есть заносить все траты непосредственно туда. Именно тогда у меня родилась идея написать приложение для своего мобильного телефона, через которое я бы смог заносить текущие траты непосредственно по факту их совершения.

Я написал это приложение за одни выходные. Идея мобильного клиента мне настолько понравилась, что я решил сделать его доступным для всех, выпустив его под бесплатной Open Source лицензией, чтобы каждый пользователь сервиса "4 конверта" смог решить для себя вопрос учета ежедневных трат раз и навсегда. Сегодня, после выхода последнего обновления (10 дней назад), мобильную версию 4 конвертов закачали около 100 человек и эта цифра постоянно растет!

По просьбе пользователей я также выпустил версию клиента для платформы Windows Mobile, но решил сделать эту версию платной. Почему? Потому что сам ей не пользуюсь и просто хочу вернуть деньги за время, потраченное на разработку.

Кроме того, я считаю, что сам мобильный клиент стоит своих денег, ведь ошибка в собственном прогнозе из-за неверных данных может стоить гораздо больше, чем эти копейки.

О каком прогнозе идет речь? Для начала пара примеров, как мы жили раньше.

Например, у нас могли закончится деньги до зарплаты, и в это же время нужно было платить кредит. Или могло быть так, что за неделю до зарплаты мы с Настей могли сходить в ресторан и потратить последние деньги, оставив себе 500 рублей на неделю до следующей получки :)

Сейчас я вспоминаю об этом с улыбкой :), но я с большим удивлением обнаружил, что все мои знакомые и друзья до сих пор находятся в таком положении - они не могут контролировать свои траты. Они даже не знают сколько у них денег и не представляют, увеличивается ли их капитал или они тратят больше, чем получают и вскоре их ждет ситуация, как у большинства - они в лучшем случае будут жить от зарплаты до зарплаты, как мы раньше, отказывая себе во многом.

Сервис "4 конверта" позволил дать ответы на большинство этих вопросов. Как минимум он позволяет задуматься о положении дел!

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

Не дожидаясь реализации нужных мне функций, я перенес основные идеи из сервиса "4 конверта" себе в Excel. Сегодня моя книга кэш-фло выглядит примерно таким образом:


В нижней части - учет движения денежных потоков, включая все плановые и фактические доходы и расходы, а также затраты на конверты, то есть на ежедневные траты.

Все наличные/безналичные деньги, которые не в резервном фонде я объединил под одним названием - подвижный остаток. Эти деньги я могу разложить по конвертам уже сегодня и хоть на год вперед. Исходя из плановых доходов и плановых расходов на конверты я всегда вижу какой минимальный подвижный остаток у меня будет на руках и когда я смогу уйти "в минус", если вдруг лишусь доходов или просто будет задержка в зарплате.

Кроме того, я всегда могу оценить размер своего капитала на каждый день на год вперед.

Зная величину капитала я могу построить тренд, который мне покажет - превышают ли мои расходы мои доходы и насколько это критично.

И еще одна функция, которая мне очень нравится в Excel - это анализ "Что-если".

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

А задействуя функцию "Что-если" я могу подобрать величину размера конверта по умолчанию таким образом, чтобы, например, мой минимальный подвижный остаток в течении года не был ниже 20000 рублей.

И если меня устраивает мой тренд, я могу смело руководствоваться величиной размера конверта по умолчанию как эталоном.

Собственно, вот эти 7 показателей на которые я смотрю строя прогнозы и принимая решения о тратах:

  1. Размер конверта по умолчанию - сколько мне можно тратить в неделю, чтобы сохранялся прогноз;

  2. Процент резервного фонда - какой процент от дохода я сразу же перечисляю в резервный фонд;

  3. Процент на дополнительный доход - какой процент от дополнительного дохода (премии и прочие нерегулярные доходы) я должен перечислить в резервный фонд;

  4. Минимальный остаток - минимальный подвижный остаток, начиная с сегодняшнего дня;

  5. Минимальный капитал - минимальный капитал, начиная с сегодняшнего дня;

  6. Обращения к резервному фонду - количество обращений к резервному фонду, когда подвижного остатка недостаточно для плановых трат;

  7. Направление тренда капитала - если тренд отрицательный, значит я трачу больше, чем зарабатываю и нужно обратить на это внимание.

В заключении хочу сказать, что вместо неопределенности в 30% по движению денег, последняя сверка (план-факт) показала точность прогноза в пределах 1-2%.

На этом на сегодня все. В качестве обзора моей текущей аналитики и показателей эффективности управления личными финансовыми потоками, и как пища для размышления Максу и команде сервиса "4 конверта", я думаю пока что вполне достаточно.

Буду рад любым отзывам и комментариям.

Tuesday, September 02, 2008

Скриншоты мобильной версии "4 конверта"


Сегодня я наконец-то выложил скриншоты мобильного клиента "4 конверта".

Там же доступна пошаговая инструкция по использованию клиента.

Эти скриншоты сделаны для Windows Mobile-клиента. Следует отметить, что он также будет работать на обычном персональном компьютере, для этого достаточно установить .Net Compact Framework 3.5 (собственно, скриншоты так и сделаны - на Windows Vista).

Java-версия содержит абсолютно идентичные экранные формы и набор функций, поэтому отдельно для него я не буду делать снимков. К тому же, в отличие от Windows Mobile-версии этот клиент распространяется бесплатно под Open Source лицензией, так что любой сможет скачать и посмотреть его вживую.