пятница, 11 марта 2011 г.

Security (безопастность) ч.2-идентификация

Security (безопасность)
Часть 2 - Механизм идентификации

1. HTTP Basic authentication (Базовая HTTP идентификация)
2. HTTP Digest authentication (Дайджест HTTP идентификация)
3. HTTPS Client authentication (HTTPS идентификация)
4. HTTP FORM-based authentication (HTTP идентификация базирующаяся на формах)
5. Определение механизма идентификации для веб-приложений.


1. HTTP Basic authentication (Базовая HTTP идентификация)

Базовая HTTP идентификация, определённая в HTTP 1.1, является простейшим типом идентификации.
Последовательность событий выглядит так:
1) Браузер делает HTTP запрос:
    GET /servlet/SalesServlet HTTP/1.1

2) Сервер возвращает HTTP ответ с кодом 401 Unauthorized и HTTP заголовком который говорит, что используется базовая идентификация. Так же указывается контекст именуемый realm.   
    HTTP/1.1 401 Unauthorized
    Server: Tomcat/5.0.25
    WWW-Authenticate: Basic realm="sales"
    Content-Length=500
    Content-Type=text/html
    <html>
        …detailed message
    </html>


3) После получения такого ответа браузер открывает диалоговое окно и предлагает ввести логин\пароль.
4) После ввода и нажатия кнопки "OK" браузер делает HTTP запрос вида:
    GET /servlet/SalesServlet HTTP/1.1
    Authorization: Basic am9objpqamo=

   
    Где am9objpqamo= это логин\пароль закодированный в Base64 кодировке. В данном случае здесь записано john:jjj. (Не стоит путать понятия закодированные и зашифрованные данные. Запись "am9objpqamo=" можно легко декодировать при помощи классов sun.misc.Base64Encoder и sun.misc.Base64Decoder).
   
ПЛЮСЫ:
 - Прост в использовании
 - Кросбраузеность

МИНУСЫ
 - Небезопасный, так как не используется шифрование
 - Вид диалогового окна зависит от браузера и не кастамизируется

2. HTTP Digest authentication (Дайджест HTTP идентификация)
Очень похож на базовую HTTP идентификацию, за исключением того, что пароль зашифрован.

ПЛЮСЫ:
 - Безопаснее базовой HTTP идентификации

МИНУСЫ:
 - НЕ поддерживается большинством браузеров (вообще говоря только некоторые версии IE поддерживают этот вид идентификации)
 - НЕ поддерживается многими видами контейнеров, так как спецификация не поддерживает его.

3. HTTPS Client authentication (HTTPS идентификация)
HTTPS - HTTP через SSL(Secure Socket Layer).SSL протокол был разработан Netscape чтоб обеспечить безопасность работы в Internet. Обобщенно это выглядит следующим образом: прежде чем передать какую-либо информацию устанавливается SSL соединение между сервером и браузером и вся последующая информация передаётся в зашифрованном виде. Используется шифрование с публичными ключами.

ПЛЮСЫ:
 - это самый безопасный метод идентификации из 4-х
 - все основные браузеры поддерживают HTTPS

МИНУСЫ:
 - для обеспечения SSL канала необходим сертификат, такой как VeriSign
 - трудоёмкое в реализации и поддержке

4. HTTP FORM-based authentication (HTTP идентификация базирующаяся на формах)     
Этот метод идентификации схож с базовой HTTP идентификацией, за исключением того, то используется HTTP FORM для получения логина и пароля. Реализуется достаточно просто: разработчик должен предоставить HTTP страницу с помещенным на неё FORM элементом. FORM должна иметь action атрибут равным j_security_check, атрибут method равным POST и 2 поля ввода j_username И j_password. Всё остальное кастаимзируется.
Пример:

<html>
    <body>
        <h4>Please login:</h4>   
        <form method="POST" action="j_security_check">
            <input type="text" name="j_username">
            <input type="password" name="j_password">
            <input type="submit" value="OK">
        </form>
    </body>
</html>


ПЛЮСЫ:
 - метод прост в реализации
 - все браузеры поддерживают этот метод идентификации
 - вид страницы легко кастамизируется

МИНУСЫ:
 - этот метод небезопасный, так как логин\пароль не зашифрованы
 - используется когда сессия поддерживает куки или HTTPS

