Осигурете сигурността на вашето Spring приложение, като използвате стабилните функции, предлагани от Spring Security framework.
Рамката Spring Security защитава вашето приложение чрез удостоверяване и оторизация. В състоянието си по подразбиране Spring Security гарантира, че всеки път на HTTP заявка (или страница) във вашето приложение изисква удостоверяване на един глобален потребител.
Тази рамка също е изключително гъвкава. Тя ви позволява да създавате персонализирани правила за сигурност за всеки път на HTTP заявка във вашето приложение, както и за различните потребители. Така че можете да премахнете ограничението за сигурност на страници, които не изискват потребителско разрешение (като начална страница). И задайте ролите и правата на конкретни типове потребители.
Добавяне на Spring Security към вашето приложение
Има два начина да добавите Spring Security към вашето приложение. Можете или да го изберете като зависимост, когато генерирате ново приложение за Spring Boot използвайки Spring initializr
, или го добавете към вашия файл със спецификация на компилация в раздела за зависимости след генериране на вашия проект.Ако сте избрали една от опциите на проекта Gradle, тогава файлът със зависимости е build.gradle. Ако обаче сте избрали Maven, тогава този файл е pom.xml.
Вашият build.gradle файлът трябва да съдържа следната зависимост:
dependencies {
implementation 'org.springframework.boot: spring-boot-starter-security'
}
Докато вашият pom.xml файлът трябва да съдържа следната зависимост:
org.springframework.boot
spring-boot-starter-security
Примерното приложение, използвано в статията, е достъпно в това GitHub хранилище и е безплатен за използване под лиценза на MIT.
Използване на Spring Security
След като добавите зависимостта Spring Security към вашето приложение, можете да започнете да използвате рамката веднага. Просто изпълнете вашето приложение, след което отидете до началната страница на Spring Boot (или която и да е страница във вашето приложение). Примерното приложение използва следния първоначален контролер, за да контролира стойността по подразбиране на Spring Boot локален хост: 8080 заявка:
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclassWebController{
@GetMapping("/")
public String home(){
return"Welcome!";
}
}
Изпълнението на вашето приложение след добавяне на единичен клас контролер по-горе генерира следния първоначален изглед:
Ще забележите, че автоматично ви насочва към локален хост: 8080/влизане страница и прави това, преди да ви позволи достъп до друга страница на приложението. На този етап ще трябва да предоставите потребителското име по подразбиране (което е потребителят) и автоматично генерираната парола (която ще намерите в конзолата). Конзолата ще генерира ред като следния:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
Всеки път, когато рестартирате приложението си, автоматично генерираната парола ще се промени, но потребителското име ще остане същото. Въвеждането на потребителското име и паролата по подразбиране ще ви насочи към подходящия изглед във вашето приложение.
Персонализиране на Spring Security
За да персонализирате сигурността на приложението си, ще трябва да замените конфигурацията по подразбиране на Spring Security. Но преди това (ако приемем, че вече имате Spring Web) ще ви трябват няколко други зависимости за това примерно приложение:
- Пролетни данни JPA
- MySQL JDBC драйвер
- мащерка
- Ломбок
Рамката Thymeleaf ще генерира различни изгледи. Lombok ще помогне за намаляване на кода във вашите обектни класове. JPA библиотеката и MySQL драйверът ще ви позволят да използвате MySQL база данни с приложението, но имате възможност да използвате всяка база данни, която ви е удобна. Използването на база данни означава конфигуриране на приложения.свойства файл под файла с ресурси.
spring.datasource.url=jdbc: mysql://${MYSQL_HOST: localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
Конфигурационният код по-горе ви позволява да се свържете с локална MySQL база данни, наречена spring_security, с потребителско име на корени парола (1234). Ще трябва да актуализирате тези данни, за да съответстват на името и идентификационните данни на вашата база данни.
След като добавите вашите допълнителни зависимости и създадете вашата база данни, можете да започнете да решавате колко изгледа ще има вашето приложение. Ще трябва също да знаете как изглежда защитата за всяка страница. Нашето примерно приложение има 6 изгледа:
- Начална страница
- Страница за регистрация
- Страница за вход
- Страница за излизане
- Потребителска страница
- Страница с грешки
Единственият изглед, който ще изисква потребителско разрешение, е потребителската страница. Тази страница е достъпна само за потребители, които първо се регистрират, след което влизат в приложението. В допълнение към пакета по подразбиране на Spring Boot, ще трябва да създадете четири други пакета във вашето приложение.
Класът на регистрационния контролер
Пакетът на контролера ще съдържа класовете, които обработват HTTP заявки. В зависимост от функцията на дадена страница обикновено можете да групирате всяка HTTP заявка в един клас контролер, какъвто е случаят с WebController клас. Изгледът за регистрация обаче има повече уникални функции, следователно може да има частен клас на контролер:
@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
publicRegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder){
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(){
return"registration";
}
@PostMapping
public String processRegistration(RegistrationForm form){
userRepo.save(form.toUser(passwordEncoder));
return"redirect:/login";
}
}
The Регистрационен контролер клас е портал към аспекта на сигурността на вашето приложение. The @RequestMapping анотацията указва типа заявка, която този контролер ще обработва (заявки към локален хост: 8080/регистр).
The @GetMapping анотацията просто показва, че ако приложението получи заявка за /register, на формуляр за регистрация() методът трябва да обработи тази заявка, като върне регистрационния изглед.
След като посетител щракне върху бутона за регистрация, след това върху @PostMapping анотацията влиза в действие. The processRegistration() метод ви позволява да публикувате потребителските данни, които получава от Формуляр за регистрация клас към базата данни, използвайки UserRepository клас. Но преди да съхрани тези данни, processRegistration() метод криптира паролата на потребителя с помощта на ПролеттаPasswordEncoder интерфейс.
Създаване на нови конфигурации за сигурност
От Spring 3.1 разработчиците вече могат да създават конфигурации за Spring Security с помощта на Java, което означава класове вместо XML. Основното нещо, което изискват тези конфигурационни класове, е @Конфигурация анотация.
@Configuration
publicclassSecurityConfiguration{
}
The @Конфигурация анотацията показва, че класът по-горе е конфигурационен клас. Тези класове предоставят зърна на Пролетен контекст на приложение, който е контейнер, който Spring използва за създаване и управление на различните компоненти (или компоненти) на приложение. Първият боб в Конфигурация за сигурност класът е passwordEncoder боб.
@Bean
public PasswordEncoder passwordEncoder(){
returnnew BCryptPasswordEncoder();
}
The Регистрационен контролер класът използва passwordEncoder bean за кодиране на нови пароли, преди да ги запишете в базата данни. Друг важен боб, който ще трябва да добавите към Конфигурация за сигурност класът е userDetailsService боб.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo){
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
thrownew UsernameNotFoundException("Customer '" + username + "' not found");
};
}
The userDetailsService боб наема Spring Security’sUserDetailsService интерфейс за извличане на потребителско име и парола на потребител за удостоверяване по време на сесия за влизане на клиента. Така че, веднага щом клиент щракне върху бутона за влизане в изгледа за влизане, userDetailsService бобът се задвижва.
През UserRepository, на userDetailsService bean получава достъп до всички съществуващи клиенти в базата данни. След това този интерфейс използва UserRepository за да намери потребител със съответстващи потребителско име и парола, след което връща всички атрибути на този клиент като обект.
Ако върнатият обект е клиент, тогава този клиент получава достъп до приложението. В противен случай страницата автоматично ще се обнови, позволявайки на потребителя да въведе валидни идентификационни данни.
Филтърната верига
Spring Security'sSecurityFilterChain интерфейсът е полезен интерфейс за програмиране на приложения (API) който играе съществена роля в конфигурацията на Spring Security. Този интерфейс работи с Spring Security’sHttpSecurity клас за създаване на филтърна верига за конкретни HTTP заявки.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}
The filterChain bean по-горе използва SecurityFilterChain API за изпълнение на няколко задачи. Първо, той използва HttpSecurity клас, за да диктува, че само потребители, които имат ролята на ПОТРЕБИТЕЛ, имат достъп локален хост: 8080/потребител. И потребителят получава тази роля след регистрация, благодарение на getAuthorities() метод, който всеки нов клиентски обект изпълнява.
@Override
public Collection extends="extends" grantedauthority="grantedauthority"?> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
Филтърната верига позволява неудостоверен достъп до всички други URL адреси в приложението. The filterChain бобът също използва formLogin() и излез от профила си() методи на HttpSecurity клас обект.
Тези методи ви позволяват автоматично да насочвате потребител към конкретни страници, след като изпълни задача. И така, потребител, който въвежда правилните идентификационни данни и щраква върху бутона за влизане на /login страницата ще бъде автоматично насочена към /user страница.
И накрая, на filterChain bean изгражда и връща филтърната верига, която позволява на оторизирани потребители достъп до приложението. И трите боба в Конфигурация за сигурност класът работи заедно, за да защити вашето приложение.
както и да е filterChain bean играе по-важната роля за диктуване на нивото на разрешение за всяка HTTP заявка. Когато започнете да добавяте повече страници към вашето приложение, можете да използвате filterChain bean, за да зададете тяхното ниво на сигурност.
Основното предимство на пролетната сигурност
Spring Security ви дава пълен контрол не само върху това кой има достъп до вашето приложение, но и върху типа достъп, който потребителят може да има (чрез функцията за потребителски роли). Контролът на достъпа е един от най-важните аспекти на всяко приложение. Предоставянето на обикновени потребители на нефилтриран достъп до вашето приложение поради ограничения за контрол на достъпа може да се окаже скъпа грешка.