Как реализовать Security в Java EE? Часть 1

Первый раз когда я услышал о безопасности в ЕЕ приложениях, это вызывало у меня страх. Так как не понятно было вовсе что и как работает. Было масса литературы, но все разбросано по просторам интернета. Сегодня, для тех кто испытывает то что и я когда-то, предоставляю урок, где все будет собрано воедино.

 

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

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

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

Представьте что вы разрабатываете банковскую систему. Вокруг вашего приложения крутятся деньги и не малые. Думаю что всегда найдутся те люди, которые захотят эти деньги получить. И если нет системы защиты и надеяться только на честность людей, то проблем не схлопотать.

 

Шаг 1. Типы реализации

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

 

Ручная реализация

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

И если что-то пойдет не так, мы допустим ошибку в своем алгоритме, то приложение стает под угрозой перед злоумышленниками.

 

Реализация с помощью сервера приложений

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

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

 

Шаг 2. Основные понятия

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

4575_7

Аутентификация — проверка на существование человека(зарегистрированного) в нашем приложении. Является ли он тем, за кого себя выдает?

Авторизация — проверка прав аутентифицированного пользователя выполнять конкретные действия.

User — пользователь, информация о человеке, которая храниться у нас в базе или файле.

Group — группа пользователей,  которая имеет одинаковые характеристики и права доступа.

Security Realm — специальная область отвечающая за аутентификацию пользователя и хранит ее настройки.

Role — определяет уровень доступа. Определяет какие действия может выполнять пользователь или группа.

 

Шаг 3. Настройка безопасности

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

4575_1

Мы создали основную структуру. Пока что нету ничего кроме статического html. Сейчас все ссылки доступны с приложения и можно дойти к любому файлу. Есть специально создано 2 ресурса: public, secured. Первым делом, ограничим доступ ко всему что находиться внутри secured folder. Для этого создаем внутри webapp директорию WEB-INF, и прописываем дескриптор развертывания web.xml.

4575_2

Пример файла web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>secured</web-resource-name>
            <url-pattern>/secured/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>MANAGER</role-name>
        </auth-constraint>
    </security-constraint>

    <security-role>
        <role-name>MANAGER</role-name>
    </security-role>

</web-app>

security-constraint — блок ограничений безопасности(настраиваем права доступа и метод(GET,POST..)).

web-resource-collection — ресурсы, к которым стоит закрыть доступ, ввести ограничение.

web-resource-name — название ресурса.

url-pattern — запрос, к которому будет применена безопасность.  * — указывает что все что идет после также попадает под настройки безопасности. /security/* — будет закрывать доступ для всех адресов вида: /security/1.html, /security/posts/1/.

http-method — метод к которому применим фильтр безопасности.

auth-constraint — выставляем роли доступа.

security-role — прописываем роль.

role-name — указываем роль.

Результат работы по рут:

4575_3

 

Результат, при доступе к закрытой страничке: Forbidden

Теперь у нас есть закрытый доступ к ресурсам, которые находятся по адресу secured/, доступ к содержимому имеет только менеджер. Но как указать что мы являемся менеджером?

 

Шаг 4. Аутентификация

Добавим теперь нашему приложению возможность аутентификации, которая есть у нас по умолчанию. Методы аутентификации:

1. BASIC — Здесь используется стандартная форма ввода данных для аутентификации.

<login-config>
        <auth-method>BASIC</auth-method>
</login-config>

При доступе к закрытым ресурсам вы увидите окно, которое попросит вас ввести свои данные.

 

2.FORM — Здесь используем свою html форму. Делаем настройки в web.xml:

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.html</form-login-page>
        <form-error-page>/error.html</form-error-page>
    </form-login-config>
</login-config>

login-config — конфигурация аутентификации.

auth-method — каким методом проводить аутентификацию. Если выбираем FORM, то нужно ввести дополнительную информацию:

form-login-config — дополнительная информация при использовании своей формы

form-login-page — url логина

form-error-page url ошибки логина.

Создаем нашу форму:

<form action="j_security_check" method="post">
    Input for username:<br>
    <input name="j_username" type="text"><br>
    Input for password:<br>
    <input name="j_password" type="password"><br>
    <input type="submit" value="Авторизироваться">
</form>

Соглашения, которых стоит придерживаться при использовании безопасности сервера приложений.

j_security_check action при нажатии на submit

j_username — поле имя пользователя

j_password — поле пароля

Форма(без стилей и ничего лишнего):

4575_6

3.DIGEST — цифровая аутентификация

4.CLIENT-CERT — аутентификация с помощью клиентского сертификата.

Последние два мы не будем рассматривать в нашем примере.

 

Шаг 5. Настройка сервера приложений

Теперь, осталось настроить наш сервер приложений и связать его с нашим приложением. Для связки, в зависимости от сервера, в приложении используется специальный файл, который имеет название: *-web.xml.

JBoss, WildFly: jboss-web.xml

GlassFish: sun-web.xml

Создаем нужный нам файл в директории WEB-INF.

В данном случае мы будем использовать properties файлы у нас на сервере, что будут хранить данные о пользователях.

Пример файла jboss-web.xml:

<jboss-web>
 <security-domain>java:/jaas/other</security-domain>
</jboss-web>

Теперь добавим пользователя, у которого будет право на просмотр скрытой информации. Для этого используем консольное приложение которое находиться в директории bin/add-user.sh (Linux), bin/add-user.bat (Windows).

4575_7

После чего, если у Вас был запущен сервер — перезапускаем и пробуем зайти на защищенные странички.

4575_8

И после корректного логина, мы попадаем на защищенную страницу.

4575_9

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

 

Шаг 6. Использование безопасности в сервлетах

Здесь очень кратко покажу базовые настройки для сервлетов. Для этого, создадим 2 сервлета в нашем проекте.

4575_10

 

SecuredServlet1 — если посмотреть на адресс, защищен с помощью настроек в web.xml

@WebServlet(urlPatterns = "/secured/servlet1")
public class SecuredServlet1 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
                                                 throws ServletException, IOException {
        resp
                .getWriter()
                .write("<h1>Secured Servlet1</h1>");
    }
}

 

SecuredServlet2 — имеет свои настройки безопасности и не попадает под настройки дескриптора.

@WebServlet(urlPatterns = "/servlet2")
@ServletSecurity(httpMethodConstraints = {
        @HttpMethodConstraint(value = "GET", rolesAllowed = "MANAGER"),
        @HttpMethodConstraint(value = "POST", rolesAllowed = "MANAGER")
})
public class SecuredServlet2 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
                                                 throws ServletException, IOException {
        resp
                .getWriter()
                .write("<h1>Secured Servlet2</h1>");
    }
}

@ServletSecurity — определяет настройки безопасности

@HttpMethodConstraint — ограничения для каждого метода доступа

    value — http method (GET,POST….)

    rolesAllowed — роль, которая может получить доступ.

 

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

Результат доступа к сервлету 2.

4575_11

После авторизации вы увидите следующее:

4575_12

Урок создан: 30 июня 2014 | Просмотров: 24350 | Автор: Олег Криль | Правила перепечатки


Добавить комментарий

Добавить комментарий

Ваш e-mail не будет опубликован.

Комментарии:

  • 07 июля 2014 в 00:43

    Антон

    А как сделать кнопку «Выход»?

    • 07 июля 2014 в 18:56

      Олег Криль

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

      • 21 июля 2014 в 22:25

        theNatd

        Всегда пугала именно эта часть и как то приходилось её обходить, делал в jax-rs проверку токена в интерцепторе, роли хранил в базе, соответственно в интерцепторе проверял роли у пользователя.

        Расскажите лучше этот момент, как лучше сделать если роли хранятся в базе.

  • 21 октября 2014 в 14:52

    Игорь

    Изображения пропали

    • 22 октября 2014 в 11:27

      Александр Барчук

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

  • 03 декабря 2014 в 16:59

    Платон

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

  • 26 января 2015 в 04:03

    Никита

    Побились многие картинки, вы не могли бы их поправить?

  • 27 февраля 2015 в 18:01

    Илья

    Изображение возможно востановить или нет?

  • 17 июля 2015 в 14:39

    Igor

    Алексанр, я каждый день пользуюсь Вашим сайтом, как учебным пособием для начинающих, прискорбно, что Вы прекратили поддержку данного ресурса.
    Вы бы не могли перезалить рисунки по битым ссылкам?
    Заранее благодарен от всех пользователей, которые пользуются Вашим ресурсом!

  • 17 июля 2015 в 22:39

    mike

    картинок не видно!!!!!!!!!

  • 10 августа 2015 в 08:29

    Oskar

    можешь сделать аналогичный пример с использованием логина и пароля из баз данных?!

  • 02 марта 2016 в 18:00

    Elm

    Пропали картинки к статье.

  • 12 октября 2016 в 10:22

    Анатолий

    Ваши уроки помогают, спасибо большоае. Но такое чувство, что на проект «забили», восстановить изображения уже 1.5 года просят. Очень жаль :(

  • 31 октября 2016 в 14:03

    Игорь

    Добрый день! Не могли бы вы восстановить картинки? Они в путях на русском, может из-за этого не отображаются.