5. Определение механизма идентификации для веб-приложений.
Механизмы идентификации определены в дескрипторе поставки web.xml, однако прежде мы должны определить пользователей, пароли и роли пользователей. Реализация этого этапа зависит от контейнера. В Tomcat это сделать просто:
Определение пользователей в Tomcat
Пользователи а томкете хранятся в <tomcat-root>\conf\tomcat-users.xml, который изначально выглядит +\- так:
<tomcat-users>
    <user name="tomcat" password="tomcat" roles="tomcat" />
    <user name="role1" password="tomcat" roles="role1" />
    <user name="both" password="tomcat" roles="tomcat,role1" />
</tomcat-users>


после нашего вмешательства файл выглядит следующим образом:
<tomcat-users>
    <user name="tomcat" password="tomcat" roles="tomcat" />
    <user name="role1" password="tomcat" roles="role1" />
    <user name="both" password="tomcat" roles="tomcat,role1" />

    <user name="petya" password="ppp" roles="employee" />
    <user name="vasya" password="vvv" roles="employee" />
    <user name="inokentiy sergeevich" password="iii" roles="employee, supervisor" />
</tomcat-users>


Итак, что изменилось. Было добавлено 3 пользователя: petya, vasya и inokentiy sergeevich с паролями соответственно ppp vvv и iii. Помимо пользователей добавлены 2 роли employee И supervisor. Концепция ролей очень важна в реальном мире, так как пользователей у системы может быть масса (от супер-начальников до обычных гостей) а роли позволяют ограничить доступ к той или иной информации. Так-же стоит заметить что любому пользователю можно назначить более одной роли.

Определение метода идентификации
Определение, какой же метод идентификации будет выбран происходит в дескрипторе поставки web.xml с помощью элемента <login-config>, который определяется следующим образом:
    <!ELEMENT login-config (auth-method?, realm-name?, form-loginconfig?)>
Рассмотрим подэлементы:
    <auth-method> определяет какой метод идентификации будет использован: BASIC, DIGEST, CLIENT-CERT или FORM
    <realm-name> определяет realm (realm это контекст идентификации, его значение показывается в диалоговом окне при базовой идентификации и служит для упорядочивания управления доступом к ресурсам и подсказывает пользователю какой логин\пароль следует использовать в данной ситуации).
    <form-login-config> определяет URL-ы для страницы идентификации и страницы ошибки. Используется в паре с auth-method равным FORM, в иных случаях просто игнорируется.

ПРИМЕРЫ:
Базовая идентификация:
<web-app>
    ...
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>sales</realm-name>
    </login-config>
    ...
<web-app>


Идентификация с помощью форм:
<web-app> 
     ...
      <login-config> 
         <auth-method>FORM</auth-method> 
         <!--realm-name not required for FORM based authentication --> 
         <form-login-config>
              <form-login-page>/formlogin.html</form-login-page>
              <form-error-page>/formerror.html</form-error-page> 
             </form-login-config>
      </login-config> 
     ...
<web-app>


где formlogin.html И formerror.html соответственно страница идентификации и страница ошибки идентификации.
formlogin.html была приведена ранее и выглядит следующим образом:
<html>
    <body>
        <h4>Please login:</h4>   
        <form method="POST" action="j_security_check">
            <input type="text" name="j_username">
            <input type="password" name="j_password">
            <input type="submit" value="OK">
        </form>
    </body>
</html>


а formerror.html может выглядеть:
<html>    
    <body>        
        <h4>Sorry, your username and password do not match.</h4>    
    </body>
</html>

среда, 9 марта 2011 г.

Security (безопастность) ч.1 - базовые понятия

Security (безопасность)
Часть 1 - базовые понятия

Список не претендует на полноту. Термины необходимые для сертификации.

1) authentication (идентификация)
2) authorization (авторизация)
3) data integrity (сохранность данных)
4) confidentiality or data privacy (конфиденциальность)
5) auditing (аудит)
6) malicious code (вредоносный код)
7) web site attack (атаки web-сайтов)

Authentication (идентификация)
Идентификация - процесс определения пользователя (будь то человек или другая программа) с последующей проверкой подлинности, то есть подтверждение что пользователь является тем (чем) представился. Обычно в интернете для авторизации пользуются логин\пароль парой.

