Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,37 @@
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- JAXB API -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
<!-- -->

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
<plugins>
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/health/app/AppApplication.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.health.app;

import com.health.app.util.JwtUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AppApplication {

public static void main(String[] args) {
System.out.println( new JwtUtil().generateToken("admin"));
SpringApplication.run(AppApplication.class, args);
}

Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/health/app/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.health.app.config;

import com.health.app.controller.filter.JwtFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

private final JwtFilter jwtFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable) // Desativar CSRF
.authorizeHttpRequests(auth -> auth
.requestMatchers("/user").permitAll() // Endpoints públicos
.anyRequest().authenticated() // Todos os outros endpoints são protegidos
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
}
}
1 change: 1 addition & 0 deletions src/main/java/com/health/app/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.health.app.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.health.app.controller.filter.JwtFilter;
import com.health.app.integrations.openai.OpenAiClient;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/health/app/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.RequiredArgsConstructor;
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.RestController;

@RestController
Expand All @@ -14,7 +15,7 @@ public class UserController {
private final UserService userService;

@PostMapping("/user")
public ResponseEntity<String> save(CreateUserRequestDTO requestDTO) {
public ResponseEntity<String> save(@RequestBody CreateUserRequestDTO requestDTO) {
userService.save(requestDTO);
return ResponseEntity.ok("User created");
}
Expand Down
81 changes: 81 additions & 0 deletions src/main/java/com/health/app/controller/filter/JwtFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.health.app.controller.filter;

import com.health.app.entity.User;
import com.health.app.repository.UserRepository;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
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.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

import java.io.IOException;

@Component
@RequiredArgsConstructor
public class JwtFilter extends GenericFilterBean {

private final String secret = "secreto"; // Sua chave secreta
private final String prefix = "Bearer "; // Prefixo do token JWT
private final UserRepository userRepository;

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;

if (((HttpServletRequest) request).getRequestURI().equals("/user")) {
filterChain.doFilter(request, response);
return;
}

String authHeader = httpRequest.getHeader("Authorization");

if (authHeader == null || !authHeader.startsWith(prefix)) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token JWT ausente ou malformado");
return;
}

String token = authHeader.substring(prefix.length()); // Remova o prefixo "Bearer "

try {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
httpRequest.setAttribute("claims", claims);

String username = claims.getSubject();
User user = userRepository.findByEmail(username);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(user, null);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(authToken);



} catch (Exception e) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token JWT inválido ou expirado");
return;
}

filterChain.doFilter(request, response);
}


@Override
public void destroy() {
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/health/app/repository/UserRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
public interface UserRepository extends JpaRepository<User, Long> {

User save(User user);

User findByEmail(String email);
}
3 changes: 2 additions & 1 deletion src/main/java/com/health/app/services/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.health.app.dto.CreateUserRequestDTO;
import com.health.app.entity.User;
import com.health.app.repository.UserRepository;
import com.health.app.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -19,7 +20,7 @@ public User save(CreateUserRequestDTO createUserRequestDTO) {
user.setName(createUserRequestDTO.getName());
user.setEmail(createUserRequestDTO.getEmail());
user.setPassword(createUserRequestDTO.getPassword());

System.out.println(new JwtUtil().generateToken(user.getEmail()));
userRepository.save(user);
return user;
}
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/health/app/util/JwtUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.health.app.util;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;


public class JwtUtil {
private String secret = "secreto";

public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1 dia de expiração
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}

public Boolean validateToken(String token, String username) {
final String extractedUsername = extractUsername(token);
return (extractedUsername.equals(username) && !isTokenExpired(token));
}

private String extractUsername(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}

private Boolean isTokenExpired(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getExpiration().before(new Date());
}
}