@EnableGlobalMethodSecurity уже устарел, вместо него нужно воспользоваться аннотацией @EnableMethodSecurity, csrf тоже стал deprecated, поэтому заменим его лямбда выражение. Потом еще устарели методы authorizeRequests() и antMatchers() и and(). Итоговый код выглядит вот так : public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ http .csrf(AbstractHttpConfigurer::disable) .cors(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authz -> authz .requestMatchers("/secured").authenticated() .requestMatchers("/info").authenticated() .requestMatchers("/admin").hasRole("ADMIN") .anyRequest().permitAll()) .sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .exceptionHandling((exceptionHandling) -> exceptionHandling.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))); //addFilterBefore() return http.build();
Циклическая зависимость возникает из-за того, что UserService зависит от PasswordEncoder, а SecurityConfig зависит от UserService. Проще всего делегировать создание Bean Definition на ioc контейнер и создать отдельную конфигурацию для PasswordEncoder, вынести PasswordEncoder-bean в отдельный класс PasswordEncoderConfiguration.
Спасибо за урок! Было бы интересно рассмотреть случай с несколькими методами аутентификации, например - для пользователей через Google учетку, а для администраторов - по паролю. Ну и refreshToken для реализма)
Spring Security: Spring Security + REST + JWT 00:00 Введение • Видео объясняет, как использовать джи-ти-токины в спринг секьюрити для защиты приложений. • Рассматриваются примеры использования и настройки безопасности в рамках работы спринга. 01:52 Создание проекта • Создание проекта с использованием спринга, GPS, H2 базы данных, ломбака и флай эмиграйшн. • Настройка проекта и добавление зависимостей. 06:37 Настройка контроллеров и сущностей • Создание контроллеров и сущностей для работы с пользователями и ролями. • Настройка гет-мапингов и сущностей для доступа к данным. 14:29 Репозитории и интерфейсы • Создание репозиториев для работы с ролями и пользователями. • Создание интерфейсов для работы с ролями и пользователями. 15:29 Создание сущностей и репозиториев • Создание сущностей и репозиториев для работы с пользователями и ролями. • Использование аннотаций для создания сущностей и репозиториев. 19:29 Создание сервиса и методов • Создание юзер-сервиса для работы с пользователями и ролями. • Реализация методов для поиска пользователей, создания новых пользователей и преобразования пользователей к виду, понимаемому Spring Security. 26:25 Конфигурация безопасности • Создание пакета конфиг-конфигурации и настройка конфигурации безопасности. • Использование аннотаций и бинов для настройки правил безопасности, хранения паролей и использования юзер-сервиса. • Создание бина для настройки анти-кейшн провайдера и юзер-сервиса. 31:21 Безопасность в REST • В REST нет сессий, поэтому безопасность основана на токенах. • Токен содержит информацию о пользователе, его роли и подписывается секретным ключом. • Токен подшивается к каждому запросу и проверяется на бэкенде. 42:13 Токен и его структура • Токен состоит из заголовка, полезной нагрузки и подписи. • Заголовок кодируется с помощью алгоритма, полезная нагрузка кодируется с помощью другого алгоритма, а подпись формируется с использованием секретного ключа. • Токен может быть расшифрован, но не подменен. 46:13 Создание утилиты для работы с токенами • Создание класса, который будет отвечать за работу с токенами, и инжектирование значений в его поля. • Создание методов для формирования токена из пользователя, получения списка ролей из токена и проверки его на корректность. 58:05 Аутентификация пользователя и выдача токена • Создание контроллера для аутентификации и регистрации пользователей, инжектирование юзер-сервиса и других необходимых компонентов. • Создание дтошек для передачи данных о пользователе и получения токена. • Использование аутенти-менеджера для проверки логина и пароля и возврата успешного результата или ошибки аутентификации. • Создание дтошки для обработки ошибок аутентификации. 01:03:01 Получение токена • Создание конструктора для получения токена с указанием статуса, сообщения и текущего времени. • Использование конструктора для формирования токена и его возврата в качестве ответа. 01:09:42 Проверка токена • Защита токена с помощью подписи, которая не может быть изменена без знания секрета. • Если подпись изменена, то бэк получает ошибку о том, что токен недействителен. 01:12:27 Создание фильтра безопасности • Создание фильтра безопасности, который проверяет наличие токена и его корректность. • Использование утилиты для получения токена из заголовка авторизации. • Проверка корректности заголовка авторизации и получение имени пользователя из токена. 01:18:23 Работа с токенами и контекстом • В видео рассказывается о том, как с помощью утилит можно сделать гет-юзернейм и проверить пользователя. • Если время жизни токена истекло, то в контексте пользователя не будет. • Если имя пользователя найдено, то проверяется, что в контексте нет других пользователей. • Если все хорошо, то имя пользователя и список ролей из токена добавляются в контекст. 01:29:15 Регистрация и фильтрация • В видео демонстрируется регистрация пользователя и фильтрация данных в токене. • Если пароли не совпадают, то возвращается ошибка. • Если пользователь уже существует, то запрос отклоняется. • В общем, автор рекомендует спрятать обработку исключений в аутсервис и использовать глобальный перехват исключений для обработки ошибок. 01:34:15 Создание и использование токена • Обсуждение использования инкодера для шифрования пароля и его хранения в базе данных. • Создание и использование токена для аутентификации пользователя. 01:46:22 Регистрация пользователя и использование токена • Регистрация пользователя с использованием пароля и инкодера. • Создание токена для пользователя и его использование для аутентификации. 01:50:22 Итоги и обсуждение • Обсуждение принципов работы с токенами и их использования в проектах на Spring. • Ответы на вопросы зрителей и приглашение к обсуждению в комментариях.
Большое спасибо конечно за твои 2 трансляции. Но представь, я просто угробил половину дня на поиск причины почему у меня выходила ошибка 403. В итоге оказалось, что я не прописывал префикс ROLE_ в бд и из-за этого аутентификация проходила, но с надписью ошибка 403. Я пролазил точкой остановы половину классов, которые добавил в конфиг. Вот такие моменты самые бесячие. Понял только когда в точке останова увидел строчку return hasAuthority(ROLE_PREFIX + role); А ну и естественно csrf().disabled().cors().disabled() обязательно ставить.
да все объясняют через жопу, данный автор один из немногих у кого получилось сделать по другому(хорошо). Но я бы рекомендовал начать с этого видео и подобных czcams.com/video/p6MXb0GtXwg/video.html
thank you for your provided content, it is very helpful and useful, but please change IDE theme to dark mode, I really struggle to understand what' going on there.
Здравствуйте. 2 день не пойму как сделать токен просроченным, чтобы он не работал для скажем заблокированного юзера. Можно ли как то подменить в существующем токене дату истечения срока жизни?
Всё круто, спасибо, очень классное объяснение. Но JwtRequestFilter срабатывает на каждый запрос и из-за этого возвращается пустой 200 стоатус по всем запросам. Тут что-то надо поменять в конфигах или логику добавить в JwtRequestFilter
Почему нельзя было снять сразу с Spring Boot 3? Объяснение логики это хорошо конечно, но практическое применение только на устаревших проектах, т.к. с 6 версии Security подход изменился
Когда я делал авторизацию и аутентификацию на Python DRF удалось довольно быстро всё настроить и ещё logout сделать, но там токены были обычные не JWT и хранились в БД привязанные к пользователю и из можно было посмотреть и удалить или изменить через админку (которая кстати из коробки в Django, только настроить надо было что там будет). Я так понимаю JWT токены не обязательно сохранять в БД, т.к. в них закодированы username, roles и lifetime. Но как тогда сделать logout? Хранить список недействительных токенов или просто сохранять токены в бд? Какой подход надо лучше использовать?
Технически токен хранит приложение или браузер, если его удалить оттуда, то оно не сможет отправить запрос, потребуется авторизация, а на стороне бека просто время жизни токена истечет
Я просто смотрю и в шоке сколько я не знаю и как это вообще уложить в своей бошке😢 Я пытаюсь устроиться хотя бы на трейни или джуна. Но спринг со всеми своими библиотеками вообще тяжело идёт. Все эти аннотации и под классы 🥴
А в чем суть наличия и работы через Principle или UserDetails интерфейсы, если у нас есть свой класс (условный User тот же или Customer, Employee и т.д), у которого мы можем получать все необходимое для авторизации и аутентификации? PS. это вопрос из разряда "хочу понять Principle и UserDetails(Service)".
Интерфейс Principal представляет аутентифицированного пользователя. У него есть только метод getName().Principal не дает подробной информации о пользователях, таких как пароль, роли или разрешения. Интерфейс UserDetails представляет полные детали пользователя, необходимые для аутентификации и авторизации. У него есть разные методы по получению информации о пользователе ( getUsername(), getAuthorities(), getPassword() и т.п.)
А что делать если мы пользователю поменяли право или например удалили его? Получается что другой сервис, пока lifetime не истек, все равно прочитает токен и посчитает его корректным? Какое решение тут выбрать? Или JWT не про это и лучше тогда использовать сессии?
Как вариант - хранить токены (например в SQL или более быстрой памяти). Условно генеришь токен и отправляешь его как пользователю так и в таблицу. Что-то подобное есть тут watch?v=R4LwwJVjVP0 Но не совсем. Пользователь стучится к тебе по токену, ты проверяешь валиден ли токен по признаку "активен" и только тогда пускаешь. А при смене роли - принудительно сбрасываешь на "неактивен" и пусть новый токен получает через логин. Ну или может быть ставить некий флаг "изменена роль" при котором в логаут не выкинет, но доступ по токену останется только для замены токена на более актуальный. А ко всем иным эндпоинтам доступ не давать. Учитывая что таких обращений будет много, то токены наверное стоит не в SQL, а в чём-то более быстром хранить.
У меня user может заходить куда угодно и получать корректные ответы, а вот admin нет, в /secured возвращается пустой текст, хотя user-у отдавалась строка secured-data, была у кого-нибудь схожая ситуация?
Объяснение хорошее. Но реализация хромает. Не показано как настраивать h2, flyway. Без которых проект не запускается или не работает как показано на видео
Под конец немного путанная подача, но тема сложная и даже автор немного подвисал или слабовато подготовился. Очень не хватает: 1. тайм-лайна 2. Ссылок после видео
@Bean public DaoAuthenticationProvider daoAuthenticationProvider() { DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setPasswordEncoder(passwordEncoder()); daoAuthenticationProvider.setUserDetailsService(userService); return daoAuthenticationProvider; } Создание этого бина лишнее
Слушайте, вопрос такой. С какой-то версии спринга поменяли принцип описания SecurityFilterChain. Теперь тот метод через .cors().disable() и .csrf().disable() не совсем валиден. Подскажите, как выкрутиться?
Почему когда я кладу в claims List, потом достаю его, idea не может успокоиться и пишет что метод должен возвращать не List, а прост List, если я так сделаю это начнутся другие предупреждения, к решению я так и не пришёл, кроме как игнорировать, но почему же у меня так происходит, у вас такого не было когда вы писали код?
так же светилось желтым предупреждение. как вариант можно сделать так: public List getRoles(String token) { List roles = getAllClaimsFromToken(token).get("roles", List.class); return roles.stream().map(Object::toString).toList(); } или просто повесить аннотацию @SuppressWarnings("unchecked")
Отличнное обьяснение работы!😊 а можно ли из principal.getname() его имя таким образом сохранять например как автора сообщения что он создает например. Если Principal будет в аигументе метода. Или лучше для таких случаев использовать @AutentificationPrincipal User user и из него получать детали?
Для разрешения циклической зависимости можно либо создать конструктор явно и указать в нём @Lazy, либо добавить после @RequiredArgsConstructor (onConstructor_={@Lazy})
Лучший. Грамотная речь, без слов паразитов, выверенный план лекции. И даже заминка помогает проследить, а как профи ищет ошибку. Спасибо!
Спасибо большое вам за ваши лекции, все очень доходчиво и понятно. Узнал про вас в ГБ, жаль не удалось побывать у вас на онлайн занятиях.
Как же у вас речь поставлена - разбирался сам с JWT и голова болела, а тут такой подарок! Спасибо за лекцию!
@EnableGlobalMethodSecurity уже устарел, вместо него нужно воспользоваться аннотацией @EnableMethodSecurity, csrf тоже стал deprecated, поэтому заменим его лямбда выражение. Потом еще устарели методы authorizeRequests() и antMatchers() и and(). Итоговый код выглядит вот так :
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authz -> authz
.requestMatchers("/secured").authenticated()
.requestMatchers("/info").authenticated()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().permitAll())
.sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling((exceptionHandling) -> exceptionHandling.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)));
//addFilterBefore()
return http.build();
человек, ты лучший!
очень сильно прарился но по итогу сделал сам и вроде как работает а потом увидел это сообщение и такой ндаааа
вы лучший в аспекте объяснений, продолжайте, пожалуйста и спасибо огромное за ваш труд
Спасибо за видео!) Жду продолжения по спрингу😄
Спасибо Вам за видео с подробной информацией)
Огромное спасибо! Самый актуальный мануал по spring security + jwt)
Благодарность 🙏 Лайк - подписка! Как я долго искал этот контент на доступном языке.
Прекрасное объяснение для русской аудитории! Внятно и по делу! Спасибо автору за труд👍👍👍
Циклическая зависимость возникает из-за того, что UserService зависит от PasswordEncoder, а SecurityConfig зависит от UserService.
Проще всего делегировать создание Bean Definition на ioc контейнер и создать отдельную конфигурацию для PasswordEncoder, вынести PasswordEncoder-bean в отдельный класс PasswordEncoderConfiguration.
Спасибо тебе мил человек за подсказку
@@user-nh3gd1mh7x удачи вам!
покажи пожалуйста эту реализацию на гитхабе =)
@@dmaberlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
public class PasswordEncoderConfiguration {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
Спасибо большое!!!! Очень ждал!! ❤
Ура! Александр, спасибо! очень долгожданная тема ))
Грамотная речь и дикция, без лишних слов. Всё доходчиво! Очень уважаю Ваш труд. Хотелось бы по больше видео уроков от Вас.
Большое спасибо за видео. Приятно слушать.
Лучшее объяснение по теме на русском! Большое спасибо!
Благодарю , за видео. Ждем разбор по микросервисам.
спасибо большое! очень доступно для понимания !
Спасибо за урок!
Было бы интересно рассмотреть случай с несколькими методами аутентификации, например - для пользователей через Google учетку, а для администраторов - по паролю. Ну и refreshToken для реализма)
Спасибо за данный гайд, лучший просто!
Очень доступно и все понятно 👌 Было бы здорово еще видео про микросервисы в сочетании spring security и spring gateway 😊
согласен
Спасибо! Сделал закладочку на будущее.Мне до этого далековато. Жду продолжения по основам.
Спасибо огромное, четко и понятно! Таким людям памятники на вокзале ставить надо)))
Spring Security: Spring Security + REST + JWT
00:00 Введение
• Видео объясняет, как использовать джи-ти-токины в спринг секьюрити для защиты приложений.
• Рассматриваются примеры использования и настройки безопасности в рамках работы спринга.
01:52 Создание проекта
• Создание проекта с использованием спринга, GPS, H2 базы данных, ломбака и флай эмиграйшн.
• Настройка проекта и добавление зависимостей.
06:37 Настройка контроллеров и сущностей
• Создание контроллеров и сущностей для работы с пользователями и ролями.
• Настройка гет-мапингов и сущностей для доступа к данным.
14:29 Репозитории и интерфейсы
• Создание репозиториев для работы с ролями и пользователями.
• Создание интерфейсов для работы с ролями и пользователями.
15:29 Создание сущностей и репозиториев
• Создание сущностей и репозиториев для работы с пользователями и ролями.
• Использование аннотаций для создания сущностей и репозиториев.
19:29 Создание сервиса и методов
• Создание юзер-сервиса для работы с пользователями и ролями.
• Реализация методов для поиска пользователей, создания новых пользователей и преобразования пользователей к виду, понимаемому Spring Security.
26:25 Конфигурация безопасности
• Создание пакета конфиг-конфигурации и настройка конфигурации безопасности.
• Использование аннотаций и бинов для настройки правил безопасности, хранения паролей и использования юзер-сервиса.
• Создание бина для настройки анти-кейшн провайдера и юзер-сервиса.
31:21 Безопасность в REST
• В REST нет сессий, поэтому безопасность основана на токенах.
• Токен содержит информацию о пользователе, его роли и подписывается секретным ключом.
• Токен подшивается к каждому запросу и проверяется на бэкенде.
42:13 Токен и его структура
• Токен состоит из заголовка, полезной нагрузки и подписи.
• Заголовок кодируется с помощью алгоритма, полезная нагрузка кодируется с помощью другого алгоритма, а подпись формируется с использованием секретного ключа.
• Токен может быть расшифрован, но не подменен.
46:13 Создание утилиты для работы с токенами
• Создание класса, который будет отвечать за работу с токенами, и инжектирование значений в его поля.
• Создание методов для формирования токена из пользователя, получения списка ролей из токена и проверки его на корректность.
58:05 Аутентификация пользователя и выдача токена
• Создание контроллера для аутентификации и регистрации пользователей, инжектирование юзер-сервиса и других необходимых компонентов.
• Создание дтошек для передачи данных о пользователе и получения токена.
• Использование аутенти-менеджера для проверки логина и пароля и возврата успешного результата или ошибки аутентификации.
• Создание дтошки для обработки ошибок аутентификации.
01:03:01 Получение токена
• Создание конструктора для получения токена с указанием статуса, сообщения и текущего времени.
• Использование конструктора для формирования токена и его возврата в качестве ответа.
01:09:42 Проверка токена
• Защита токена с помощью подписи, которая не может быть изменена без знания секрета.
• Если подпись изменена, то бэк получает ошибку о том, что токен недействителен.
01:12:27 Создание фильтра безопасности
• Создание фильтра безопасности, который проверяет наличие токена и его корректность.
• Использование утилиты для получения токена из заголовка авторизации.
• Проверка корректности заголовка авторизации и получение имени пользователя из токена.
01:18:23 Работа с токенами и контекстом
• В видео рассказывается о том, как с помощью утилит можно сделать гет-юзернейм и проверить пользователя.
• Если время жизни токена истекло, то в контексте пользователя не будет.
• Если имя пользователя найдено, то проверяется, что в контексте нет других пользователей.
• Если все хорошо, то имя пользователя и список ролей из токена добавляются в контекст.
01:29:15 Регистрация и фильтрация
• В видео демонстрируется регистрация пользователя и фильтрация данных в токене.
• Если пароли не совпадают, то возвращается ошибка.
• Если пользователь уже существует, то запрос отклоняется.
• В общем, автор рекомендует спрятать обработку исключений в аутсервис и использовать глобальный перехват исключений для обработки ошибок.
01:34:15 Создание и использование токена
• Обсуждение использования инкодера для шифрования пароля и его хранения в базе данных.
• Создание и использование токена для аутентификации пользователя.
01:46:22 Регистрация пользователя и использование токена
• Регистрация пользователя с использованием пароля и инкодера.
• Создание токена для пользователя и его использование для аутентификации.
01:50:22 Итоги и обсуждение
• Обсуждение принципов работы с токенами и их использования в проектах на Spring.
• Ответы на вопросы зрителей и приглашение к обсуждению в комментариях.
Нейросети имба
что за нейросеть?
от яндекса, которая пересказывает видео@@lusterluster6403
Встроенная в браузер Яндекс
Спасибо большое, вы лучший
Топ. Вот бы видос по микросервисам
Спасибо автору за видео, очень информативно.
Автор сделайте видос по микросервисах
Это лучший ментор! Гуру💪🏻🙏🏻
Все супер! Можно еще улучшить, увеличив немного размер шрифта и всего остального.
Спасибо автору
Спасибо огромное!
Огромное спасибо)
I do not understand the language well but the course is very well done thank you for sharing from french
Спринг, ммм :) Спасибо!
Спасибо!🙂
Спасибо вам
super-puper ждем еще видосы
Хорош!👍
Большое спасибо конечно за твои 2 трансляции. Но представь, я просто угробил половину дня на поиск причины почему у меня выходила ошибка 403. В итоге оказалось, что я не прописывал префикс ROLE_ в бд и из-за этого аутентификация проходила, но с надписью ошибка 403. Я пролазил точкой остановы половину классов, которые добавил в конфиг. Вот такие моменты самые бесячие. Понял только когда в точке останова увидел строчку return hasAuthority(ROLE_PREFIX + role);
А ну и естественно csrf().disabled().cors().disabled() обязательно ставить.
супермегахарош
Спасибо за контент,правда мне до этого ещё далеко
185 раз смотрю, так и не могу разобраться, что к чему в этом security)))
да все объясняют через жопу, данный автор один из немногих у кого получилось сделать по другому(хорошо). Но я бы рекомендовал начать с этого видео и подобных czcams.com/video/p6MXb0GtXwg/video.html
thank you for your provided content, it is very helpful and useful, but please change IDE theme to dark mode, I really struggle to understand what' going on there.
Ссылка на исходники: github.com/FlameXander/security-jwt
Исходники чуть попозже залью на GitHub
@@anyone7783 прикрепил ссылку в описании и в комментариях
А можно ещё видео как разлогиниться) а то как-то не полно вышло!)
Здравствуйте. 2 день не пойму как сделать токен просроченным, чтобы он не работал для скажем заблокированного юзера. Можно ли как то подменить в существующем токене дату истечения срока жизни?
Подскажите, можно ли записаться на ваши курсы?
Если можно то где?
Всё круто, спасибо, очень классное объяснение. Но JwtRequestFilter срабатывает на каждый запрос и из-за этого возвращается пустой 200 стоатус по всем запросам. Тут что-то надо поменять в конфигах или логику добавить в JwtRequestFilter
А в конце вызывается filterChain.doFilter(request, response)?
Почему нельзя было снять сразу с Spring Boot 3? Объяснение логики это хорошо конечно, но практическое применение только на устаревших проектах, т.к. с 6 версии Security подход изменился
При авторизации дважды в базу лезем. AuthenticationManager под капотом сам бегает в UserService.
Не совсем понятно на 1:20:25, что значит, что в контексте может лежать что-то "поверх токенов или под токенами"?
Когда я делал авторизацию и аутентификацию на Python DRF удалось довольно быстро всё настроить и ещё logout сделать, но там токены были обычные не JWT и хранились в БД привязанные к пользователю и из можно было посмотреть и удалить или изменить через админку (которая кстати из коробки в Django, только настроить надо было что там будет). Я так понимаю JWT токены не обязательно сохранять в БД, т.к. в них закодированы username, roles и lifetime. Но как тогда сделать logout? Хранить список недействительных токенов или просто сохранять токены в бд? Какой подход надо лучше использовать?
Технически токен хранит приложение или браузер, если его удалить оттуда, то оно не сможет отправить запрос, потребуется авторизация, а на стороне бека просто время жизни токена истечет
Я просто смотрю и в шоке сколько я не знаю и как это вообще уложить в своей бошке😢 Я пытаюсь устроиться хотя бы на трейни или джуна. Но спринг со всеми своими библиотеками вообще тяжело идёт. Все эти аннотации и под классы 🥴
То есть контроллер authitization заменяет контроллер login?
я не пойму тут старый спринг секьюрити? сейчас он так фильтрчейн не конфигурируется
А в чем суть наличия и работы через Principle или UserDetails интерфейсы, если у нас есть свой класс (условный User тот же или Customer, Employee и т.д), у которого мы можем получать все необходимое для авторизации и аутентификации?
PS. это вопрос из разряда "хочу понять Principle и UserDetails(Service)".
Интерфейс Principal представляет аутентифицированного пользователя. У него есть только метод getName().Principal не дает подробной информации о пользователях, таких как пароль, роли или разрешения.
Интерфейс UserDetails представляет полные детали пользователя, необходимые для аутентификации и авторизации. У него есть разные методы по получению информации о пользователе ( getUsername(), getAuthorities(), getPassword() и т.п.)
не хотите снять видео какой-то проект типа магазина
я думаю при регистрации мы должны редиректиться на форму входа, где мы вводим логин и пароль. это самое логичное было бы
А что делать если мы пользователю поменяли право или например удалили его? Получается что другой сервис, пока lifetime не истек, все равно прочитает токен и посчитает его корректным? Какое решение тут выбрать? Или JWT не про это и лучше тогда использовать сессии?
Как вариант - хранить токены (например в SQL или более быстрой памяти).
Условно генеришь токен и отправляешь его как пользователю так и в таблицу.
Что-то подобное есть тут watch?v=R4LwwJVjVP0
Но не совсем.
Пользователь стучится к тебе по токену, ты проверяешь валиден ли токен по признаку "активен" и только тогда пускаешь.
А при смене роли - принудительно сбрасываешь на "неактивен" и пусть новый токен получает через логин.
Ну или может быть ставить некий флаг "изменена роль" при котором в логаут не выкинет, но доступ по токену останется только для замены токена на более актуальный.
А ко всем иным эндпоинтам доступ не давать.
Учитывая что таких обращений будет много, то токены наверное стоит не в SQL, а в чём-то более быстром хранить.
Есть ли какая то конкретная причина использования Date для времени, или можно спокойно использовать Local[Date/Time/DateTime]?
Можно спокойно использовать LocalDateTime
секрет любой или какой то особенный нужен?
У кого-то возникала ошибка, что бин AuthenticationManager не регистрируется?
Решил проблему, если будете пробовать реализовывать, то класс SecurityConfig помечайте аннотацией @Configuration
@@jersonmade8043 спасибо большое! долго возился не понимал почему на все запросы 401 ловил.
после добавления @Configuration все заработало
лучший ты мне помог!!!!!!!! @@jersonmade8043
Jwt использует javax.xml.bind.DatatypeConverter но в новых версиях java оно не используется и выдает ошибку
Может уже есть новая версия где не используется avax.xml.bind.DatatypeConverter?
Нужна зависимость javax.xml.bind:jaxb-api
У меня user может заходить куда угодно и получать корректные ответы, а вот admin нет, в /secured возвращается пустой текст, хотя user-у отдавалась строка secured-data, была у кого-нибудь схожая ситуация?
может в конфиге что-то?
Вот пример моего конфига:
```
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(request -> {
var corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOriginPatterns(List.of("*"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
corsConfiguration.setAllowedHeaders(List.of("*"));
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}))
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/user/log").permitAll()
.requestMatchers("/user/logpost").permitAll()
.requestMatchers("/user/reg").permitAll()
.requestMatchers("/").hasAnyRole("ADMIN","USER")
.requestMatchers("/user").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.httpBasic(Customizer.withDefaults())
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
```
я не понимаю, что я сделал не так у меня на 1:08:30 все время выдает 401 ответ, хотя все вроде бы делал так же
в нормальном качестве будет позже , я так понимаю ? тема очень нужная и интересная
+ тоже жду лучше кач-во
CZcams еще несколько часов видео будет обрабатывать и потом да, будет нормальное качество
@@FlameXander а можно ожидать что появится видео про юнит тесты? Особенно авторизация прям требует чтобы была покрыта юнит тестами
1:30:06 не поняла, что меняем в токене?
А обязательно использовать роли ?
Объяснение хорошее. Но реализация хромает. Не показано как настраивать h2, flyway. Без которых проект не запускается или не работает как показано на видео
И помогите пожалуйста прописать контроллер logout
Хотелось бы теперь узнать, как сдлеать вход без postman так, чтобы токен встравивался в сылку
🤔🤔
Это достаточно просто делается на фронтенде
@@FlameXander я в фронтенде не шарю, не могли бы вы скинуть статью? Если не затруднит.
@@FlameXander я пытаюсь запустить через постман registration, но не могу понять каким должен быть путь
Под конец немного путанная подача, но тема сложная и даже автор немного подвисал или слабовато подготовился. Очень не хватает:
1. тайм-лайна
2. Ссылок после видео
Туман в мозгу по поводу jwt начинает рассеиваться )
jwt:
secret:111ddd
lifetime:30m
'Cannot resolve configuration property 'jwt'
почему выходит циклическая зависимость, потому что в SecurityConfig мы инжектим
UserService userService;
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userService);
return daoAuthenticationProvider;
}
Создание этого бина лишнее
@@TEOOOOOOOOOOOO спасибо
У меня скоро крыша полетит, до сих пор не нашёл нужного гайда как встроить токен в сылку
Слушайте, вопрос такой. С какой-то версии спринга поменяли принцип описания SecurityFilterChain. Теперь тот метод через .cors().disable() и .csrf().disable() не совсем валиден. Подскажите, как выкрутиться?
http.cors(cors -> cors.disable()).csrf(csrf -> csrf.disable()) и т.д.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(request -> {
var corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOriginPatterns(List.of("*"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
corsConfiguration.setAllowedHeaders(List.of("*"));
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}))
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/user/log").permitAll()
.requestMatchers("/user/logpost").permitAll()
.requestMatchers("/user/reg").permitAll()
.requestMatchers("/").hasAnyRole("ADMIN","USER")
.requestMatchers("/user").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.httpBasic(Customizer.withDefaults())
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@@kai_9482 Спасибо большое
Почему когда я кладу в claims List, потом достаю его, idea не может успокоиться и пишет что метод должен возвращать не List, а прост List, если я так сделаю это начнутся другие предупреждения, к решению я так и не пришёл, кроме как игнорировать, но почему же у меня так происходит, у вас такого не было когда вы писали код?
так же светилось желтым предупреждение. как вариант можно сделать так:
public List getRoles(String token) {
List roles = getAllClaimsFromToken(token).get("roles", List.class);
return roles.stream().map(Object::toString).toList();
}
или просто повесить аннотацию @SuppressWarnings("unchecked")
хтось може надіслати посилання на телеграм канал а то ця не дійсна
много что не объясняешь
Отличнное обьяснение работы!😊 а можно ли из principal.getname() его имя таким образом сохранять например как автора сообщения что он создает например. Если Principal будет в аигументе метода. Или лучше для таких случаев использовать @AutentificationPrincipal User user и из него получать детали?
метод контролера auth не авторизует пользователя и выдает сообщение o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
Для разрешения циклической зависимости можно либо создать конструктор явно и указать в нём @Lazy, либо добавить после @RequiredArgsConstructor (onConstructor_={@Lazy})