Autorization (авторизация)
После идентификации пользователя идёт его авторизация.
Авторизация - процесс определения достаточно ли прав у пользователя для доступа к запрашиваемым ресурсам. Авторизация обычно реализуется на основе списков доступа (access control list - ACL), который содержит пользователей и их уровни доступа. 

Data integrity (сохранность\целостность данных)
Сохранность данных - процесс обеспечивающий неизменяемость передаваемых данных во время транзита от отправителя к получателю. Обычно реализуется на основе хеш-кодов или сигнатур передаваемых вместе с данными, после приёма получатель проверяет соответствие информации и хеш-кодов.

Confidentiality or data privacy (конфиденциальность)
Конфиденциальность - процесс обеспечения доступа к критичной информации исключительно заданными пользователями.
Например передача пары логин\пароль через HTTP происходит при помощи простого текста. Если эта информация попадёт в руки недоброжелателей то конфиденциальность нарушена. Обеспечение же конфиденциальности происходит при помощи шифрования данных. На сегодняшний день большинство web-ресурсов используют HTTPS протокол для шифрования передаваемой информации.В результате даже если часть пакетов данных будет перехвачена, злоумышленник не сможет использовать эту информацию.

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

Malicious code (вредоносный код)
Части кода которые могут повредить програмному обеспечению и\или данным называются вредоносным кодом. Это могут быть и вирусы и черьви и троянские кони. А иногда доморощенные разработчики оставляют лазейку в своих программах.

Web site attack (атаки web-сайтов)
Всё что считается ценным потенциально явлется целью злоумышленников. Web-сайты не являются исключением. Они могут быть атакованы различными типами людей и в различных целях. Кто-то получает от этого удовольствие, а кто то финансовую выгоду. Обобщенно существует 3 типа атак:
1) Атаки уровня конфиденциальности (secrecy attacks) - базируются на попытке украсть конфиденциальную информацию через анализ трафика между 2-я компьютерами. В этом случае помогает шифрование.
2) Атаки уровня сохранности\целостности (Integrity attack) - базируются на подмене части оригинальных сообщений на вредоносные во время транзита этих сообщений от отправителя получателю. IP-спуфинг (spoofing) один из распространенных способов. Суть в том, что злоумышленник отправляет сообщение в котором указывается IP дружественной системы и таким образом получает доступ к данным. Бороться с таким типом атак можно путём использования технологии строгой идентификации, таких как шифрование с публичными ключами.
3) Атаки доступности (Denial-of-service attacks OR availability attacks) - Суть в том, чтобы зафлудить систему фальшивыми сообщениям и она отказалась обслуживать реальные запросы.

четверг, 24 февраля 2011 г.

Listeners (хм .. Слушатели)

Для начала разобьём эту тему на под темы:
1. Listeners (Непосредственно слушатели).
2. Подключение слушателей
3. События и слушатели
4. Резюме

Listeners

Существует достаточно большое разнообразие Listener-ов. Для систематизации разделим их на несколько групп:

1. Attributes Listener (Слушатель Атрибутов)

2. Servlet Life-Cycle Events and Listener (События и слушатели жизненного цикла сервлета)


Attributes Listener (Слушатель Атрибутов) 
В зависимости от контекста (scope) различают следующих Listener-ов:

Request Scope (Контекст запроса): 
                  ServletRequestAttributeListener (javax.servlet)
Session Scope (Контекст сессии): 
                  HttpSessionAttributeListener (javax.servlet.http)
                  HttpSessionBindingListener (javax.servlet.http)
                  HttpSessionActivationListener (javax.servlet.http)
Context Scope (Контекст сервлет контекста):  
                  ServletContextAttributeListener (javax.servlet)

javax.servlet.ServletRequestAttributeListener
Этот Listener используется при "слушании" событий происходящих с атрибутами  запроса.

Метод                                                                                           Описание                          _
void attributeAdded(ServletRequestAttributeEvent srae)            Вызывается когда атрибут 
                                                                                                      добавляется в запрос

void attributeRemoved(ServletRequestAttributeEvent srae)        Вызывается когда атрибут 
                                                                                                       удаляется из запроса

void attributeReplaced(ServletRequestAttributeEvent srae)        Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                              _


 javax.servlet.http.HttpSessionAttributeListener
Этот Listener используется для "слушания" событий происходящих с атрибутами в сессии.
 Метод                                                                                          Описание                           _
