From f0b1a817d37af8a373f837b61eb3db2a1c554fa5 Mon Sep 17 00:00:00 2001 From: lucasmoraist Date: Fri, 4 Oct 2024 08:54:28 -0300 Subject: [PATCH] feat(develop): removing security of the gateway --- .../src/main/resources/application.properties | 2 +- gateway/pom.xml | 41 ------------ .../{config/rest => }/RestClientConfig.java | 2 +- .../config/security/SecurityConfig.java | 48 -------------- .../config/security/SecurityFilter.java | 47 -------------- .../gateway/controller/UserController.java | 38 ----------- .../gateway/domain/dto/TokenDTO.java | 4 -- .../gateway/domain/entity/User.java | 42 ------------ .../gateway/domain/model/LoginRequest.java | 21 ------ .../gateway/domain/model/RegisterRequest.java | 30 --------- .../gateway/repository/UserRepository.java | 10 --- .../gateway/service/TokenService.java | 8 --- .../gateway/service/UserDetailsService.java | 8 --- .../gateway/service/UserService.java | 10 --- .../service/impl/TokenServiceImpl.java | 54 ---------------- .../service/impl/UserDetailsServiceImpl.java | 26 -------- .../gateway/service/impl/UserServiceImpl.java | 64 ------------------- .../src/main/resources/application.properties | 9 +-- 18 files changed, 3 insertions(+), 461 deletions(-) rename gateway/src/main/java/com/lucasmoraist/gateway/{config/rest => }/RestClientConfig.java (87%) delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityConfig.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityFilter.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/controller/UserController.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/domain/dto/TokenDTO.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/domain/entity/User.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/domain/model/LoginRequest.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/domain/model/RegisterRequest.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/repository/UserRepository.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/TokenService.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/UserDetailsService.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/UserService.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/impl/TokenServiceImpl.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserDetailsServiceImpl.java delete mode 100644 gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserServiceImpl.java diff --git a/comments/src/main/resources/application.properties b/comments/src/main/resources/application.properties index 282822d..74b2647 100644 --- a/comments/src/main/resources/application.properties +++ b/comments/src/main/resources/application.properties @@ -1,7 +1,7 @@ spring.profiles.active=${PROFILE:open,dev} # JPA properties -spring.datasource.url=jdbc:postgresql://localhost:5433/db_comments +spring.datasource.url=jdbc:postgresql://localhost:5433/db_comment spring.datasource.username=postgres spring.datasource.password=password spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect diff --git a/gateway/pom.xml b/gateway/pom.xml index c3e5e21..06dda7b 100644 --- a/gateway/pom.xml +++ b/gateway/pom.xml @@ -52,47 +52,6 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-test - test - - - com.auth0 - java-jwt - 4.4.0 - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.security - spring-security-test - test - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - org.postgresql - postgresql - runtime - 42.6.0 - - - org.projectlombok - lombok - true - diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/config/rest/RestClientConfig.java b/gateway/src/main/java/com/lucasmoraist/gateway/RestClientConfig.java similarity index 87% rename from gateway/src/main/java/com/lucasmoraist/gateway/config/rest/RestClientConfig.java rename to gateway/src/main/java/com/lucasmoraist/gateway/RestClientConfig.java index fcd9f0e..1c88903 100644 --- a/gateway/src/main/java/com/lucasmoraist/gateway/config/rest/RestClientConfig.java +++ b/gateway/src/main/java/com/lucasmoraist/gateway/RestClientConfig.java @@ -1,4 +1,4 @@ -package com.lucasmoraist.gateway.config.rest; +package com.lucasmoraist.gateway; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityConfig.java b/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityConfig.java deleted file mode 100644 index fd9d4d0..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.lucasmoraist.gateway.config.security; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -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.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 -public class SecurityConfig { - - @Autowired - SecurityFilter securityFilter; - - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .csrf(csrf -> csrf.disable()) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .authorizeHttpRequests(authorize -> authorize - .requestMatchers(HttpMethod.POST, "/auth/login").permitAll() - .requestMatchers(HttpMethod.POST, "/auth/register").permitAll() - .anyRequest().authenticated() - ) - .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class); - return http.build(); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Bean - public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { - return authenticationConfiguration.getAuthenticationManager(); - } - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityFilter.java b/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityFilter.java deleted file mode 100644 index d4022e6..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/config/security/SecurityFilter.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.lucasmoraist.gateway.config.security; - -import com.lucasmoraist.gateway.domain.entity.User; -import com.lucasmoraist.gateway.repository.UserRepository; -import com.lucasmoraist.gateway.service.TokenService; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -import java.io.IOException; -import java.util.Collections; - -@Component -public class SecurityFilter extends OncePerRequestFilter { - - @Autowired - private TokenService tokenService; - @Autowired - private UserRepository userRepository; - - @Override - protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException { - var token = this.recoverToken(req); - var login = tokenService.validateToken(token); - if(login != null){ - User user = userRepository.findByEmail(login).orElseThrow(() -> new RuntimeException("User Not Found")); - var authorities = Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")); - var authentication = new UsernamePasswordAuthenticationToken(user, null, authorities); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - filterChain.doFilter(req, res); - } - - private String recoverToken(HttpServletRequest request){ - var authHeader = request.getHeader("Authorization"); - if(authHeader == null) return null; - return authHeader.replace("Bearer ", ""); - } - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/controller/UserController.java b/gateway/src/main/java/com/lucasmoraist/gateway/controller/UserController.java deleted file mode 100644 index d47de99..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/controller/UserController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.lucasmoraist.gateway.controller; - -import com.lucasmoraist.gateway.domain.dto.TokenDTO; -import com.lucasmoraist.gateway.domain.model.LoginRequest; -import com.lucasmoraist.gateway.domain.model.RegisterRequest; -import com.lucasmoraist.gateway.service.UserService; -import jakarta.validation.Valid; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@Slf4j -@RestController -@RequestMapping("/auth") -public class UserController { - - @Autowired - private UserService service; - - @PostMapping("register") - public ResponseEntity register(@Valid @RequestBody RegisterRequest request) throws Exception { - this.service.register(request); - log.info("Registering"); - return ResponseEntity.ok().build(); - } - - @PostMapping("login") - public ResponseEntity login(@Valid @RequestBody LoginRequest request) throws Exception { - var response = this.service.login(request); - log.info("Logging in"); - return ResponseEntity.ok().body(response); - } - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/domain/dto/TokenDTO.java b/gateway/src/main/java/com/lucasmoraist/gateway/domain/dto/TokenDTO.java deleted file mode 100644 index 0bd9285..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/domain/dto/TokenDTO.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.lucasmoraist.gateway.domain.dto; - -public record TokenDTO(String token) { -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/domain/entity/User.java b/gateway/src/main/java/com/lucasmoraist/gateway/domain/entity/User.java deleted file mode 100644 index 01526f8..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/domain/entity/User.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.lucasmoraist.gateway.domain.entity; - -import com.lucasmoraist.gateway.domain.model.LoginRequest; -import com.lucasmoraist.gateway.domain.model.RegisterRequest; -import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -@Entity(name = "t_user") -@Table(name = "t_user") -public class User { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false, length = 80) - private String name; - - @Column(nullable = false, length = 255, unique = true) - private String email; - - @Column(nullable = false, length = 20) - private String password; - - public User(RegisterRequest request) { - this.name = request.getName(); - this.email = request.getEmail(); - this.password = request.getPassword(); - } - - public User(LoginRequest request) { - this.email = request.getEmail(); - this.password = request.getPassword(); - } - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/LoginRequest.java b/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/LoginRequest.java deleted file mode 100644 index d4b4669..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/LoginRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.lucasmoraist.gateway.domain.model; - -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class LoginRequest { - - @NotBlank - @Email - private String email; - - @NotBlank - private String password; - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/RegisterRequest.java b/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/RegisterRequest.java deleted file mode 100644 index 4feec75..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/domain/model/RegisterRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.lucasmoraist.gateway.domain.model; - -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class RegisterRequest { - - @Size(min = 3, max = 80) - private String name; - - @NotBlank - @Email(message = "Invalid email") - @Size(max = 255) - private String email; - - @NotBlank - @Size(min = 8, max = 20) - @Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).*$", - message = "Password must contain at least one uppercase letter, one lowercase letter and one digit") - private String password; - -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/repository/UserRepository.java b/gateway/src/main/java/com/lucasmoraist/gateway/repository/UserRepository.java deleted file mode 100644 index 46d537f..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/repository/UserRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.lucasmoraist.gateway.repository; - -import com.lucasmoraist.gateway.domain.entity.User; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface UserRepository extends JpaRepository { - Optional findByEmail(String email); -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/TokenService.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/TokenService.java deleted file mode 100644 index f9245a4..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/TokenService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.lucasmoraist.gateway.service; - -import com.lucasmoraist.gateway.domain.entity.User; - -public interface TokenService { - String generateToken(User user); - String validateToken(String token); -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/UserDetailsService.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/UserDetailsService.java deleted file mode 100644 index 550de21..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/UserDetailsService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.lucasmoraist.gateway.service; - -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - -public interface UserDetailsService { - UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/UserService.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/UserService.java deleted file mode 100644 index 06a5e39..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/UserService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.lucasmoraist.gateway.service; - -import com.lucasmoraist.gateway.domain.dto.TokenDTO; -import com.lucasmoraist.gateway.domain.model.LoginRequest; -import com.lucasmoraist.gateway.domain.model.RegisterRequest; - -public interface UserService { - void register(RegisterRequest request) throws Exception; - TokenDTO login(LoginRequest request) throws Exception; -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/TokenServiceImpl.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/TokenServiceImpl.java deleted file mode 100644 index 3862443..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/TokenServiceImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.lucasmoraist.gateway.service.impl; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.exceptions.JWTCreationException; -import com.auth0.jwt.exceptions.JWTVerificationException; -import com.lucasmoraist.gateway.domain.entity.User; -import com.lucasmoraist.gateway.service.TokenService; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; - -@Service -public class TokenServiceImpl implements TokenService { - - @Value("${jwt.secret}") - private String secret; - - @Override - public String generateToken(User user) { - try { - Algorithm algorithm = Algorithm.HMAC256(secret); - - return JWT.create() - .withIssuer("task-list") - .withSubject(user.getEmail()) - .withExpiresAt(this.generateExpirationDate()) - .sign(algorithm); - } catch(JWTCreationException e){ - throw new RuntimeException("Error while authentication"); - } - } - - @Override - public String validateToken(String token) { - try { - Algorithm algorithm = Algorithm.HMAC256(secret); - return JWT.require(algorithm) - .withIssuer("task-list") - .build() - .verify(token) - .getSubject(); - } catch(JWTVerificationException e) { - return null; - } - } - - private Instant generateExpirationDate(){ - return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00")); - } -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserDetailsServiceImpl.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserDetailsServiceImpl.java deleted file mode 100644 index 3772db3..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserDetailsServiceImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.lucasmoraist.gateway.service.impl; - -import com.lucasmoraist.gateway.domain.entity.User; -import com.lucasmoraist.gateway.repository.UserRepository; -import com.lucasmoraist.gateway.service.UserDetailsService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; - -@Service -public class UserDetailsServiceImpl implements UserDetailsService { - - @Autowired - private UserRepository repository; - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = this.repository.findByEmail(username) - .orElseThrow(() -> new UsernameNotFoundException("User Not Found")); - - return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), new ArrayList<>()); - } -} diff --git a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserServiceImpl.java b/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserServiceImpl.java deleted file mode 100644 index e111571..0000000 --- a/gateway/src/main/java/com/lucasmoraist/gateway/service/impl/UserServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.lucasmoraist.gateway.service.impl; - -import com.lucasmoraist.gateway.domain.dto.TokenDTO; -import com.lucasmoraist.gateway.domain.entity.User; -import com.lucasmoraist.gateway.domain.model.LoginRequest; -import com.lucasmoraist.gateway.domain.model.RegisterRequest; -import com.lucasmoraist.gateway.repository.UserRepository; -import com.lucasmoraist.gateway.service.TokenService; -import com.lucasmoraist.gateway.service.UserService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; - -import java.util.Optional; - -@Slf4j -@Service -@RequiredArgsConstructor -public class UserServiceImpl implements UserService { - - private final UserRepository repository; - private final TokenService tokenService; - private final PasswordEncoder passwordEncoder; - - @Override - public void register(RegisterRequest request) throws Exception { - log.info("Attempting to register user with email: {}", request.getEmail()); - - Optional optionalUser = this.repository.findByEmail(request.getEmail()); - if (optionalUser.isPresent()) { - log.error("Registration failed: email already in use: {}", request.getEmail()); - throw new Exception("Email already in use"); - } - - User newUser = new User(request); - newUser.setPassword(this.passwordEncoder.encode(request.getPassword())); - - this.repository.save(newUser); - - log.info("Registration successful for email: {}", request.getEmail()); - } - - @Override - public TokenDTO login(LoginRequest request) throws Exception { - log.info("Attempting to authenticate user with email: {}", request.getEmail()); - - User user = this.repository.findByEmail(request.getEmail()) - .orElseThrow(() -> { - log.error("Authentication failed: email not found for email: {}", request.getEmail()); - return new Exception("Email not found"); - }); - - if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { - log.error("Authentication failed: incorrect password for email: {}", request.getEmail()); - throw new Exception("Incorrect password"); - } - - String token = this.tokenService.generateToken(user); - - log.info("Authentication successful for email: {}", request.getEmail()); - return new TokenDTO(token); - } -} diff --git a/gateway/src/main/resources/application.properties b/gateway/src/main/resources/application.properties index 8f0d68b..c32df79 100644 --- a/gateway/src/main/resources/application.properties +++ b/gateway/src/main/resources/application.properties @@ -1,8 +1,3 @@ -spring.datasource.url=jdbc:postgresql://localhost:5434/db_user -spring.datasource.username=postgres -spring.datasource.password=password -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect - spring.application.name=gateway server.port=8082 @@ -10,6 +5,4 @@ eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ spring.cloud.gateway.discovery.locator.enabled=true spring.cloud.gateway.discovery.locator.lower-case-service-id=true spring.main.web-application-type=reactive -spring.main.allow-bean-definition-overriding=true - -jwt.secret=secret \ No newline at end of file +spring.main.allow-bean-definition-overriding=true \ No newline at end of file