Как сделать секьюрити пароль

Добавил пользователь Валентин П.
Обновлено: 04.10.2024

В этом уроке мы покажем вам, как использовать BCryptPasswordEncoder хэшировать пароль и выполнять аутентификацию при входе в Spring Security.

В старые времена, как правило, мы использовали MD5 Md5PasswordEncoder или SHA ShaPasswordEncoder алгоритм хеширования для кодирования пароля … вам все еще разрешено использовать любой кодировщик, который вам нравится, но Spring рекомендует использовать BCrypt BCryptPasswordEncoder более сильный алгоритм хеширования со случайно сгенерированной солью.

  1. Весна 3.2.8. ВЫПУСК
  2. Spring Security 3.2.3.RELEASE
  3. Spring JDBC 3.2.3.RELEASE
  4. MySQL Server 5.6

1. Просмотрите PasswordEncoder

Знакомая старая аутентификация PasswordEncoder интерфейс устарел …

Вместо этого вы должны использовать этот новый крипто PasswordEncoder интерфейс.

2. Создайте пароль BCrypt

В алгоритме хеширования BCrypt каждый раз генерируется другое значение хэша длины 60.

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

3. База данных

4. Включить Password Encoder

Несколько способов включить кодировщик паролей в конфигурации XML.

4.1 Использование BCryptPasswordEncoder по умолчанию.

4.3. Передайте кодировщик в DaoAuthenticationProvider .

4.4 Пример аннотации.

5. Демонстрация проекта

Как кодировать пароль при регистрации (и аутентификации) нового пользователя – с помощью Spring Security и BCrypt.

1. Обзор

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

Существует несколько механизмов кодирования, поддерживаемых Spring Security – и для этой статьи мы будем использовать BCrypt , так как это обычно лучшее доступное решение.

Большинство других механизмов, таких как MD5PasswordEncoder и ShaPasswordEncoder , используют более слабые алгоритмы и теперь устарели.

Дальнейшее чтение:

Новое Хранилище Паролей В Spring Security 5

Разрешить аутентификацию из принятых местоположений только с помощью Spring Security

2. Определите Кодировщик паролей

Мы начнем с определения простого BCryptPasswordEncoder в качестве компонента в нашей конфигурации:

Более старые реализации, такие как ShaPasswordEncoder , потребовали бы, чтобы клиент передавал значение соли при кодировании пароля.

BCrypt, однако, будет внутренне генерировать случайную соль вместо этого. Это важно понимать, потому что это означает, что каждый вызов будет иметь другой результат, и поэтому нам нужно только один раз закодировать пароль.

Чтобы эта случайная генерация соли работала, BCrypt будет хранить соль внутри самого хэш-значения. Например, в следующем хэш-значении:

Есть три поля, разделенные $:

  1. “2a” представляет версию алгоритма BCrypt
  2. “10” представляет силу алгоритма
  3. “ZLhnHxdpHETcxmtEStgpI.” часть на самом деле является случайно сгенерированной солью. В основном, первые 22 символа-это соль. Оставшаяся часть последнего поля-это фактическая хэшированная версия обычного текста

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

3. Закодируйте Пароль при регистрации

Теперь мы будем использовать PasswordEncoder в нашем Пользовательском сервисе для хэширования пароля во время процесса регистрации пользователя:

Пример 3.1. – Обслуживание пользователей e Хэширует пароль

4. Закодируйте пароль при аутентификации

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

Во-первых, нам нужно ввести компонент кодировщика паролей, который мы определили ранее, в наш поставщик аутентификации:

Конфигурация безопасности проста:

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

И, наконец, нам нужно ссылаться на этого поставщика аутентификации в нашей конфигурации XML безопасности:

Или, в случае, если вы используете конфигурацию Java:

5. Заключение

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

полную реализацию этой регистрации с помощью руководства по безопасности Spring можно найти на GitHub .

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

Приложение проверяет, какие стоят права у данного пользователя, и либо впускает его, либо нет.

Например, user может зайти на url /user, а admin и на /user, и еще на другие url.

Подготовка

В прошлом примере мы настроили аутентификацию типа In-Memory, при которой пользователи хранятся в памяти приложения. Пример простой и подходящий для демонстрации настройки авторизации.

Контроллер

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

Контроллер теперь имеет три URL:

Пользователи (In-Memory athentication)

А настройка аутентификации (см. предыдущий пример) выглядит теперь так:

Теперь мы ввели два разрешения ROLE_USER и ROLE_ADMIN, а в прошлом примере было одно.

Вот теперь разрешения нам пригодятся — для настройки авторизации.

Настройка авторизации

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

Мы по очереди перечисляем возможные url и задаем права доступа к ним (точнее, в нашем примере — роли).

Перечисление url

Это строкой мы говорим предоставить разрешения для следующих url.

Далее мы перечисляем не сами url (поскольку их может быть слишком много), а шаблоны. Шаблоны url задаются с помощью класса AntPathRequestMatcher .

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

Например, следующие три url подпадают под шаблон /admin/**:

Если в коде начать перечисление с всеобъемлющего шаблона /**, то перебор на нем остановится (так как любой url, в том числе /admin) соответствует шаблону /** , а значит всем будет разрешен доступ. Именно поэтому начинать нужно с узкоохватывающих шаблонов.

Настройка доступа (роли, разрешения)

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

Можно было задать доступ с помощью разрешений, результат был бы аналогичный:

Еще такой есть полезный метод:

Наконец, страница логина теперь генерироваться не будет, чтобы ее вернуть, допишем строку:

Если пользователь не аутентифицирован (в данном случае так будет, если в запросе либо отсутствует кукис JSESSIONID, либо он неправильный), то выполняется редирект на страницу ввода логина и пароля.

Ввод логина и пароля в форму считается аутентификцией типа Form-Based, что означает, что имя и пароль приходят в POST-запросе в параметрах username и password (такие имена параметров по умолчанию используются в Spring Security). То есть когда пользователь попадет на страницу логина и введен туда данные, на сервер пойдет новый запрос, в котором данные будут передаваться в этом самом POST.

Это устаревший и небезопасный способ.

Но суть в том, что обе эти строки указывают Spring Security, как именно он должен брать из запроса имя пользователя и пароль.

Итоги

Пример доступен на GitHub.

Также см. тут как защитить конкретные методы с помощью @Preauthorize.

Как настроить авторизацию в Spring Security: 13 комментариев

Здравствуйте, подскажите, пожалуйста, как со всеми аналогичными настройками авторизоваться через постман? json с передачей username и password в формате json (raw) и через form-data не сработали. Возвращается всегда 403

Можно сделать авторизацию на уровне методов, например, если пользователь приложения AppUser может редактировать только свой объект Thing, то аннотируем метод редактирования так:

Есть также Spring Security ACL — мощная вещь (но возможно избыточная, нужно создавать обязательные таблицы и т.д.)

1. Возможно не включили @EnableGlobalMethodSecurity(prePostEnabled = true) на главном классе.
2. @PreAuthorize рекомендуется ставить на методы сервисов

Вы очень понятно объясняете, спасибо большое за ваш труд!
2 связанных вопроса:
1. Откуда в конфиге вытаскивается информация о наличии у юзера определенной роли hadRole? Я использую jwt token, по вашему примеру делала фильтр, чтобы токен при запуске апп.проверялся, обновлялся (дата продлевается) и заново ложился в хедер реквеста перед возвратом в чейн — и дальше уже в контроллер

2. Допустим, в jwt токен есть роли в authorities. Что срабатывает раньше: наш конфиг со своими hadRole, или фильтр? А то выходит, фильтр мне обновит токен (дату, и вытащит в токен актуальные роли из бд с помощью userDetails), но секьюрити конфиг сработает раньше фильтра и не будет знать, что юзер уже админ, например

Подскажите, использую микросервисную архитектуру, и авторизация выполняется на другом сервере. У пользователя есть два токена. Токен досупа и refresh токен. Второй устаревает каждый 3 минуты. За его обновлением следит свой сервис.
Для доступа к основыным сервсам приложения пользователь в базовой аутентификации передает логин и пароль. Логи это токен доступа… пароль… refreshToken. Так как второй все время обновляется то компроментация ему не страшна.
Но есть пролблем. Спринг хеширует авторизацию. И при повторных запросах уже не проверяет ее если установлен куки JSESSIONID.
А так как токен устаревает, то проверять надо при каждом доступе к серверу.
Сейчас у меня такие настройки Spring Security

Подскажите, может еще надо что то дописать, чтоб каждый запрос проходил процедуру авторизации?

В декомпилированном BasicAuthenticationFilter нашел вот такой метод private boolean authenticationIsRequired(String username) Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
if (existingAuth != null && existingAuth.isAuthenticated()) if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) return true;
> else return existingAuth instanceof AnonymousAuthenticationToken;
>
> else return true;
>
>

тут он как раз проверяет необходимость повторной авторизации. Но как это мне поможет не понимаю.

Спасибо! Помогло!
У меня токен обновления живет 3 минуты. Может мне не отключать совсем сессию, а сделать у нее таймаут, пару минут. Чтоб уменьшить нагрузку на сервис авторизации?

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


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

От регулярной смены паролей мало пользы

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

Для примера возьмем пароль batman2018. Если нужно будет его сменить, многие, скорее всего, просто сделают так: batman2019. Система воспримет этот пароль как новый, но по сути он остался тем же самым. И если старый пароль каким-то образом попадет в руки злоумышленникам, им несложно будет угадать новый.

А как у вас дела с паролями?

A post shared by Лаборатория Касперского (@kasperskylabrus) on May 16, 2019 at 5:36am PDT

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

Почему пароль обязательно должен быть уникальным

Казалось бы, имеет смысл придумать один максимально надежный пароль и использовать его для всех аккаунтов. Тогда все они будут хорошо защищены, а уж один набор символов, пусть и сложный, запомнить можно — беспроигрышная ситуация!

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

Надежный пароль — это какой?

И еще: надежный пароль вовсе не должен быть случайным набором символов. Рандомные комбинации, несомненно, хороши с точки зрения безопасности, но запоминать их — настоящая пытка. Лучше придумайте легко запоминаемый пароль, но подлиннее, минимум 12 символов — а лучше больше.

Надежные и уникальные пароли, которые легко запомнить

На самом деле запоминать сложные и уникальные пароли проще, чем кажется на первый взгляд. Нужно просто знать правильный подход. Сложный на вид (и для запоминания) и сложный для взлома — это совсем не одно и то же.

Читайте также: