From 915f7a06f9f601eb7ca021a3648c32ea0d8617e1 Mon Sep 17 00:00:00 2001 From: Subivas Date: Mon, 1 Dec 2025 18:09:42 +0100 Subject: [PATCH] =?UTF-8?q?feat=20:=20ajout=20fonctionnalit=C3=A9=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 +- .../controller/AuthController.java | 17 ++-- .../security/CustomUserDetailsService.java | 24 +++--- .../fotosharing/security/SecurityConfig.java | 76 +++++++++--------- .../controller/AuthController.class | Bin 3445 -> 3218 bytes .../security/CustomUserDetailsService.class | Bin 2895 -> 3492 bytes .../fotosharing/security/SecurityConfig.class | Bin 6417 -> 6147 bytes 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/pom.xml b/pom.xml index d221a81..c5c8dac 100644 --- a/pom.xml +++ b/pom.xml @@ -79,17 +79,13 @@ spring-boot-starter-webmvc-test test - - org.springframework.boot - spring-boot-starter-actuator - org.springframework.boot spring-boot-starter-security - jakarta.validation - jakarta.validation-api + org.springframework.boot + spring-boot-starter-validation diff --git a/src/main/java/local/epul4a/fotosharing/controller/AuthController.java b/src/main/java/local/epul4a/fotosharing/controller/AuthController.java index bacef49..00052f1 100644 --- a/src/main/java/local/epul4a/fotosharing/controller/AuthController.java +++ b/src/main/java/local/epul4a/fotosharing/controller/AuthController.java @@ -2,6 +2,7 @@ package local.epul4a.fotosharing.controller; import local.epul4a.fotosharing.model.Utilisateur; import local.epul4a.fotosharing.repository.UtilisateurRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,7 +14,9 @@ import jakarta.validation.Valid; @Controller public class AuthController { + @Autowired private final UtilisateurRepository utilisateurRepository; + @Autowired private final PasswordEncoder passwordEncoder; public AuthController(UtilisateurRepository utilisateurRepository, PasswordEncoder passwordEncoder) { @@ -37,21 +40,19 @@ public class AuthController { } @PostMapping("/register") - public String doRegister(@ModelAttribute("utilisateur") @Valid Utilisateur utilisateur, - BindingResult bindingResult, Model model) { - if (bindingResult.hasErrors()) { - return "register"; - } - + public String register(@ModelAttribute Utilisateur utilisateur, Model model) { + // Vérifier si l'email existe déjà if (utilisateurRepository.findByEmail(utilisateur.getEmail()).isPresent()) { - model.addAttribute("error", "Email déjà utilisé"); + model.addAttribute("error", "Cet email est déjà utilisé"); return "register"; } - // encoder le mot de passe puis sauvegarder + // CRUCIAL : Encoder le mot de passe avant de sauvegarder utilisateur.setMotDePasse(passwordEncoder.encode(utilisateur.getMotDePasse())); utilisateur.setActif(true); + utilisateurRepository.save(utilisateur); + return "redirect:/login?registered"; } } \ No newline at end of file diff --git a/src/main/java/local/epul4a/fotosharing/security/CustomUserDetailsService.java b/src/main/java/local/epul4a/fotosharing/security/CustomUserDetailsService.java index 77cb8f8..0f66256 100644 --- a/src/main/java/local/epul4a/fotosharing/security/CustomUserDetailsService.java +++ b/src/main/java/local/epul4a/fotosharing/security/CustomUserDetailsService.java @@ -2,6 +2,9 @@ package local.epul4a.fotosharing.security; import local.epul4a.fotosharing.model.Utilisateur; import local.epul4a.fotosharing.repository.UtilisateurRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; @@ -9,16 +12,19 @@ import org.springframework.stereotype.Service; @Service public class CustomUserDetailsService implements UserDetailsService { - private final UtilisateurRepository utilisateurRepository; - - public CustomUserDetailsService(UtilisateurRepository utilisateurRepository) { - this.utilisateurRepository = utilisateurRepository; - } + @Autowired + private UtilisateurRepository utilisateurRepository; @Override - public CustomUserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - Utilisateur u = utilisateurRepository.findByEmail(username) - .orElseThrow(() -> new UsernameNotFoundException("Utilisateur introuvable: " + username)); - return new CustomUserDetails(u); + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + Utilisateur utilisateur = utilisateurRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("Utilisateur non trouvé : " + email)); + + return User.builder() + .username(utilisateur.getEmail()) + .password(utilisateur.getMotDePasse()) // Le hash BCrypt depuis la BD + .disabled(!utilisateur.isActif()) + .authorities("USER") + .build(); } } \ No newline at end of file diff --git a/src/main/java/local/epul4a/fotosharing/security/SecurityConfig.java b/src/main/java/local/epul4a/fotosharing/security/SecurityConfig.java index 254b9db..0cefae8 100644 --- a/src/main/java/local/epul4a/fotosharing/security/SecurityConfig.java +++ b/src/main/java/local/epul4a/fotosharing/security/SecurityConfig.java @@ -1,63 +1,59 @@ package local.epul4a.fotosharing.security; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.Customizer; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 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.web.SecurityFilterChain; +import java.io.DataOutput; + @Configuration @EnableMethodSecurity +@EnableWebSecurity public class SecurityConfig { - private final CustomUserDetailsService customUserDetailsService; - - public SecurityConfig(CustomUserDetailsService customUserDetailsService) { - this.customUserDetailsService = customUserDetailsService; - } - - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - - http - .authorizeHttpRequests(auth -> auth - .requestMatchers("/login", "/register", "/css/**", "/js/**").permitAll() - .anyRequest().authenticated() - ) - .formLogin(form -> form - .loginPage("/login") - .defaultSuccessUrl("/", true) - .permitAll() - ) - .logout(logout -> logout - .logoutSuccessUrl("/login?logout=true") - .permitAll() - ) - .csrf(csrf -> csrf.disable()); - - return http.build(); - } - - @Bean - public UserDetailsService userDetailsService() { - // Spring Security 6.2 utilise ce bean automatiquement - return customUserDetailsService; - } - - @Bean - public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { - // Spring Boot crée automatiquement un DaoAuthenticationProvider interne - return config.getAuthenticationManager(); - } + @Autowired + private CustomUserDetailsService customUserDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .userDetailsService(customUserDetailsService) // Utiliser directement le UserDetailsService + .authorizeHttpRequests(auth -> auth + .requestMatchers("/register", "/login", "/css/**", "/js/**").permitAll() + .anyRequest().authenticated() + ) + .formLogin(form -> form + .loginPage("/login") + .defaultSuccessUrl("/", true) + .failureUrl("/login?error=true") + .permitAll() + ) + .logout(logout -> logout + .logoutSuccessUrl("/login?logout") + .permitAll() + ); + + return http.build(); + } } + diff --git a/target/classes/local/epul4a/fotosharing/controller/AuthController.class b/target/classes/local/epul4a/fotosharing/controller/AuthController.class index 97793d6ba08b24fccd7492cb8cd0fd1dc10a293f..c59934b98ee14207dc5c690b2c6b4891a7c32a44 100644 GIT binary patch delta 1074 zcmah|OHUI~7(I77bV@rdP^1VxXtg3x$|z4C1?5qEq9|IlXk~z*v_h+$L1JRU(ly?d zapOW4>@XSRsI*^Sr1c`GxUF*lZN-fk5=h%$K7hBcJ828?0dGz|~VqgO$nihc|* z#Fn;Vyh@Ha2UT3aMLsGwAGxgJ3a&D^OvCD(v@+8SaznB);em#0Dz0Ogzm;3rP5xD` zA76q(ydHBr}fTT`Grium?F{7_;=;N(n{!kdx^!W zCmG7K`V(E7)pKcW#42QRX@++GjaBhY=O#-Lx{s$^L#*R>ZXXYn`slb<)Yb^u=mf(p zn*At4ImLT(GObH+8xj({!W~SE3Y<)105Ymkiv94R26reEgoDO1+(nXRJMuuK{dQzC zOBkcLRHC$<0+sIJKG7ujb9c|8P3;pDb*Lh;CWHiS6Cr?Tkv2*~Q-U^1s1(uK)dv`- zy*kA+khkdwS%FKzg!t7$Qcz3bHr4+uICctbdl8j?mHxX&^y77q9=myv1_<+fq;87- z#u%81X{0HC)Io_E5^I=*&m@uET?g&8H%lmnhnS^468wuNEF5u*{_4rTwlhB~01q2Df?W)uG0W{QxJRu4({ZdIdT>m~aRa?L!H|0LEyX{n zDeox*edyk5+oF;oN5$F>`A-ca|8E}?`%s>|7z&ss9z#4H zY>*uZNPb(WeGRf3HF96I)Qu|1oXJu=Y?Tsj5^xa?DLF(*<|%?%tq%v}_j9L{J$fKEDLgdn2#!=yNvRRwMX&G0>ph7;GSA?oU z2)UKs43LC=`f-S##zrJ**GfXQ(+A!`pYCp)#-3#Yra+mxB9pejqjUf@ydN F`~sXR?8yKC diff --git a/target/classes/local/epul4a/fotosharing/security/CustomUserDetailsService.class b/target/classes/local/epul4a/fotosharing/security/CustomUserDetailsService.class index b9e91841f79083212991e99bd2422e71547c4c7b..6cbfc95a1270e3296be38df5ef1075815621969b 100644 GIT binary patch delta 1313 zcmZWpTW=dh6#mBR^|!jgk%B_!;*f*Y$5Dy3{kPAUvB;I&INcP&*2QighV@j5RD)jgl!p{ zf?>&@ROg!qAGeE*XgDj2bx^UK?ahk3;krUXk7;;b;)d%K*|wdE?CnJjFJYW`nC?{B zGuIfDguW`%&ud8I0;N|>*C^FQg<&SKsxR73HRaZ2!)uP=4=IBe5B0z?!4P|#TNslJ z!D1nMRYFf|n87SV)M$7&ZO8OX;W88x*ZnDVZtxJCOrO&*k5?Gfw$==peWjzb!Xq`^ zG{;5%m~tt!s3C_-{<@NlE+DT##TAAg(y5y-a}*dRrKCO&#{3JR6X(VcbJ-Lm%0{Xr z49iWe8D-CQc2b6A*`DE4}EpGxhA5j)G^DH*!XONovdx$=)i9x~xZv#Bzf4spJiZz&+u({$2GO z|5|85-+25AT`sMQvX_1$gv|)TuryR4VyOGSh4LeGJNt`|3db$mihGXT*!tt^`1v@a zLtX?8Y;kOBxP_hXC%DQw-;LlsywCB0RJG|}3IE+q1P)woj*l4z{cm~i=iyM)9ayyO zjYgg0Q$K%Xta%j-0YssZU7{B$M7Bs)A*;5%W%5$wF|um%KG;3l1n?TIG8yQ=HCiPA zC13@sWErmG27$=K|4>vRJD>akeE27H1Tegdqd*J2&EIh{_amM<-NIlCI+;`pqhwzA z0zCK?f=UbLg1;cMqIA7nXkn^_?01BvwCfMy2<^KOLl1iC*N-Q03VqOV9FyeD-~{F< zF8hn`^|0R`b%WRO2AYf>kKj$bMU)Im(-C-pF(@2ijtr-Fk8va)$dZpj0SYmcC>SKB z3ncgSj kB;TZe7aev9cpWv^c!vtSjSu(ZNn&}M_LUVEd)zu@mMo+%1OFLus3v**0eJ3ISk&zBbc^UsZs0M24&RgWkd zhsDrcebrW-4*GPodT;b&CQNTMu!I-1`gv0gISn&9;6p?rNJk1Ejn{K zhLNy%?rz>v;Yp4N!?18%U82()&`mHz4a9I%JX2Ff7;%Z{WC+NqCZ6HwV(72;hg4pD z>Q(v(o>U?kv8*kM@4TtQQ`u&jV~?CgCth%hv+>DtDPNpTGO!9mY|C(Sqn=ut$vrOT z=Zgyr6B05cLaImn;BSSk?G;r|AG;{NdV=O9d9qOh{TT3LoMAL9rd&PbdUt$+A($@b z3;6}7oU4?qe6d`buPi##gju)uyj$|B%y&~q7PmNV%j4b=FZ6FN zjwvzMV7ncLkXZ4C#Cn6de4IXsi3S*S6K={?bVET8RYMdNin?6`v!frtSE*8Pf>s|~ z_0^3=c;UxMs#>F7G@1hGNRCm@wcnioHU04G^75!nO7@br9QJJ@oV7P#12r7` zS2}=+9c^FTx%4_ng9^^$0!8T|MRAB8lXkC=@GwR&h8y(eGVap8PT4)&$28i00Xw9E AL;wH) diff --git a/target/classes/local/epul4a/fotosharing/security/SecurityConfig.class b/target/classes/local/epul4a/fotosharing/security/SecurityConfig.class index 1bdaef235ab8cf591f2fd32977c157d51c01d196..410a6e2ef807a232147342263278970f97991455 100644 GIT binary patch delta 1560 zcmZ8hTT@$A6#h23oaAH!Ng&)qxm8S%CQztgp)}TNwP0IXWax}&fCFX>IrNa&Vp}7{ zYE?wz_R?ClTJNnFDxGx1!Rh$mRA2lBKKP(-KKQDm@Px&(t5htpg>J7TyN#n+#_f~3G2O3EMPhCgAhYG?Xpvjis6M49;u77; zu>}F~XhFTXjiEyvFnPtrg7QWiwlWk32pEa=-Gp~yn}Rzzy3ozAFQfElOP#P=PTD%L zoudc6V#zX5)ki6^M^%Jyw}M?9_h2`}VD5}l?6ocy-^aiL5^+Dr1K2Bmw~96!1{hqq zyqaO?MsM6mXcD!LV?PcssFUGHG+}5%MwH>W*km~*ZYa$*2{}j_R_2wz80!%y?B`iP zRH#00G5zpqQ_<#y2QNI(>SJuW3z$D@OWG|<^th$Kp>Qe z>qjGoHnCmIt5NZH;gD$K!Id?>gB7W}kBw_H86E{siGLgw9_N4-e@vg)A2!0%T3jsQ=p4t3Saf2s*owDh;2nr^~730P0whi<|P{= z&q`J&tB|#1yczNWc?=0WK`42+ovg&!zC}_Q zxd!_(Ir#+MJOW#e;HH+N8M0%TgE>RiO;l2~r6mpZ|3nQLqOvR?M?_FOiQ{za1dt>a zhLdC|%qWiakIp7~8uPhCM~Fox^0oM{!kI?dDr$f<>Q>Pt?dDb7F0F5vl-zM0!3{B0 zR2b0jY9T}+d{o<3c(Ii#p6tp~=v!Cl!znCe72YcF)U5*PS)nE%pe$>Mt#}Dbv}eZ4G#B8N%cq_L$k9Tvc3%H0&gsLLMC@$j*l0Q!NOO=Fug)3M=<$ovT9c%yq delta 1817 zcmZWqTT@$A6#jN@C!8EYI0;Y?iUdmGPz(jJtrWwp6e|=87KR7W5CTmN2_}cOSZi!i zYpaOq_I|CGdcU;N2AitGlg>D!e?fil#ToxV9~{?CG7#h;XRZCMwZ8T3z1N;BHYJ+n zU;a(~2%sI`CuC249<0cdAS-|>jNNt>P6;jrMJQ(I<7dq+{0~Es ziJ{2HkH{|WH!cp^WvD1sP$qKnrX$hW{>V%)tiphFs6xSZ5we6LGm&{+g)xIyDR2wi z!QB#C z72Jb83|;nc}Nw{CZAw0k^EEMsj0w?!c777L!m`7v`Dj32M{OzOf6!;+BM z$%o_zSuMXJ*BiZc{XERv{C8Grs2}Ckworv*AfO+MObz*>zS)2th{hP4vFx6D`BMI0 zcKN_5e_&1zM#3=(r}-oK+xTyCIcwyF#v*>(R>p@7MTQ>Hs)}DQxK~uAgYjkC(W>&0 zZ+3FZSF=tR3{ivbW4>UxriHdt$N#iYK}KJLbTfG=z2i$9*S!o{%p*;~AVh9`Ng=qrifwF>il>_bdvhe4*Cm^A4vSQ`NwQFUj)*oldK%AU6*rR= z;;gse8DGWj^Er-fN2mc&E)ij~m z>dvebo2Kqf;@%`Wawt?f7&_)!8l#;gt&WDJHiyqfm-&2}kDfr5?=a;GH7-rmyNVuMmi%EV6XcDW^aGBL z8`YkXag#d6M@wqrbA)H+y%MD)%uQ3dLDz^&;FMv)%k(wimGs@nwSXH@h#<-QSJm*a07)7_{m9