Token's returns worked

This commit is contained in:
rayankonecny 2025-12-17 00:51:56 +00:00
parent ef8c2e8ca0
commit dbf9d46679
11 changed files with 103 additions and 66 deletions

View file

@ -23,10 +23,6 @@ configurations {
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
compileOnly 'org.projectlombok:lombok'
@ -40,3 +36,7 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}
tasks.withType(org.springframework.boot.gradle.tasks.aot.ProcessAot).configureEach {
enabled = false
}

View file

@ -3,46 +3,35 @@ package br.com.rayankonecny.authserviceapi.configs;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
// AUTH
.requestMatchers("/auth/login").permitAll()
http.authorizeHttpRequests(auth -> auth.requestMatchers("/auth/login", "/v3/api-docs/**", "/swagger-ui/**",
"/swagger-ui.html", "/swagger-ui/index.html").permitAll().anyRequest().authenticated())
// SWAGGER / OPENAPI
.requestMatchers(
"/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/swagger-ui/index.html"
).permitAll()
// API pura sem Basic
.httpBasic(httpBasic -> httpBasic.disable())
// TODO o resto protegido
.anyRequest().authenticated()
)
// Stateless (JWT)
.csrf(csrf -> csrf.disable())
// API pura sem Basic
.httpBasic(httpBasic -> httpBasic.disable())
// Stateless (JWT)
.csrf(csrf -> csrf.disable())
// Sem sessão
.sessionManagement(session ->
session.sessionCreationPolicy(
org.springframework.security.config.http.SessionCreationPolicy.STATELESS
)
);
// Sem sessão
.sessionManagement(session -> session.sessionCreationPolicy(
org.springframework.security.config.http.SessionCreationPolicy.STATELESS));
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View file

@ -7,9 +7,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import br.com.rayankonecny.hdcommoslib.models.exceptions.StandardError;
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
import org.springframework.web.bind.annotation.RequestBody;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.media.Schema;
@ -17,7 +17,6 @@ import jakarta.validation.Valid;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RequestMapping("/auth")
public interface AuthController {
@ -27,9 +26,10 @@ public interface AuthController {
@ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
@ApiResponse(responseCode = "401", description = "Bad credentials", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
@ApiResponse(responseCode = "404", description = "Username not found", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
})
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))), })
@PostMapping("/login")
ResponseEntity<AuthenticationResponse> authenticate(@Valid @RequestBody final AuthenticateRequest requests) throws Exception;
ResponseEntity<AuthenticationResponse> authenticate(@RequestBody
@Valid
final AuthenticateRequest requests) throws Exception;
}

View file

@ -1,27 +1,26 @@
package br.com.rayankonecny.authserviceapi.controllers.impl;
import org.springframework.http.ResponseEntity;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.web.bind.annotation.RestController;
import br.com.rayankonecny.authserviceapi.controllers.AuthController;
import br.com.rayankonecny.authserviceapi.security.JWTAuthenticationImpl;
import br.com.rayankonecny.authserviceapi.utils.JWTUtils;
import br.com.rayankonecny.authserviceapi.services.AuthService;
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
public class AuthControllerImpl implements AuthController {
private final JWTUtils jwtUtils;
private final AuthenticationConfiguration authenticationConfiguration;
private final AuthService authService;
@Override
public ResponseEntity<AuthenticationResponse> authenticate(final AuthenticateRequest requests) throws Exception {
return ResponseEntity.ok().body(
new JWTAuthenticationImpl(jwtUtils, authenticationConfiguration.getAuthenticationManager()).authentication(requests));
public ResponseEntity<AuthenticationResponse> authenticate(@Valid
AuthenticateRequest request) {
return ResponseEntity.ok(authService.authenticate(request));
}
}

View file

@ -2,15 +2,21 @@ package br.com.rayankonecny.authserviceapi.models;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Set;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import br.com.rayankonecny.hdcommoslib.models.enums.ProfileEnum;
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "user")
public class User {
@Id
private String id;
private String name;
private String email;

View file

@ -6,11 +6,13 @@ import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
@AllArgsConstructor
public class UserDetailsDTO implements UserDetails {
@Serial
@ -18,13 +20,13 @@ public class UserDetailsDTO implements UserDetails {
private String id;
private String name;
private String username;
private String email;
private String password;
private Collection<? extends GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
public String getUsername() {
return this.email; // 🔥 FUNDAMENTAL
}
@Override
@ -33,15 +35,10 @@ public class UserDetailsDTO implements UserDetails {
}
@Override
public String getUsername() {
return this.username;
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
public String getName() {
return this.name;
}
@Override
public boolean isAccountNonExpired() {
return true;
@ -52,4 +49,13 @@ public class UserDetailsDTO implements UserDetails {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

View file

@ -0,0 +1,33 @@
package br.com.rayankonecny.authserviceapi.services;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import br.com.rayankonecny.authserviceapi.utils.JWTUtils;
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class AuthService {
private final UserDetailsServiceImpl userDetailsService;
private final PasswordEncoder passwordEncoder;
private final JWTUtils jwtUtils;
public AuthenticationResponse authenticate(AuthenticateRequest request) {
var user = userDetailsService.loadUserByUsername(request.email());
if (!passwordEncoder.matches(request.password(), user.getPassword())) {
throw new BadCredentialsException("Invalid credentials");
}
String token = jwtUtils.generateToken(user);
return new AuthenticationResponse(token,user.getUsername());
}
}

View file

@ -0,0 +1,5 @@
package br.com.rayankonecny.authserviceapi.services;
public class BadCredentialsExceptionion {
}

View file

@ -1,10 +1,8 @@
package br.com.rayankonecny.authserviceapi.services;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@ -20,7 +18,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository repository;
@Override
public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
public UserDetailsDTO loadUserByUsername(final String email) throws UsernameNotFoundException {
final var entity = repository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + email));
@ -28,7 +26,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
return UserDetailsDTO.builder()
.id(entity.getId())
.name(entity.getName())
.username(entity.getEmail())
.email(entity.getEmail())
.password(entity.getPassword())
.authorities(entity.getProfiles().stream().map(x -> new SimpleGrantedAuthority(x.getDescription())).collect(Collectors.toSet()))
.build();

View file

@ -19,12 +19,12 @@ public class JWTUtils {
@Value("${jwt.expiration}")
private Long expiration;
public String generateToken(final UserDetailsDTO dto) {
public String generateToken(final UserDetailsDTO user) {
return Jwts.builder()
.claim("id", dto.getId())
.claim("name", dto.getName())
.claim("authorities", dto.getAuthorities())
.setSubject(dto.getUsername())
.claim("id", user.getId())
.claim("name", user.getName())
.claim("authorities", user.getAuthorities())
.setSubject(user.getUsername())
.signWith(SignatureAlgorithm.HS512, secret.getBytes())
.setExpiration(new Date(System.currentTimeMillis()+ expiration))
.compact();

View file

@ -5,6 +5,7 @@ spring:
mongodb:
uri: mongodb://175.15.15.6:27017/olympdb
auto-index-creation: true
aot:
enabled: false
jwt.secret: "IHf3Yua/byvtA+iIcGWmkrLvpKEXTb5ClkXaZ0VDmYbr/6b1otCs38x68bidvZLAOB7anUtVQlCid6YDULO5XA=="
jwt.expiration: 120000