Guest User

Untitled

a guest
Jun 27th, 2025
98
0
134 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.26 KB | Source Code | 0 0
  1. /*
  2. * Background -> Learning Spring Security
  3.  
  4. * Requirements -> to create a "all-in-one" authentication mechanism that allows multiple methods of authentication (e.g. authentication via username, via email, via phone number, oauth, OTP, etc.)
  5.  
  6. * Logic -> Create custom `SecurityFilterChain` to personalize access routes, custom `PasswordEncoder` for using Argon2PasswordEncoder, as well as custom `UserDetailsService` to allow loading `UserDetails` in spring via JPA/Hibernate
  7.  
  8. Problem -> I can authenticate via username just fine, but using email to authenticate throws an error, because the `myCustomAuthenticationProvider.authenticate()` method calls "loadUserByUsername()" method... which is fine if I am passing a username into it... but what if I am passing an email into it? It won't be able to load the UserDetails object, because, well.. it needs a username for it.
  9.  
  10. Further steps -> I am unable to think what to do from now. I can't think of a way to overload the `loadUserByUsername` method, nor does spring allow me to do that. Moreover the `myCustomUserDetailsService.loginUserByEmail(String email, String password)` method defined in my own custom `UserDetailsService` is calling the `loadUserByUsername` method (which I think is by design, since in spring security architecture, the authentication manager HAS to call it to authenticate the credentials?)
  11.  
  12. */
  13.  
  14. // File - WebSecurityConfig.java
  15.  
  16. @Configuration
  17. @EnableWebSecurity
  18. public class WebSecurityConfig {
  19.    
  20.    
  21.     @Autowired
  22.     private AuthService authService;
  23.    
  24.     @Autowired
  25.     private PasswordEncoder passwordEncoder;
  26.    
  27.    
  28.     @Bean
  29.     public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
  30.        
  31.         httpSecurity.
  32.             csrf(csrf -> csrf.disable()).
  33.             authorizeHttpRequests(auth -> auth.
  34.                     requestMatchers("/auth/register", "/auth/login/username").permitAll().
  35.                     anyRequest().authenticated()
  36.             ).
  37.             authenticationManager(authenticationManager());
  38.        
  39.         return httpSecurity.build();
  40.     }
  41.    
  42.    
  43.     @Bean
  44.     public AuthenticationManager authenticationManager() {
  45.         DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(authService);
  46.         authenticationProvider.setPasswordEncoder(passwordEncoder);
  47.         return new ProviderManager(authenticationProvider);
  48.        
  49.     }
  50.    
  51.     @Bean
  52.     public PasswordEncoder encoder() {
  53.         return new Argon2PasswordEncoder(10, 50, 100, 1024, 20);
  54.     }
  55.    
  56.    
  57. }
  58.  
  59.  
  60.  
  61. // File - AuthService.java
  62.  
  63. import org.springframework.security.core.userdetails.UserDetails;
  64. import org.springframework.security.core.userdetails.UserDetailsService;
  65. import org.springframework.stereotype.Service;
  66.  
  67. import com.ramyak.springsecuritywithjwt.dto.UserDTO;
  68.  
  69. import jakarta.servlet.http.HttpServletRequest;
  70.  
  71. @Service
  72. public interface AuthService extends UserDetailsService {
  73.  
  74.     public UserDTO RegisterNewUser(UserDTO userDTO, String requestURL);
  75.  
  76.     public String loginUserByEmail(String email, HttpServletRequest httpServletRequest);
  77.  
  78.     public UserDetails loginUserByUsername(String username, HttpServletRequest httpServletRequest);
  79.    
  80.  
  81. }
  82.  
  83.  
  84. // File - AuthServiceImpl.java
  85.  
  86. @Component
  87. public class AuthServiceImpl implements AuthService {
  88.    
  89.     @Autowired
  90.     private AuthRepository authRepository;
  91.    
  92.  
  93.      // Here is where I am facing problem, my authManager is calling this method, which I have also confirmed with the debugger. No surprises here, since its in the architecture of spring to call it, but what do I do if email comes here?
  94.     @Override
  95.     public UserDetails loadUserByUsername(String username) {
  96.         System.out.println("Inside loadUserByUsername"); /// This gets printed out to console
  97.         Optional<AppUser> u = authRepository.findByUsername(username);
  98.         return null;
  99.     }
  100.    
  101.    
  102.  
  103.     @Override
  104.     public UserDTO RegisterNewUser(UserDTO userDTO, String requestURL) {
  105.         Optional<AppUser> u = authRepository.findByUsername(userDTO.getUsername());
  106.         if (u.isEmpty()) {
  107.             AppUser u1 = new AppUser();
  108.             u1.setPassword(new Argon2PasswordEncoder(10, 50, 100, 1024, 20).encode(userDTO.getPassword()));
  109.             authRepository.save(u1);
  110.             u1.setEmail(userDTO.getEmail());
  111.             u1.setUsername(userDTO.getUsername());
  112.             u1.setRole(userDTO.getRole());
  113.             u = Optional.of(authRepository.save(u1));
  114.             return UserDTO.convertEntitytoDTO(u.get());
  115.         } else {
  116.             System.out.println("User already exists");
  117.             return UserDTO.convertEntitytoDTO(new AppUser(null, null, null, null, null));
  118.         }
  119.  
  120.     }
  121.  
  122.     @Override
  123.     public String loginUserByEmail(String email, HttpServletRequest httpServletRequest) {
  124.         // TODO Auto-generated method stub
  125.         return null;
  126.     }
  127.  
  128.     @Override
  129.     public UserDetails loginUserByUsername(String username, HttpServletRequest httpServletRequest) throws UsernameNotFoundException {
  130.         System.out.println(new Argon2PasswordEncoder(10, 50, 100, 1024, 20).toString());
  131.         Optional<AppUser> oau = authRepository.findByUsername(username);
  132.         UserDetails u = User.withUsername(oau.get().getUsername()).password((oau.get().getPassword())).roles(oau.get().getRole()).build();
  133.         return u;
  134.     }
  135.    
  136.    
  137. }
  138.  
  139.  
  140.  
  141. // File - AuthController.java
  142.  
  143. @RestController
  144. @RequestMapping(path = "/auth")
  145. public class AuthenticationController {
  146.    
  147.     @Autowired
  148.     private AuthService authService;
  149.    
  150.     @Autowired
  151.     private AuthenticationManager authenticationManager;
  152.    
  153.    
  154.     @PostMapping("/register")
  155.     public ResponseEntity<UserDTO> registerNewUser(@RequestBody UserDTO userDTO, HttpServletRequest httpServletRequest) {
  156.         UserDTO registeredUserDto = authService.RegisterNewUser(userDTO, httpServletRequest.getRequestURL().toString());
  157.         return new ResponseEntity<UserDTO>(registeredUserDto, HttpStatus.OK);
  158.        
  159.     }
  160.    
  161.     @PostMapping("/login/username")
  162.     public ResponseEntity<?> loginUserByUsername(@RequestBody LoginRequestDTO loginRequestDTO, HttpServletRequest httpServletRequest) throws UsernameNotFoundException {
  163.         UserDetails result = authService.loginUserByUsername(loginRequestDTO.getUsername(), httpServletRequest);
  164.         if (result != null) {
  165.             UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(result, result.getPassword());
  166.             authenticationManager.authenticate(upat); // Error occurs here
  167.         }
  168.         return null;
  169.        
  170.     }
  171.    
  172.     @PostMapping("/login/email")
  173.     public ResponseEntity<?> loginUserByEMail(HttpServletResponse httpServletResponse) {
  174.         return null;
  175.        
  176.     }
  177.  
  178. }
  179.  
  180.  
  181.  
Advertisement
Add Comment
Please, Sign In to add comment