Aller au contenu

Sécurité & Authentification (dynors-security)

Objectif : expliquer comment sécuriser une application client en s’appuyant sur dynors-security, sans mélanger avec l’auth interne LDAP (réservée à RAGNAR/TAKKU).


1. Rôle de dynors-security vs LDAP

  • dynors-security (ce module) :
  • Pour les applications clients (tenants).
  • Authentifie les utilisateurs finaux (clients de SeckShop, employés du client, étudiants MIAMCAMPUS, etc.).
  • Gère : JWT, OAuth2 (Google, Facebook, …), authentification par base de données, rôles/permissions (RBAC), MFA.
  • LDAP (dynors-internal) :
  • Pour l’infrastructure interne DYNORS (employés).
  • Utilisé par RAGNAR, TAKKU, HEISENBERG, RED, GitLab, etc.
  • Jamais utilisé directement par un projet client.

👉 Un projet client n’utilise pas LDAP. Il expose des endpoints publics (/api/auth/login, /api/auth/oauth2/...) qui reposent sur dynors-security.


2. Dépendances & configuration de base

Dans le build.gradle.kts du projet client :

dependencies {
    implementation(platform("com.dynors:dynors-core-bom:1.0.0"))
    implementation("com.dynors:dynors-security")
    // déjà présents : dynors-commons, dynors-db, Spring Boot, ...
}

Configuration minimale dans application.yml :

dynors:
  security:
    provider: jwt  # ou oauth2, database, hybrid

    jwt:
      secret: ${JWT_SECRET}
      expiration: 86400   # 24h en secondes

    database:
      enabled: true
      user-table: users
      username-column: username
      password-column: password

3. Flux typique d’authentification JWT

  1. L’utilisateur envoie ses credentials sur /api/auth/login.
  2. L’application vérifie username/password (Database Authentication).
  3. dynors-security génère un JWT qui contient :
  4. l’identifiant utilisateur,
  5. ses rôles/permissions,
  6. le code du tenant.
  7. À chaque requête suivante, le frontend envoie Authorization: Bearer <token>.
  8. Un filtre JwtAuthFilter valide le token et reconstruit le contexte de sécurité.

Exemple simplifié de génération de token :

@Autowired
private JwtService jwtService;

String token = jwtService.generateToken(
    user.getUsername(),
    Map.of(
        "role", "ADMIN",
        "tenant", tenantCode
    )
);

4. Intégration avec Spring Security

Dans un projet client, Spring Security est configuré pour :

  • autoriser /api/auth/** (login, refresh, etc.) sans être authentifié,
  • protéger les autres endpoints en JWT.

Exemple de SecurityConfig (simplifié) :

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private JwtAuthFilter jwtAuthFilter; // fourni par dynors-security

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session ->
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

5. Rôles & permissions (RBAC)

dynors-security fournit un système de rôles / permissions :

  • Rôles (ex : ADMIN, USER, MANAGER…)
  • Permissions plus fines si nécessaire.
  • Annotation @RequiresRole pour protéger les méthodes.

Exemple :

@RestController
public class UserController {

    @RequiresRole("ADMIN")
    @DeleteMapping("/api/users/{id}")
    public void deleteUser(@PathVariable String id) {
        // Seuls les ADMIN peuvent supprimer
    }
}

Les rôles/permissions par tenant sont configurés via TAKKU (ou via une interface d’admin propre au projet), et chargés par TenantSecurityLoader.


6. Points d’attention pour les projets clients

  • Ne pas mélanger :
  • Apps internes (auth LDAP + dynors-security ensuite)
  • Apps clients (dynors-security uniquement).
  • Toujours inclure le code tenant dans le JWT pour que la sécurité et dynors-db restent alignés.
  • Centraliser la configuration de sécurité par tenant plutôt que coder les rôles en dur dans chaque projet.

Pour plus de détails, se référer à : - core/packages/core/security/README.md - core/INTERACTIONS_DYNORS_INTERNAL.md (pour comprendre le rôle de RAGNAR/TAKKU).