void attributeAdded(HttpSessionBindingEvent se)                      Вызывается когда атрибут 
                                                                                                      добавляется в сессию

void attributeRemoved(HttpSessionBindingEvent se)                  Вызывается когда атрибут 
                                                                                                       удаляется из сессии

void attributeReplaced(HttpSessionBindingEvent se)                  Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                              _

javax.servlet.http.HttpSessionBindingListener
Этот Listener так-же используется для прослушивания событий происходящих с атрибутами в сессии. Разница между HttpSessionAttributeListener и HttpSessionBindingListener: 
HttpSessionAttributeListener: декларируется в web.xml (декларирование см ниже), экземпляр класса создается автоматически (контейнером) в единственном числе  и применяется ко всем сессиям
HttpSessionBindingListener: экземпляр этого класса должен быть создан и закреплён за определённой сессией программистом "вручную", количество экземпляров регулируется программистом.
 Метод                                                                                          Описание_                     _
void valueBound(HttpSessionBindingEvent se)                           Вызывается когда объект
                                                                                                     добавляется в сессию

void valueUnbound(HttpSessionBindingEvent se)                       Вызывается когда объект
                                                                                                     удаляется из сессии
_                                                                                                                                              _

javax.servlet.http.HttpSessionActivationListener 
Этот Listener используется атрибутами сессии в случае, если сессия будет "мигрировать" между различными JVM в распределённых приложениях.
 Метод                                                                                     Описание                              _
void sessionWillPassivate(HttpSessionEvent se)                     Вызывается перед тем, как сессия                                                                                                 станет пассивной перед миграцией

void sessionDidActivate(HttpSessionEvent se)                       Вызывается после того, как сессия   
                                                                                                 стала активной после миграции
_                                                                                                                                              _

javax.servlet.ServletContextAttributeListener
 Этот Listener используется для "слушания" событий, происходящих с атрибутами в сервлет контексте (ServletContext).
Метод                                                                                          Описание                              _
void attributeAdded(ServletContextAttributeEvent scae)          Вызывается когда атрибут 
                                                                                                    добавляется в ServletContext

void attributeRemoved(ServletContextAttributeEvent scae)      Вызывается когда атрибут 
                                                                                                    удаляется из ServletContext-a 

void attributeReplaced(ServletContextAttributeEvent scae)       Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                                  _

 Servlet Life-Cycle Events and Listener (События и слушатели жизненного цикла сервлета)

К слушателям событий жизненного цикла относятся следующие Listener-ы:
     ServletContextListener (javax.servlet)
     HttpSessionListener (javax.servlet.http)
     ServletRequestListener (javax.servlet)

 javax.servlet.ServletContextListener
Этот Listener позволяет разработчику "уловить" момент когда ServletContext инициализируется либо уничтожается. Его можно использовать, например, для открытия соединения с базой данных в момент создания контекста и закрытия соединения в момент уничтожения контекста.
Метод                                                                                          Описание                             _
void contextDestroyed(ServletContextEvent sce)                   Вызывается перед тем как ServletContext 
                                                                                                   будет уничтожен

void contextInitialized(ServletContextEvent sce)                   Вызывается сразу после создания
                                                                                                      ServletContext-a 
_                                                                                                                                                  _


javax.servlet.http.HttpSessionListener
Этот Listener позволяет разроботчику "уловить" момент создания и уничтожения сессии.

Метод                                                                                          Описание                               _
void sessionCreated(HttpSessionEvent se)                              Вызывается когда сессия создается

void sessionDestroyed(HttpSessionEvent se)                           Вызывается когда сессия уничтодается
_                                                                                                                                                   _

 javax.servlet.ServletRequestListener 
Этот Listener используется, соответственно, для того, чтоб "уловить" момент создания и уничтожения запроса.

Метод                                                                                          Описание                               _
void requestDestroyed(ServletRequestEvent se)                       Вызывается когда запрос уничтожается 

void requestInitialized(ServletRequestEvent se)                       Вызывается когда запрос инициализируется
_                                                                                                                                                   _

Подключение слушателей
Для описания того, как подключить Listener-ов обратимся с перво истокам web.xml-я, а именно к web-app_2_3.dtd взятых вот здесь. 

Root-овый элемент web-app:

<!ELEMENT web-app (icon?, display-name?, description?, distributable?, context-param*, filter*, filter-mapping*, listener*, servlet*, servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?, error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*, login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>

и соответственно сам элемент listener:

<!ELEMENT listener (listener-class)>

где listener-class: 

<!ELEMENT listener-class (#PCDATA)>

То есть можно добавлять любое количество listener-ов непосредственно в root-овый элемент web-app причём элемент listener обязан содержать 1 элемент - listener-class. 
Пример: 

<web-app>
    ...
    <listener>
        <listener-class>my.some.path.MyListenerClass</listener-class>
    </listener>
    <listener>
        <listener-class>my.some.other.path.MyOtherListenerClass</listener-class>

    </listener>
    ...
</web-app>

Отдельно стоит рассмотреть HttpSessionBindingListener, так как он подключается непосредственно в сессию в качестве атрибута. Тоесть, чтоб подключить этот listener необходимо: 
 - создать экземрляр класса реализующего этот интерфейс
 - положить созданый экземпляр в сессию при помощи setAttribute(String, Object)

Пример: 
Допустим есть класс наследующий HttpServlet с переопределённым методом doGet


public void doGet(HttpServletRequest req, HttpServletResponse resp) {
...
    MyInstanceOfHttpSessionBindingListener miohsbl = new MyInstanceOfHttpSessionBindingListener();
    HttpSession session = req.getSession();
    req.setAttribute("anyName", miohsbl);             <---- A
...
    req.setAttribute("anyName", new Object());     <---- B
....
{


метод valueBound класса MyInstanceOfHttpSessionBindingListener будет вызван в момент A, a метод valueUnbound в момент B.

События и слушатели
Соберём всё события и слушатели в одну "таблицу" :
Listener                                              Event                                           Самые значимые методы Event _
ServletRequestAttributeListener       ServletRequestAttributeEvent        public String getName()
                                                                                                              public Object getValue()

HttpSessionAttributeListener            HttpSessionBindingEvent               public String getName()
                                                                                                              public Object getValue()
                                                                                                              public HttpSession getSession()

HttpSessionBindingListener              HttpSessionBindingEvent               public String getName()
                                                                                                              public Object getValue()
                                                                                                              public HttpSession getSession()

HttpSessionActivationListener         HttpSessionEvent                            public HttpSession getSession()

ServletContextAttributeListener      ServletContextAttributeEvent        public String getName()
                                                                                                              public Object getValue()

ServletContextListener                     ServletContextEvent                      public ServletContext getServletContext()

HttpSessionListener                          HttpSessionEvent                           public HttpSession getSession()

ServletRequestListener                     ServletRequestEvent                      public ServletContext getServletContext()
                                                                                                              public ServletRequest getServletRequest()
 _                                                                                                                                                               _


Для простоты запоминаная: практически все пары listener\event имеют название ...Listener \ ...Event (ServletContextListener \ ServletContextEvent ... ) за 2-я исключениями: 
- HttpSessionAttributeListener, который в качестве параметра принимает HttpSessionBindingEvent 
- HttpSessionActivationListener, который принимает HttpSessionEvent              

Резюме
 - Cуществует множество задач решение которых станет (или уже стало) более простое и элегантное с применением listener-ов. 
 - Ещё одним удобным способом разбиения listener-ов на группы является разбиение исключительно по принципу контекста (scope):
Request:
    ServletRequestListener
    ServletRequestAttributeListener
Context
    ServletContextListener
    ServletContextAttributeListener

Session
    HttpSessionListener                  
    HttpSessionAttributeListener         
    HttpSessionBindingListener           
    HttpSessionActivationListener


вторник, 22 февраля 2011 г.

Подготовка к SCWCD.

Итак, SCJD уже позади и полным ходом идет подготовка к SCWCD. В качестве основных источников я взял:

1) Sun Certified Web Component Developer Study Guide издательство Oracle
2) SCWCD Exam Study Kit Second Edition: Java Web Component Developer Certification издательство Manning

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

В общем, вторая книга разделена на 3 части:

1. Getting started (Начнёмс)
2. Servlets (Сервлеты)
3. JavaServer Pages and Design Patterns (JSP и паттерны проэктирования)

И суммарно они деляться на 18 глав.

Так что далее последуют (я надеюсь) +\- 18 переводо-очерков о каждой из глав.