security: remove credentials from docs, centralize CORS, add reverse proxy support
This commit is contained in:
parent
f40888e7ee
commit
088f2b8736
|
|
@ -37,5 +37,8 @@ frontend/.flutter-plugins
|
||||||
frontend/.flutter-plugins-dependencies
|
frontend/.flutter-plugins-dependencies
|
||||||
frontend/build/
|
frontend/build/
|
||||||
|
|
||||||
|
# Claude Code (contient des tokens et commandes sensibles)
|
||||||
|
.claude/
|
||||||
|
|
||||||
# Docs sensibles
|
# Docs sensibles
|
||||||
memoire de fin d'etude.docx
|
memoire de fin d'etude.docx
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
| 3 | Backend Spring Boot API | ✅ Déployé & Fonctionnel |
|
| 3 | Backend Spring Boot API | ✅ Déployé & Fonctionnel |
|
||||||
| 4 | Frontend Flutter | ⏳ À faire |
|
| 4 | Frontend Flutter | ⏳ À faire |
|
||||||
| 5 | Tests & Validation | 🔄 En cours |
|
| 5 | Tests & Validation | 🔄 En cours |
|
||||||
| 6 | Déploiement Production | ✅ Docker sur 192.168.100.33:8090 |
|
| 6 | Déploiement Production | ✅ Docker — https://rayhan-erp.bolbol.tn |
|
||||||
| 7 | Rapport de PFE | 🔄 En cours |
|
| 7 | Rapport de PFE | 🔄 En cours |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -88,11 +88,9 @@
|
||||||
|
|
||||||
## Infrastructure Serveur
|
## Infrastructure Serveur
|
||||||
|
|
||||||
- **Serveur local** : 192.168.100.33
|
|
||||||
- **SSH** : port 22222, user Best0f
|
|
||||||
- **Portainer** : http://192.168.100.33:9000/
|
|
||||||
- **Gitea** : https://gitea.bolbol.tn
|
- **Gitea** : https://gitea.bolbol.tn
|
||||||
- **API REST** : http://192.168.100.33:8090 ✅ En ligne
|
- **API REST (production)** : https://rayhan-erp.bolbol.tn ✅ En ligne
|
||||||
|
- **API REST (local dev)** : http://localhost:8090
|
||||||
- **Conteneurs Docker** : `rayhan-mysql` + `rayhan-backend`
|
- **Conteneurs Docker** : `rayhan-mysql` + `rayhan-backend`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ Password : rayhan_erp_2024
|
||||||
|
|
||||||
> MySQL Workbench : https://dev.mysql.com/downloads/workbench/
|
> MySQL Workbench : https://dev.mysql.com/downloads/workbench/
|
||||||
|
|
||||||
**Note :** Sur le serveur de production (192.168.100.33), le port MySQL n'est pas exposé à l'extérieur par mesure de sécurité.
|
**Note :** Sur le serveur de production (localhost), le port MySQL n'est pas exposé à l'extérieur par mesure de sécurité.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
## Configuration de Base
|
## Configuration de Base
|
||||||
|
|
||||||
**URL de base** : `http://192.168.100.33:8090`
|
**URL de base** : `https://rayhan-erp.bolbol.tn`
|
||||||
|
|
||||||
### 1. Configurer une Variable d'Environnement Postman
|
### 1. Configurer une Variable d'Environnement Postman
|
||||||
|
|
||||||
Dans Postman, créer un environnement "Rayhan ERP" avec :
|
Dans Postman, créer un environnement "Rayhan ERP" avec :
|
||||||
- `baseUrl` = `http://192.168.100.33:8090`
|
- `baseUrl` = `https://rayhan-erp.bolbol.tn`
|
||||||
- `token` = (sera rempli automatiquement)
|
- `token` = (sera rempli automatiquement)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ La base de données `rayhan_erp_db` contient les tables suivantes :
|
||||||
|
|
||||||
## 4.1 Infrastructure
|
## 4.1 Infrastructure
|
||||||
|
|
||||||
L'application est déployée sur un serveur NAS Synology (192.168.100.33) via Docker Compose. Deux conteneurs sont en production :
|
L'application est déployée via Docker Compose, accessible publiquement derrière un reverse proxy HTTPS. Deux conteneurs sont en production :
|
||||||
|
|
||||||
- **rayhan-mysql** — MySQL 8, base de données `rayhan_erp_db`
|
- **rayhan-mysql** — MySQL 8, base de données `rayhan_erp_db`
|
||||||
- **rayhan-backend** — Spring Boot, accessible sur le port **8090**
|
- **rayhan-backend** — Spring Boot, accessible sur le port **8090**
|
||||||
|
|
@ -254,8 +254,8 @@ ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
|
|
||||||
| Service | URL |
|
| Service | URL |
|
||||||
|---------|-----|
|
|---------|-----|
|
||||||
| API REST | http://192.168.100.33:8090 |
|
| API REST | https://rayhan-erp.bolbol.tn |
|
||||||
| Documentation Swagger UI | http://192.168.100.33:8090/swagger-ui/index.html |
|
| Documentation Swagger UI | https://rayhan-erp.bolbol.tn/swagger-ui/index.html |
|
||||||
| Dépôt source (Gitea) | https://gitea.bolbol.tn/bolbol/rayhan-erp |
|
| Dépôt source (Gitea) | https://gitea.bolbol.tn/bolbol/rayhan-erp |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -272,7 +272,7 @@ L'API intègre **Swagger UI** (SpringDoc OpenAPI 2.5.0), accessible depuis n'imp
|
||||||
|
|
||||||
**Procédure de test :**
|
**Procédure de test :**
|
||||||
|
|
||||||
1. Ouvrir http://192.168.100.33:8090/swagger-ui/index.html
|
1. Ouvrir https://rayhan-erp.bolbol.tn/swagger-ui/index.html
|
||||||
2. Exécuter `POST /api/auth/signin` avec `{"username":"admin","password":"Rayhan2024!"}`
|
2. Exécuter `POST /api/auth/signin` avec `{"username":"admin","password":"Rayhan2024!"}`
|
||||||
3. Copier le token de la réponse
|
3. Copier le token de la réponse
|
||||||
4. Cliquer sur **Authorize 🔒** → coller le token → Authorize
|
4. Cliquer sur **Authorize 🔒** → coller le token → Authorize
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableMethodSecurity
|
@EnableMethodSecurity
|
||||||
|
|
@ -51,9 +56,26 @@ public class WebSecurityConfig {
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
config.setAllowedOriginPatterns(List.of(
|
||||||
|
"https://rayhan-erp.bolbol.tn",
|
||||||
|
"http://localhost:*",
|
||||||
|
"http://127.0.0.1:*"
|
||||||
|
));
|
||||||
|
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||||
|
config.setAllowedHeaders(List.of("*"));
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
|
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
|
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
|
||||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/articles")
|
@RequestMapping("/api/articles")
|
||||||
public class ArticleController {
|
public class ArticleController {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/auth")
|
@RequestMapping("/api/auth")
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/clients")
|
@RequestMapping("/api/clients")
|
||||||
public class ClientController {
|
public class ClientController {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/dashboard")
|
@RequestMapping("/api/dashboard")
|
||||||
public class DashboardController {
|
public class DashboardController {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/fournisseurs")
|
@RequestMapping("/api/fournisseurs")
|
||||||
public class FournisseurController {
|
public class FournisseurController {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/production")
|
@RequestMapping("/api/production")
|
||||||
public class ProductionOrderController {
|
public class ProductionOrderController {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/purchase-orders")
|
@RequestMapping("/api/purchase-orders")
|
||||||
public class PurchaseOrderController {
|
public class PurchaseOrderController {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/sales-orders")
|
@RequestMapping("/api/sales-orders")
|
||||||
public class SalesOrderController {
|
public class SalesOrderController {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/stock")
|
@RequestMapping("/api/stock")
|
||||||
public class StockController {
|
public class StockController {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@
|
||||||
# Serveur
|
# Serveur
|
||||||
server.port=8080
|
server.port=8080
|
||||||
|
|
||||||
|
# Reverse proxy HTTPS (Nginx/Traefik devant le conteneur)
|
||||||
|
server.forward-headers-strategy=framework
|
||||||
|
server.tomcat.remoteip.remote-ip-header=x-forwarded-for
|
||||||
|
server.tomcat.remoteip.protocol-header=x-forwarded-proto
|
||||||
|
|
||||||
# Base de données MySQL
|
# Base de données MySQL
|
||||||
spring.datasource.url=jdbc:mysql://localhost:3306/rayhan_erp_db?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Africa/Tunis
|
spring.datasource.url=jdbc:mysql://localhost:3306/rayhan_erp_db?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Africa/Tunis
|
||||||
spring.datasource.username=root
|
spring.datasource.username=root
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue