Аутентификация rest api с помощью spring security и mongodb

Содержание

Переключаемся на использование NTLMv2

Если вы задумались полностью отказаться от NTLM в своем домене, сначала нужно убедиться, что у вас не используется его более уязвимая версия- NTLMv1. Вероятно в вашей сети имеется ряд устаревших устройств или служб, которые все еще используют аутентификацию NTLMv1 вместо NTLMv2 (или Kerberos). Поэтому прежде, чем прибегнуть к его полному отключению прочитайте раздел этой статьи по аудиту событий авторизации с помощью NTLM.


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

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

Тип аутентификации можно задать с помощью доменной (или локальной) политики. Откройте консоль управления доменными политиками и отредактируйте Default Domain Policy. Перейдите в раздел Computer Configurations -> Policies -> Windows Settings -> Security Settings -> Local Policies -> Security Options и найдите политику

Network Security: LAN Manager authentication level (Сетевая безопасность: уровень проверки подлинности LAN Manager).

В настройках политики есть 6 опций:

  • Send LM & NTLM responses;
  • Send LM & NTLM responses – use NTLMv2 session security if negotiated;
  • Send NTLM response only;
  • Send NTLMv2 response only;
  • Send NTLMv2 response only. Refuse LM;
  • Send NTLMv2 response only. Refuse LM& NTLM.

Политики использования NTLM аутентификации расположены в порядке возрастания их безопасности. По умолчанию в Windows 7 и выше используется настройка Send NTLMv2 response only (Отправлять только NTLMv2-ответ). При этой настройке клиентские компьютеры используют NTLMv2 аутентификацию, но контролеры домены принимают LM, NTLM, и NTLMv2 запросы.

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

Вы можете изменить значение политики на более безопасную 6 опцию — “Send NTLMv2 response only. Refuse LM & NTLM”. При этой политике контролеры домена также будут отвергать запросы LM и NTLM.

Также вы можете отключить NTLMv1 через реестр. Для этого в ветке

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Lsa нужно создать параметр DWORD с именем LmCompatibilityLevel и значением от 0 до 5. Значение 5 соответствует значению политики «Отправлять только NTLMv2-ответ. Отказывать LM и NTLM».

В этом же разделе GPO убедитесь, что у вас включена политика Network security: Do mot store Lan Manager hash value on next password change (Сетевая безопасность: не хранить хэш-значения LAN Manager при следующей смене пароля). Эта политика включена по умолчанию, начиная с Windows Vista / Windows Server 2008 и запрещает создание LM-хэша.

Не забудьте применить эту политику для контроллеров домена.

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

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

Настольное приложение

В настольном приложении доступны следующие :

  • парольная;

  • ролевая;

  • доменная;

  • интегрированная доменная.

Дополнительно доступны:


  • двухфакторная аутентификация;

  • встроенная аутентификация.

Доступность базовых методов аутентификации зависит от используемой СУБД:

Тип СУБД \ Тип аутентификации

Парольная

Ролевая

Доменная

Интегрированная доменная

Oracle
Microsoft SQL Server 2008
Microsoft SQL Server 2012\2014\2016
Microsoft SQL Server (ODBC)
Teradata
PostgreSQL
SQLite
WEB Service

Условные обозначения:

— тип аутентификации доступен;

— тип аутентификации недоступен.

Парольная аутентификация

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

  1. Пользователь вводит логин и пароль в «Форсайт. Аналитическая платформа».

  2. «Форсайт. Аналитическая платформа» обращается к СУБД, используя предоставленные данные.

Ролевая аутентификация

Ролевая аутентификация аналогична парольной, производится с использованием логина и пароля. Доступ к объектам определяется по присвоенным пользователю ролям на сервере СУБД, которые совпадают с группами в «Форсайт. Аналитическая платформа».

Примечание. Ролевая аутентификация доступна только при использовании СУБД Microsoft SQL Server.

  1. Пользователь вводит логин и пароль в «Форсайт. Аналитическая платформа».

  2. «Форсайт. Аналитическая платформа» обращается к СУБД, используя предоставленные данные.

  3. СУБД возвращает список ролей пользователя. Список ролей сопоставляется со списком групп платформы. Пользователь получает права, соответствующие группам.

Доменная аутентификация

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

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

  1. Пользователь вводит доменное имя и пароль в «Форсайт. Аналитическая платформа».

  2. «Форсайт. Аналитическая платформа» передаёт указанные учётные данные на сервер СУБД.

  3. СУБД обращается к доменному контроллеру, доменный контроллер проверяет правильность указанных данных и делегирует «Форсайт. Аналитическая платформа» право на подключение от имени доменного пользователя с использованием временного билета.

