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.

Authentication auth = new UsernamePasswordAuthenticationToken(
"admin", // username (principal)
"12345", // password (credentials)
null // authorities (hələ yoxdur)
);


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();
}

}






















































Комментарии

Популярные сообщения из этого блога

Interview questions

Lesson1: JDK, JVM, JRE

Lesson_2: Operations in Java