MS Lesson 21: Spring Security
1. Authentication vs Authorization
* Authentication - "Who are you?"
Istifadecinin kimliyinin yoxlanilmasi. Esasen username ve passwordun yoxlanilmasi.
Dogru olmadigi halda 401 Unauthorized xetasi verir.
* Authorization - "What can you do?"
Authentifikasiya olunmush istifadecinin hansi emeliyyatlara icazesi oldugunun yoxlanilmasi.
Dogru olmadigi halda 403 (Forbidden) xetasi verir.
2. Spring Security internal flow
Authentication - login melumatlarini dashiyan Java obyektidir.
AuthenticationManager - Authentication prosesini idare eden koordinator.
Default implementasiya ProviderManager. Filter-den Authentication obyektini alir, hansi AuthenticationProvider-in ishleyeceyini secir, Provider-e oturur.
AuthenticationProvider - esl Authentication mentiqinin oldugu yer. Default implementasiya DaoAuthenticationProvider. UserDetailsService-den user-i tapir, PasswordEncoder ile parolu yoxlayir, ugurlu olsa tam Authentication obytekti qaytarir.
UserDetailsService/Manager - User melumatlarini DB-den oxuyan servis. Default implementasiyasi InMemoryUserDetailsManager. Esas metodu: UserDetails loadUserByUsername(String username);
PasswordEncoder - parollari hash eden ve muqayise eden komponent. Default (production) BCryptPasswordEncoder.
SecurityContext - Authentikasiya olunmush user-in melumatinin saxlandigi yer. SecurityContextHolder (ThreadLocal) . Tomcat her request ucun ayri thread verir, ona gore paralel requestler bir birine qarishmir.
2. Indi ise sade Spring Security app yazaq.
Step1: dependency elave etmek:
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.boot:spring-boot-starter-security-test'
Step2: Controller yaradaq
package az.etibarli.lessonspecification.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/test")
public class TestController {
@GetMapping("/public")
public String publicEndpoint() {
return "public endpoint";
}
@GetMapping("/user")
public String userEndpoint() {
return "user endpoint";
}
@GetMapping("/admin")
public String adminEndpoint() {
return "admin endpoint";
}
}
Step3: Security konfiqurasiya yaradaq
package az.etibarli.lessonspecification.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/test/public").permitAll()
.anyRequest().authenticated()
);
http.httpBasic(Customizer.withDefaults());
return http.build();
}
}
Step4: Mock user-ler yaradaq
package az.etibarli.lessonspecification.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder.encode("12345"))
.roles("ADMIN")
.build();
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder.encode("12345"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(admin, user);
}
}
Step5: indi ise endpointlere access-leri deyishek
package az.etibarli.lessonspecification.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/test/user").hasRole("USER")
.requestMatchers("/api/v1/test/admin").hasRole("ADMIN")
.requestMatchers("/api/v1/test/public").permitAll()
.anyRequest().authenticated()
);
http.httpBasic(Customizer.withDefaults());
return http.build();
}
}
Комментарии
Отправить комментарий