Интегрированная доменная аутентификация

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

Метод аутентификации Kerberos:

При работе с СУБД Teradata интегрированная доменная аутентификация всегда осуществляется с использованием механизма аутентификации Kerberos. Для СУБД PostrgreSQL данный механизм может быть включён опциально в соединения с репозиторием.

Для работы по протоколу Kerberos на клиентском компьютере необходимо установить MIT Kerberos (не входит в комплект поставки «Форсайт. Аналитическая платформа»).

  1. Пользователь вводит доменное имя и пароль при входе в операционную систему.

  2. «Форсайт. Аналитическая платформа» передаёт указанные учётные данные на сервер СУБД.

  3. СУБД обращается к доменному контроллеру, доменный контроллер проверяет правильность указанных данных и делегирует «Форсайт. Аналитическая платформа» право на подключение от имени доменного пользователя с использованием временного билета.

Двухфакторная аутентификация

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

В «Форсайт. Аналитическая платформа» двухфакторная аутентификация в качестве первого типа аутентификации использует любой , в качестве второго  — сертификат пользователя.

  1. Пользователь выполняет базовую аутентификацию в «Форсайт. Аналитическая платформа».

  2. После запроса пользователь предоставляет «Форсайт. Аналитическая платформа» сертификат.

  3. При совпадении сертификата «Форсайт. Аналитическая платформа» обращается к СУБД, используя предоставленные данные.

Встроенная аутентификация

При встроенной аутентификации доступ к данным СУБД происходит под встроенным администратором. Проверка прав пользователя осуществляется на уровне платформы. Учётные данные администратора хранятся в зашифрованном виде. Встроенная аутентификация настраивается через .


  1. Пользователь вводит логин и пароль в «Форсайт. Аналитическая платформа».

  2. «Форсайт. Аналитическая платформа» проверяет разрешения пользователя и обращается к СУБД, используя учётные данные встроенного администратора.

Полное отключение NTLM в домене Active Directory

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

Protected Users (группа доступна, начиная с Windows Server 2012 R2), членам которой можно аутентифицироваться только по протоколу Kerberos (нельзя использовать NTLM, Digest Authentication или CredSSP). Так вы можете проверить корректность Kerberos аутентификации пользователя в различных приложениях.

Теперь вы можете полностью отключить NTLM в домене с помощью групповой политики Network Security: Restrict NTLM: NTLM authentication in this domain.

В этой политике доступно 5 опций:

  • Disable: политика отключена (NTLM аутентификация в домене разрешена);
  • Deny for domain accounts to domain servers: контролеры домена запрещают попытки аутентификации NTLM для всех серверов под доменными аккаунтами, возвращается ошибка «NTLM заблокирован»;
  • Deny for domain accounts: контролеры домена запрещают попытки NTLM аутентификации для всех учетных записей домена, возвращается ошибка «NTLM заблокирован»;
  • Deny for domain servers: запрещены запросы NTLM аутентификации для всех серверов;
  • Deny all: контроллеры домена блокируют все запросы NTLM для всех серверов и учетных записей.

Для дальнейшего эшелонирования защиты в AD рекомендую познакомиться со статьями «Защита от извлечения пароля из памяти утилитами а-ля mimikatz», «Защита учетных записей администраторов», отключение LLMNR и NetBIOS over TCP/IP.

Задача

Ранее мы писали приложения с формой логина, которую предоставляет  Spring Security (SS) по умолчанию. В этой статье так не получится, поскольку по умолчанию SS не поддерживает JWT. Сейчас будет чистый REST-сервис без фронтенда. Подразумевается, что фронтенд написан отдельно: например, на каком-нибудь JavaScript-фрейворке.

Для отправки запросов мы будем использовать программу POSTMAN. Например, для “входа” с именем/паролем и получения JWT-токена. А также для запроса защищенных страниц.

В этом примере наш старый REST-контроллер останется, а настройка Spring Security не особо поменяется – скорее, она дополнится.

  1. Мы добавим в приложение конечную точку /authenticate для аутентификации. Сюда приходят имя и пароль от пользователя. Приложение проверяет пароль, и если он верный, высылает пользователю в ответ JWT-токен.
  2. Во всех дальнейших запросах пользователь обязан высылать в заголовке JWT-токен, наше приложение проверяет подлинность токена в специально написанном фильтре JWTFilter и, если он корректен, пропускает запрос дальше.

