Changes between Version 16 and Version 17 of UseCaseImplementation


Ignore:
Timestamp:
02/20/25 15:54:17 (2 days ago)
Author:
222077
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • UseCaseImplementation

    v16 v17  
    396396===
    397397
    398 
     398== **ID-5** - Login
     399The `/login` endpoint provides users with authentication functionality through a custom authentication provider.
     400It supports user authentication using email and password credentials, with proper security measures including password encryption and role-based authorization.
     401
     402=== Authentication Flow
     403The login process follows these steps:
     404 1. User accesses the login page: `/login`
     405 2. User submits credentials
     406 3. System validates and authenticates the user
     407 4. User is redirected based on authentication result
     408
     409===
     410{{{
     411    @Controller
     412    @RequestMapping("/login")
     413    public class LoginController {
     414        @GetMapping
     415        public String loginPage(Model model) {
     416            model.addAttribute("display", "login");
     417            return "master";
     418        }
     419    }
     420}}}
     421===
     422
     423==== Controller Details: 
     424- **URL Mapping:** `/login` 
     425- **Method:** `GET` 
     426- **Functionality:** 
     427  - Displays the login form when accessed
     428  - Handles authentication through Spring Security configuration
     429- **View:** Uses the `master` template and dynamically embeds `login` view
     430
     431==== Authentication Provider Implementation:
     432The `CustomAuthenticationProvider` handles the core authentication logic:
     433{{{
     434    @Component
     435    public class CustomAuthenticationProvider implements AuthenticationProvider {
     436        private final AccountService accountService;
     437        private final PasswordEncoder passwordEncoder;
     438
     439        @Override
     440        public Authentication authenticate(Authentication authentication)
     441                throws AuthenticationException {
     442            String username = authentication.getName();
     443            String password = authentication.getCredentials().toString();
     444
     445            if (username.isEmpty() || password.isEmpty()) {
     446                throw new BadCredentialsException("Please fill out all fields.");
     447            }
     448
     449            try {
     450                UserDetails userDetails = accountService.findOneByPredicate(
     451                    AccountSpecification.hasEmail(username));
     452
     453                if (!passwordEncoder.matches(password, userDetails.getPassword())) {
     454                    throw new BadCredentialsException("Invalid username or password");
     455                }
     456                return new UsernamePasswordAuthenticationToken(
     457                    userDetails,
     458                    userDetails.getPassword(),
     459                    userDetails.getAuthorities()
     460                );
     461            } catch (EntityNotFoundException exc) {
     462                throw new BadCredentialsException(exc.getMessage());
     463            }
     464        }
     465    }
     466}}}
     467
     468==== Security Configuration:
     469The security rules are defined in `SecurityConfig`:
     470{{{
     471    @Configuration
     472    @EnableWebSecurity
     473    @EnableMethodSecurity
     474    public class SecurityConfig {
     475        @Bean
     476        public SecurityFilterChain securityFilterChain(HttpSecurity http)
     477                throws Exception {
     478            http
     479                .authorizeHttpRequests(
     480                    authorizeRequests ->
     481                        authorizeRequests
     482                            .requestMatchers("/", "/home", "/login", "/css/**",
     483                                "/js/**", "/images/**", "/register",
     484                                "/search-routes")
     485                            .permitAll()
     486                            .requestMatchers("/routes/company/**")
     487                                .hasAnyRole("TRANSPORT_ORGANIZER", "DRIVER")
     488                            .requestMatchers("/admin/**")
     489                                .hasRole("ADMIN")
     490                            .requestMatchers("/trips/user/**")
     491                                .hasRole("USER")
     492                            .anyRequest().authenticated()
     493                )
     494                .formLogin(login ->
     495                    login.loginPage("/login")
     496                        .permitAll()
     497                        .defaultSuccessUrl("/")
     498                        .failureUrl("/login?error")
     499                );
     500            return http.build();
     501        }
     502    }
     503}}}
     504
     505==== Role Resolution:
     506User roles are determined through the `RoleResolver` utility:
     507{{{
     508    public class RoleResolver {
     509        public static Collection<? extends GrantedAuthority> resolveRoles(Account account) {
     510            List<GrantedAuthority> authorities = new ArrayList<>();
     511
     512            if (account.getAdmin() != null) {
     513                authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
     514            }
     515            if (account.getStudent() != null) {
     516                authorities.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
     517            }
     518            if (account.getDriver() != null) {
     519                authorities.add(new SimpleGrantedAuthority("ROLE_DRIVER"));
     520            }
     521            if (account.getTransportOrganizer() != null) {
     522                authorities.add(new SimpleGrantedAuthority("ROLE_TRANSPORT_ORGANIZER"));
     523            }
     524            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
     525
     526            return authorities;
     527        }
     528    }
     529}}}
     530
     531===
     532==== Result of `/login` page
     533[[Image(login.png, 100%)]]
     534===
     535
     536==== Result of failed login attempt
     537[[Image(login-error.png, 100%)]]
     538===
     539
     540