Concevoir, développer et sécuriser des micro-services avec Spring Boot
1. Concevoir et développer des
Micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services
DNG Consulting
Version 1.0
https://www.dng-consulting.com
Pour découvrir la totalité de cette formation
Rendez-vous sur https://www.dng-consulting.com/spring-boot-microservices/
3. DNG Consulting
Présentation
▰ La sécurité est essentielle lorsqu'il s'agit d'API
▰ Spring propose des fonctions couvrant :
▻ L'authentification : l'identification d'un utilisateur via ses credentials (login,
mot de passe, …)
▻ L'autorisation : les droits d'accès de l'utilisateur (rôles, …)
▰ L'architecture de Spring Security est constituée de filtres jouant
chacun un rôle dans la chaîne de sécurité
▻ Les filtres de servlet (SecurityFilterChain)
3
4. DNG Consulting
Le workflow Spring Security
1) Requête HTTP quelconque
2) Création du token d'identification basé sur les
credentials (login, mot de passe ,…)
3) Délégation du token à l'authentication manager
4) Tente de se connecter avec une liste de
fournisseurs
5) Nécessite un UserDetailService (cas du DAO)
6) 7) et 8) Renvoie un objet d'authentification
UserDetails ou UserObject
9) L'authentification est réalisée
10) Stockage de l'objet d'identification dans le
SecurityContextHolder
4
/courses
5. DNG Consulting
Contexte de sécurité
▰ Voici un exemple simple d'une application réalisant sa propre
authentification par login et mot de passe avec le rôle "USER"
5
@Service
public class CourseService {
public void login(String username, String password) {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add(new SimpleGrantedAuthority("USER"));
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(username, password,list );
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
▰ L'objet SecurityContextHolder stocke les éléments
d'authentification de type Authentication
6. DNG Consulting
L'authentification
▰ Dans l'exemple précédent, la validation du login et du mot de passe
n'est jamais réalisée car on stocke directement un contexte de
sécurité qu'on définit comme "valide"
▰ La classe AuthenticationManager est celle qui permet de vérifier
réellement les credentials
6
public void login(String username, String password) {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add(new SimpleGrantedAuthority("USER"));
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(username, password,list );
Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
if (authenticate.isAuthenticated())
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
Classe technique injectée
7. DNG Consulting
Les différents modèles d'authentification
▰ Il existe des classes techniques prenant en charge automatiquement
le workflow précédent via des filtres de servlet
▰ Spring Security intègre de nombreux modèles :
▻ HTTP (Forms/Basic Login, …)
▻ LDAP, JWT, OpenID
▻ JAAS, CAS, JDBC, ACL, …
▰ Et aussi une implémentation spécifique s'appuyant sur la classe
UserDetailsService et l'authentification à base de DAO
7
9. DNG Consulting
Où et comment définir le mode d'authentification
9
@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password(encoder().encode("adminPass")).roles("ADMIN")
.and()
.withUser("user").password(encoder().encode("userPass")).roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.exceptionHandling()
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/**").authenticated()
.antMatchers("/admin/**").hasRole("ADMIN");
}
}
Configuration du modèle
d'authentification
(ici "mémoire" pour le
mode développement)
Configuration des règles
de sécurité centralisées
s'appliquant
aux requêtes HTTP
Mémoire, JDBC, LDAP,
UserDetailService, etc …
Toutes les URL doivent
être authentifiées
La page d'admin ne peut être
accédée que par un rôle Admin
10. DNG Consulting
Exemples de configurations d'authentifications
10
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource()
.url("ldap://localhost:389/dc=mycompany,dc=org")
.and()
.passwordCompare()
.passwordEncoder(passwordEncoder())
.passwordAttribute("userPassword");
}
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).withDefaultSchema().passwordEncoder(enc)
.withUser("user").password(enc.encode("password")).roles("USER").and()
.withUser("admin").password(enc.encode("password")).roles("USER", "ADMIN");
}
LDAP
JDBC
Informations stockées dans
application.properties
ou application-xx.yml
11. DNG Consulting
Règles d'autorisations via annotations
11
@RestController
@RequestMapping("/api")
public class TestService {
@Secured("ROLE_USER")
@RequestMapping("/currentUser")
public Principal information(Principal principal) {
return principal;
}
@PreAuthorize("hasRole('ROLE_USER') and hasRole('ROLE_TRAINER')")
@RequestMapping("/courses")
public List<Course> courses() {
return courseDAO.getCourses();
}
}
▰ Possible de définir les règles directement au niveau des composants
12. DNG Consulting
La classe UserDetailsService
▰ Illustration d'une
authentification
personnalisée DAO
12
public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(userDetailsService);
} (…)
@Service
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDAO;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDTO user = userDAO.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new UserDetailsImpl(user);
}
}
13. DNG Consulting
La classe UserDetails
13
public class UserDetailsImpl implements UserDetails {
String ROLE_PREFIX = "ROLE_";
private UserDTO user;
public UserDetails(UserDTO user) {
this.user = user;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
List<AuthorisationVO> roles = user.getRoles();
for(AuthorisationVO item : roles) {
grantedAuthorities.add(new SimpleGrantedAuthority(
ROLE_PREFIX+item.getAuthorisation()));
}
return grantedAuthorities;
}
(...)
}
@RestController
@RequestMapping("/api")
public class TestService {
@RequestMapping("/currentUser")
@ResponseBody
public Principal information(Principal principal) {
return principal;
}
}
http://localhost:8080/api/currentUser
• La classe Principal est
automatiquement injectée dans le
contrôleur REST
• La classe UserDetailsImpl
définit le l'identité de l'utilisateur
(Principal)
14. DNG Consulting
Sécurité Monolitique vs Micro-services
14
AUTH
SA
Session
HTTP
Session
HTTP
Composants État
AUTH
Service A
Service B
Monolithique
Micro-servicesToken
▰ L'authentification
est associée à l'état
de l'application
(stateful)
▰ L'authentification
est décentralisée,
sans état et gérée
par un service dédié
pour assurer le SSO
Token
Token
Token
15. DNG Consulting
OpenID et les technologies SSO
▰ OAuth2 est un Framework qui cible l'autorisation d'accès. Permet
d'autoriser un site web, un logiciel ou une application à utiliser l'API
sécurisée d'un fournisseur pour le compte d'un utilisateur via un
périmètre d'accès (les fameux "scope")
▰ JWT est un format de jeton encodé en JSON
▰ OpenID Connect est un standard bâtit sur OAuth2 ajoutant
l'authentification
▰ JOSE : JavaScript Object Signing
and Encryption cible la sécurité
15
Open ID Connect
OAuth2 JWT+JOSE
16. DNG Consulting
Le vocabulaire OAuth2
▰ Resource Owner : La personne ou l'application qui possède les
données à partager
▰ Resource Server : L'application qui contient les ressources protégées
▰ Authorization Server : L'application qui vérifie l'identité des
utilisateurs
▰ Client : L'application qui réalise la requête au Resource Server de la
part du Resource Owner
16
17. DNG Consulting
Le workflow OAuth 2
17
Res. Owner
Res. Server
Client
Authorization
Server
J'aimerai récupérer la liste des cours du catalogue
http://server/training/courses
Hey le backend, tu veux bien me donner cette liste ?
1
2
18. DNG Consulting
Le workflow OAuth 2
18
Res. Owner
Res. Server
Client
Authorization
Server
Désolé mais c'est une ressource protégée, va falloir
me présenter un jeton d'accès (Token Access)
3
4
19. DNG Consulting
Le workflow OAuth 2
19
Res. Owner
Res. Server
Client
Authorization
Server
Hello, pourrais tu me donner ton identité ?
5
6
20. DNG Consulting
Le workflow OAuth 2
20
Res. Owner
Res. Server
Client
Authorization
Server
Oui, c'est claudie@gmail.com et voilà mon mot de passe
7
8
21. DNG Consulting
Le workflow OAuth 2
21
Res. Owner
Res. Server
Client
Authorization
Server
Hey Backend, voilà mon token
Token : dfsfdsf434DF@ffdS
9
10
22. DNG Consulting
Le workflow OAuth 2
22
Res. Owner
Res. Server
Client
C'est bon, tout est en ordre,
voici la liste des cours du catalogue
12
11
Voicilescours
Claudie
13
23. DNG Consulting
SSO et Micro-services avec JWT
▰ Le format JWT apporte le bénéfice d'une gestion sans état
▰ JWT permet de vérifier le contexte de sécurité d'un utilisateur sans
avoir à systématiquement interroger le serveur d'authentification
▻ En utilisant un mécanisme de clés cryptographiques signées
▰ Intéressant lorsque les appels entre les micro-services sont
importants et doivent être authentifiés
▻ Ne pas oublier qu'un micro-service peut s'arrêter et se lancer souvent avec le
risque d'une perte de la session HTTP
23
24. DNG Consulting
Vous souhaitez suivre cette formation en entier ?
▰ Rendez-vous sur notre site, réservez votre place
https://www.dng-consulting.com/spring-boot-microservices/
24