Введение. Зачем я вообще это пишу?
Эта статья является первой, написанной мной. Буду очень рад, если она все же будет опубликована. На данный момент являюсь Junior Java разработчиком, поэтому в этой статье не будет сложной аналитики и глубокого погружения в тему, но я свой опыт изучения и реализации приложений с использованием Spring Security, возможно, кому-то это поможет справиться с теми трудностями, с которыми встретился я.
Недавно мне пришлось подключать и настраивать авторизацию через Spring Security версии 3.1.0. В процессе разработки и решения сложностей, которых было не мало, я заметил, что информации по версии 3.1.0 довольно мало, если не считать документацию. (https://docs.spring.io/spring-security/reference/index.html)
Настройки приложения
Первым делом, начав работу над добавлением авторизации в свое приложение, я добавил соответствующую зависимость в pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Следующий шагом я приступил к настройке базы данных и подключению PostgreSQL. Я решил использовать application.yml вместо application.properties, так как данный формат является более удобным и читаемым
spring:
datasource:
url: jdbc:postgresql://localhost:5432/demoproject
username: postgres
password: password!456
driver-class-name: org.postgresql.Driver
SecurityConfig
Основные сложности у меня возникли в конфигурации, поэтому попробую расписать подробнее.
Первым делом я создал объект DataSource, который позволил связать Security с
приложением.
private DataSource dataSource;
@Autowired
public SecurityConfig(DataSource dataSource) { this.dataSource = dataSource; }
Следующим шагом я реализовал метод, создающий сущность JdbcUserDetailsManager. JdbcUserDetailsManager - реализует интерфейс UserDetailsManager, который позволяет работать с пользователями, в том числе создавать их при необходимости. Так как цели реализовывать полноценный механизм регистрации нет, то воспользовался методом createUser().
@Bean
public JdbcUserDetailsManager user(PasswordEncoder encoder) {
UserDetails admin = User.builder()
.username("admin")
.password(encoder.encode("adm_psw"))
.roles("ADMIN")
.authorities("ADMIN")
.build();
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
jdbcUserDetailsManager.createUser(admin);
return jdbcUserDetailsManager;
}
Момент создания пользователя можно исключить и реализовать возможность полноценной регистрации или иным образом заполнить базу необходимыми данными - дальнейшую работу с базой я стал вести с Liquibase. Тогда метод будет выглядеть так:
@Bean
public JdbcUserDetailsManager user(PasswordEncoder encoder) {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
return jdbcUserDetailsManager;
}
В базе так же должны быть таблицы authorities:
create table authorities
(
username varchar,
authority varchar
);
и users:
create table users
(
username varchar,
password varchar,
enabled varchar
priority integer
);
Далее логика доступа к необходимым эндпоинтам. Необходимый эндпоинт прописывается в requestMatchers(). С помощью hasAuthority или hasRole позволяем доступ определенной категории пользователей
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(
(authorize) -> authorize
.dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
.requestMatchers("/admin").hasAuthority("ADMIN")
.requestMatchers("/user").hasAuthority("USER")
.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.formLogin(Customizer.withDefaults());
return http.build();
}
Заключение
На этом в целом все. Далее можно создать тестовый контроллер и проверить работу авторизации в приложении. Как вариант, проверка через постман. Для этого в Authorization выбирает type Basic Auth. В полях username и password прописываем заданные ранее значения.
Подробную информацию о специфике методов и работы с Spring Security все же рекомендую брать из документации.
Код моего проекта можно найти на моем аккаунте в GitHub
Так же буду рад получить советы и рекомендации как по коду, так и по написанию статей.
Комментарии (5)
xini
16.08.2023 12:37Коллеги, поделитесь опытом, часто ли приходиться самостоятельно настраивать таким образом speing-security? Мне кажется это все ненужным, когда есть OAuth2, OIDC, Keycloak и spring-boot-starter-oauth2-resource-server
Kmplzz
16.08.2023 12:37Keycloak нужно устанавливать и поддерживать, а тут прикрутил basic auth и все работает. Я не говорю, что basic лучше, но на многих проектах присутствует
shamank
16.08.2023 12:37блин, огромное спасибо!!! сам с этим вожусь уже не первый день, нигде не мог найти нормальное разъяснение...
Mrakobec
16.08.2023 12:37К чему эта статья? В дока всё описано, либо достаточно зайти в нужный интерфейс и в нём всё также прекрасно расписано. Основные изменения - это ввод лямбда функций в качестве параметров, вместо огромной колбасы.
Dddn
О, спасибо, как раз искал информацию. Spring Security 3 сильно изменили. Ещё бы примеров про тестирование информации.