Проблема входа в систему

То, что происходит после того, как OAuth 2.0 установил способ доступа к сторонним API, заключается в том, что приложение также требуется регистрировать пользователей у себя. Используя наш пример: HireMe123 нужно, чтобы пользователь MyCalApp мог залогиниться, используя свою учетную запись MyCalApp, даже несмотря на то, что он не был зарегистрирован в HireMe123.

Но, как мы упоминали выше, OAuth 2.0 предназначен только для делегированного доступа. Это не протокол аутентификации. Но это не помешало людям попытаться использовать его и для аутентификации, и это представляет проблему.

Проблемы с использованием токенов доступа для аутентификации

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

Например:

  • Кто-то мог украсть токен доступа у другого пользователя
  • Маркер доступа мог быть получен от другого клиента (не HireMe123) и введен в HireMe123

Это называется запутанной проблемой делегирования. HireMe123 не знает, откуда взялся этот токен и кому он был выдан. Если мы помним: аутентификация — это проверка того, что пользователь — это тот, кем он себя заявляет. HireMe123 не может знать это из-за того, что он может использовать этот токен доступа для доступа к API.

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

Факторы аутентификации

Ещё до появления компьютеров использовались различные отличительные черты субъекта, его характеристики. Сейчас использование той или иной характеристики в системе зависит от требуемой надёжности, защищённости и стоимости внедрения. Выделяют 3 фактора аутентификации:

Нечто, что нам известно, например, какая-либо секретная информация. Это тайные сведения, которыми должен обладать только авторизованный субъект. Секретом может быть некая фраза или пароль, например в виде устного сообщения, текстового представления, комбинации для замка или личного идентификационного номера (PIN). Парольный механизм может быть довольно легко воплощён и имеет низкую стоимость. Но имеет существенные недостатки: сохранить пароль в тайне зачастую бывает сложно, злоумышленники постоянно придумывают новые способы кражи, взлома и подбора пароля (см. бандитский криптоанализ, метод грубой силы). Это делает парольный механизм слабозащищённым.

Нечто, чем мы обладаем, например, какой-либо уникальный физический объект

Здесь важно обстоятельство обладания субъектом каким-то неповторимым предметом. Это может быть личная печать, ключ от замка, для компьютера это файл данных, содержащих характеристику

Характеристика часто встраивается в особое устройство аутентификации, например, пластиковая карта, смарт-карта. Для злоумышленника заполучить такое устройство становится более сложно, чем взломать пароль, а субъект может сразу же сообщить в случае кражи устройства. Это делает данный метод более защищённым, чем парольный механизм, однако стоимость такой системы более высокая.

Нечто, что является неотъемлемой частью нас самих — биометрика. Характеристикой является физическая особенность субъекта. Это может быть портрет, отпечаток пальца или ладони, голос или особенность глаза. С точки зрения субъекта, данный способ является наиболее простым: не надо ни запоминать пароль, ни переносить с собой устройство аутентификации. Однако биометрическая система должна обладать высокой чувствительностью, чтобы подтверждать авторизованного пользователя, но отвергать злоумышленника со схожими биометрическими параметрами. Также стоимость такой системы довольно велика. Но, несмотря на свои недостатки, биометрика остается довольно перспективным фактором.

Фильтр, проверяющий JWT-токен при каждом запросе


Итак, JWT-токен выдан, клиент его нам отправляет при каждом запросе, надо этот токен при каждом запросе проверять (и извлекать из него имя пользователя). Для этого напишем фильтр JWTFilter. Он расширяет OncePerRequestFilter и происходит в нем следующее:

  1. При каждом запросе из заголовка Authorization берем JWT-токен (он начинается с  префикса “Bearer“).
  2. Извлекаем из него имя пользователя (которое записывали при формировании токена).
  3. Проверяем подпись (validateToken())
  4. Если все ок, устанавливаем в SecurityContext объект Authencation (а в Authencation – UserDetails). Так нужно для Spring Security.
  5. Если с токеном не все ок, то фильтр не пропустит запрос в контроллер к защищенному /url.
@Component
public class JWTFilter extends OncePerRequestFilter {

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    CustomUserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }


        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            //если подпись неправильная, то SignatureException
            if (this.jwtUtil.validateToken(jwt, userDetails)) {


                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                        new UsernamePasswordAuthenticationToken(
                                userDetails, null, userDetails.getAuthorities());

                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }

}

Конечная точка аутентификации для выдачи JWT-токена

