From 1851e3fe8e327d2bd6ddd573276f71a357316b37 Mon Sep 17 00:00:00 2001 From: vanderleik Date: Wed, 17 Apr 2024 15:02:57 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20VIN-451=20-=20adicionando=20filtro=20na?= =?UTF-8?q?s=20configs=20de=20seguran=C3=A7a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/cadastro/UserService.java | 3 ++ .../cadastro/impl/UserServiceImpl.java | 15 ++++++ .../bff/client/cadastro/UserClient.java | 7 ++- .../controllers/cadastro/UserController.java | 7 +++ .../inputs/cadastro/AuthenticationDTO.java | 13 +++++ .../outputs/cadastro/LoginResponseDTO.java | 16 +++++++ .../bff/utils/MessagesConstants.java | 1 + .../security/SecurityConfigurations.java | 10 +++- .../security/SecurityFilter.java | 48 +++++++++++++++++++ .../controllers/AuthenticationController.java | 9 +++- .../dtos/outputs/LoginResponseDTO.java | 12 +++++ 11 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/inputs/cadastro/AuthenticationDTO.java create mode 100644 bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/outputs/cadastro/LoginResponseDTO.java create mode 100644 cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityFilter.java create mode 100644 cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/dtos/outputs/LoginResponseDTO.java diff --git a/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/UserService.java b/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/UserService.java index f3cf3caa..ccfd95b5 100644 --- a/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/UserService.java +++ b/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/UserService.java @@ -1,6 +1,8 @@ package com.vinhonotas.bff.application.services.cadastro; +import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.AuthenticationDTO; import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.UserInputDTO; +import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.LoginResponseDTO; import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.UserOutputDTO; import java.util.List; @@ -13,5 +15,6 @@ public interface UserService { UserOutputDTO getUserByName(String name); UserOutputDTO updateUser(String id, UserInputDTO userInputDTO); void deleteUser(String id); + LoginResponseDTO login(AuthenticationDTO data); } diff --git a/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/impl/UserServiceImpl.java b/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/impl/UserServiceImpl.java index cd581a08..32ba6db6 100644 --- a/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/impl/UserServiceImpl.java +++ b/bff/src/main/java/com/vinhonotas/bff/application/services/cadastro/impl/UserServiceImpl.java @@ -4,7 +4,9 @@ import com.vinhonotas.bff.application.services.exceptions.BadRequestException; import com.vinhonotas.bff.application.services.exceptions.NotFoundException; import com.vinhonotas.bff.client.cadastro.UserClient; +import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.AuthenticationDTO; import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.UserInputDTO; +import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.LoginResponseDTO; import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.UserOutputDTO; import com.vinhonotas.bff.utils.MessagesConstants; import lombok.RequiredArgsConstructor; @@ -87,4 +89,17 @@ public void deleteUser(String id) { } } + @Override + public LoginResponseDTO login(AuthenticationDTO data) { + log.info("login :: Realizando login"); + try { + LoginResponseDTO login = userClient.login(data); + log.info("login :: Login realizado com sucesso"); + return login; + } catch (Exception e) { + log.error("login :: Ocorreu um erro ao realizar o login: {} ", MessagesConstants.ERROR_WHEN_LOGIN, e); + throw new BadRequestException(MessagesConstants.ERROR_WHEN_LOGIN); + } + } + } diff --git a/bff/src/main/java/com/vinhonotas/bff/client/cadastro/UserClient.java b/bff/src/main/java/com/vinhonotas/bff/client/cadastro/UserClient.java index 424f7c0e..fefee76f 100644 --- a/bff/src/main/java/com/vinhonotas/bff/client/cadastro/UserClient.java +++ b/bff/src/main/java/com/vinhonotas/bff/client/cadastro/UserClient.java @@ -1,7 +1,9 @@ package com.vinhonotas.bff.client.cadastro; import com.vinhonotas.bff.configuration.FeignConfig; +import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.AuthenticationDTO; import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.UserInputDTO; +import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.LoginResponseDTO; import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.UserOutputDTO; import jakarta.validation.Valid; import org.springframework.cloud.openfeign.FeignClient; @@ -12,7 +14,7 @@ @FeignClient(name = "user", url = "${cadastro-api.url}", configuration = FeignConfig.class) public interface UserClient { - @PostMapping("/users") + @PostMapping("/auth/register") UserOutputDTO createUser(@Valid @RequestBody UserInputDTO userInputDTO); @GetMapping("/users") @@ -30,4 +32,7 @@ public interface UserClient { @DeleteMapping("/users/{id}") Void deleteUser(@PathVariable("id") String id); + @PostMapping("/auth/login") + LoginResponseDTO login(@RequestBody @Valid AuthenticationDTO data); + } diff --git a/bff/src/main/java/com/vinhonotas/bff/interfaces/controllers/cadastro/UserController.java b/bff/src/main/java/com/vinhonotas/bff/interfaces/controllers/cadastro/UserController.java index 72126dc0..f8f627b4 100644 --- a/bff/src/main/java/com/vinhonotas/bff/interfaces/controllers/cadastro/UserController.java +++ b/bff/src/main/java/com/vinhonotas/bff/interfaces/controllers/cadastro/UserController.java @@ -1,7 +1,9 @@ package com.vinhonotas.bff.interfaces.controllers.cadastro; import com.vinhonotas.bff.application.services.cadastro.UserService; +import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.AuthenticationDTO; import com.vinhonotas.bff.interfaces.dtos.inputs.cadastro.UserInputDTO; +import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.LoginResponseDTO; import com.vinhonotas.bff.interfaces.dtos.outputs.cadastro.UserOutputDTO; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -49,4 +51,9 @@ public ResponseEntity deleteUser(@PathVariable("id") String id) { return ResponseEntity.noContent().build(); } + @PostMapping("/login") + public ResponseEntity login(@Valid @RequestBody AuthenticationDTO data) { + return ResponseEntity.ok(userService.login(data)); + } + } diff --git a/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/inputs/cadastro/AuthenticationDTO.java b/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/inputs/cadastro/AuthenticationDTO.java new file mode 100644 index 00000000..e2203bfe --- /dev/null +++ b/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/inputs/cadastro/AuthenticationDTO.java @@ -0,0 +1,13 @@ +package com.vinhonotas.bff.interfaces.dtos.inputs.cadastro; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class AuthenticationDTO { + + private String email; + private String password; + +} diff --git a/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/outputs/cadastro/LoginResponseDTO.java b/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/outputs/cadastro/LoginResponseDTO.java new file mode 100644 index 00000000..b35f2860 --- /dev/null +++ b/bff/src/main/java/com/vinhonotas/bff/interfaces/dtos/outputs/cadastro/LoginResponseDTO.java @@ -0,0 +1,16 @@ +package com.vinhonotas.bff.interfaces.dtos.outputs.cadastro; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LoginResponseDTO { + + private String token; + +} diff --git a/bff/src/main/java/com/vinhonotas/bff/utils/MessagesConstants.java b/bff/src/main/java/com/vinhonotas/bff/utils/MessagesConstants.java index 6613a7c2..594e18d4 100644 --- a/bff/src/main/java/com/vinhonotas/bff/utils/MessagesConstants.java +++ b/bff/src/main/java/com/vinhonotas/bff/utils/MessagesConstants.java @@ -8,6 +8,7 @@ public class MessagesConstants { public static final String ERROR_WHEN_UPDATING = "Erro ao atualizar registro"; public static final String ERROR_WHEN_SAVING = "Erro ao salvar registro"; public static final String BAD_REQUEST = "Requisição inválida, verifique os campos informados"; + public static final String ERROR_WHEN_LOGIN = "Erro ao realizar login"; private MessagesConstants() { } diff --git a/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityConfigurations.java b/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityConfigurations.java index cd7493fc..a814e625 100644 --- a/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityConfigurations.java +++ b/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityConfigurations.java @@ -1,5 +1,6 @@ package com.vinhonotas.cadastro.configuration.security; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; @@ -7,25 +8,32 @@ import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity +@RequiredArgsConstructor public class SecurityConfigurations { + private final SecurityFilter securityFilter; + @Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity - .csrf(csrf -> csrf.disable()) + .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(authorize -> authorize .requestMatchers(HttpMethod.POST, "/api/v1/auth/login").permitAll() .requestMatchers(HttpMethod.POST, "/api/v1/auth/register").permitAll() .requestMatchers(HttpMethod.POST, "/api/v1/persons").permitAll() + .anyRequest().authenticated() ) + .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class) .build(); } diff --git a/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityFilter.java b/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityFilter.java new file mode 100644 index 00000000..86db9290 --- /dev/null +++ b/cadastro/src/main/java/com/vinhonotas/cadastro/configuration/security/SecurityFilter.java @@ -0,0 +1,48 @@ +package com.vinhonotas.cadastro.configuration.security; + +import com.vinhonotas.cadastro.application.services.TokenService; +import com.vinhonotas.cadastro.infrastructure.UserRepository; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.Objects; + +@Component +@RequiredArgsConstructor +public class SecurityFilter extends OncePerRequestFilter { + + private final TokenService tokenService; + private final UserRepository userRepository; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + String token = recoverToken(request); + if (Objects.nonNull(token)) { + String login = tokenService.validateToken(token); + UserDetails user = userRepository.findByEmail(login); + + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + filterChain.doFilter(request, response); + } + + private String recoverToken(HttpServletRequest request) { + String authHeader = request.getHeader("Authorization"); + if (Objects.isNull(authHeader)) { + return null; + } + return authHeader.replace("Bearer ", ""); + } + +} diff --git a/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/controllers/AuthenticationController.java b/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/controllers/AuthenticationController.java index 99c1bafa..6d825663 100644 --- a/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/controllers/AuthenticationController.java +++ b/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/controllers/AuthenticationController.java @@ -1,12 +1,14 @@ package com.vinhonotas.cadastro.interfaces.controllers; import com.vinhonotas.cadastro.application.services.PersonService; +import com.vinhonotas.cadastro.application.services.TokenService; import com.vinhonotas.cadastro.domain.entities.PersonEntity; import com.vinhonotas.cadastro.domain.entities.UserEntity; import com.vinhonotas.cadastro.domain.enums.EnumProfile; import com.vinhonotas.cadastro.infrastructure.UserRepository; import com.vinhonotas.cadastro.interfaces.dtos.inputs.AuthenticationDTO; import com.vinhonotas.cadastro.interfaces.dtos.inputs.UserInputDTO; +import com.vinhonotas.cadastro.interfaces.dtos.outputs.LoginResponseDTO; import com.vinhonotas.cadastro.utils.EnumConverter; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -34,15 +36,18 @@ public class AuthenticationController{ private final AuthenticationManager authenticationManager; private final UserRepository repository; private final PersonService personService; + private final TokenService tokenService; @PostMapping("/login") - public ResponseEntity login(@RequestBody @Valid AuthenticationDTO data){ + public ResponseEntity login(@RequestBody @Valid AuthenticationDTO data){ log.info("login :: Login request received {}: ", data); var usernamePassword = new UsernamePasswordAuthenticationToken(data.getEmail(), data.getPassword()); log.info("login :: usernamePassword {}: ",usernamePassword); var auth = authenticationManager.authenticate(usernamePassword); - return ResponseEntity.ok().build(); + String token = tokenService.generateToken((UserEntity) auth.getPrincipal()); + LoginResponseDTO login = LoginResponseDTO.builder().token(token).build(); + return ResponseEntity.ok(login); } @PostMapping("/register") diff --git a/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/dtos/outputs/LoginResponseDTO.java b/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/dtos/outputs/LoginResponseDTO.java new file mode 100644 index 00000000..7a5db3d3 --- /dev/null +++ b/cadastro/src/main/java/com/vinhonotas/cadastro/interfaces/dtos/outputs/LoginResponseDTO.java @@ -0,0 +1,12 @@ +package com.vinhonotas.cadastro.interfaces.dtos.outputs; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class LoginResponseDTO { + + private String token; + +}