Тут собственно выдается  JWT-токен. Пользователь делает POST-запрос с именем и паролем по адресу /authenticate, а в ответ получает сгенерированынй токен. Токен генерится методом generateToken() из утилиты выше.

@RestController
public class AuthenticationController {


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JWTUtil jwtTokenUtil;


    @PostMapping("/authenticate")
    @ResponseStatus(HttpStatus.OK)
    public AuthResponse createAuthenticationToken(@RequestBody AuthRequest authRequest){
        Authentication authentication;
        try {
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authRequest.getName(), authRequest.getPassword()));
            System.out.println(authentication);
        } catch (BadCredentialsException e) {
            throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Имя или пароль неправильны", e);
        }

        final String jwt = jwtTokenUtil.generateToken((UserDetails) authentication.getPrincipal());
        System.out.println(jwt);

        return new AuthResponse(jwt);
    }
}

Запрос имеет такой формат:

public class AuthRequest {
    private String name;
    private String password;
    // геттеры сеттеры
}

А ответ такой:

public class AuthResponse {

    private String jwtToken;

   // геттер и сеттер
}

Если имя и пароль верные, токен возвращается в AuthResponse, а если нет – выбрасывается исключение и на фронтенд приходит сообщение об ошибке.

Фронтенд сохраняет у себя JWT-токен, и потом использует его при каждом запросе.

Немного о “разлогине”

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

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

В этом проблема JWT-токена  – нужды обходные пути для его инвалидации.

Перейдем ко второй принципиальной части – фильтру, проверяющему токен при каждом запросе.

Элементы аутентификации

  1. Субъект — пользователь
  2. Характеристика субъекта — информация, предоставляемая пользователем для проверки подлинности.
  3. Владелец системы аутентификации — владелец ресурса.
  4. Механизм аутентификации — принцип проверки
  5. Механизм авторизации — управление доступом

Методы аутентификации

  1. Парольные
  2. Комбинированные
  3. Биометрические
  4. Информация о пользователе
  5. Пользовательские данные

Парольные

Самый распространенный метод. Аутентификация может проходить по одноразовым и многоразовым паролям. Многоразовый пароль задает пользователь, а система хранит его в базе данных. Он является одинаковым для каждой сессии. К ним относятся PIN-коды, слова, цифры, графические ключи. Одноразовые пароли — разные для каждой сессии. Это может быть SMS с кодом. 

Комбинированные

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

Биометрические

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

Информация о пользователе

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

Пользовательские данные

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

Классификация видов аутентификации

В зависимости от политики безопасности систем и уровня доверия

  • Односторонняя. Пользователь доказывает право доступа к ресурсу его владельцу.
  • Взаимная. Проверяется подлинность прав доступа и пользователя и владельца сайта. Для этого используют криптографические способы.

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

Типы протоколов обусловлены тем, где происходит аутентификация — на PC или в сети.

Аутентификация на PC

  • Login
  • PAP (Password Authentication Protocol) — логин и пароль
  • Карта доступа — USB и сертификаты
  • Биометрические данные

Аутентификация в сети

  • Cookies. Используются для отслеживания сеанса, сохранения предпочтений и сбора статистики. Степень защиты невысокая, однако привязка к IP-адресу решает эту проблему.
  • Kerberos. Протокол взаимной аутентификации с помощью криптографического ключа.
  • SAML (Security Assertion Markup Language) Язык разметки, который позволяет сторонам обмениваться данными аутентификации.
  • SNMP (Simple Network Management Protocol) Протокол, который контролирует подключенные к сети устройства.
  • Сертификаты X.509 Сертификаты с открытым ключом.
  • OpenID Connect. Используется для создания единой учетной записи для аутентификации на разных ресурсах.

Стандарты

Документы, определяющие стандарты аутентификации

ГОСТ Р ИСО/МЭК 9594-8-98 — Основы аутентификации

Настоящий стандарт:

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

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

FIPS 113 — COMPUTER DATA AUTHENTICATION

Настоящий стандарт устанавливает Data Authentication Algorithm(DAA), который может быть использован для обнаружения несанкционированных изменений данных, как преднамеренных, так и случайных, стандарт основан на алгоритме, указанном в Data Encryption Standard(DES) Federal Information Processing Standards Publication(FIPS PUB) 46, и совместим как с Department of the Treasury’s Electronic Funds and Security Transfer Policy and the American National Standards Institute(ANSI) так и с Standard for Financial Institution Message Authentication.

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

Методы аутентификации

В зависимости от важности ресурса, для доступа к нему могут применяться разные методы аутентификации:

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

С этим читают