public record DatosAutenticacionUsuario(
String login,
String clave
) {
}
public record DatosJWTToken(String token) {
}
@Service
public class TokenService {
@Value("${api.security.secret}")
private String secret;
public String generarToken(Usuario usuario) {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
.withIssuer("api pacientes")
.withSubject(usuario.getLogin())
.sign(algorithm);
}
public String getSubject(String tokenJWT) {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.require(algorithm)
.withIssuer("api pacientes")
.build()
.verify(tokenJWT)
.getSubject();
}
}
@RestController
@RequestMapping("/login")
public class AuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenService tokenService;
@PostMapping
public ResponseEntity<DatosJWTToken> autenticarUsuario(
@RequestBody @Valid DatosAutenticacionUsuario datos) {
var authToken = new UsernamePasswordAuthenticationToken(
datos.login(),
datos.clave()
);
var autenticacion = authenticationManager.authenticate(authToken);
var tokenJWT = tokenService.generarToken(
(Usuario) autenticacion.getPrincipal()
);
return ResponseEntity.ok(new DatosJWTToken(tokenJWT));
}
}
@Entity
@Table(name = "usuarios")
public class Usuario implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String clave;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of();
}
@Override
public String getPassword() {
return clave;
}
@Override
public String getUsername() {
return login;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
public interface UsuarioRepository extends JpaRepository<Usuario, Long> {
UserDetails findByLogin(String login);
}
@Service
public class AutenticacionService implements UserDetailsService {
@Autowired
private UsuarioRepository repository;
@Override
public UserDetails loadUserByUsername(String username) {
return repository.findByLogin(username);
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfigurations {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(csrf -> csrf.disable())
.sessionManagement(sm ->
sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(req -> {
req.requestMatchers(HttpMethod.POST, "/login").permitAll();
req.anyRequest().authenticated();
})
.build();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}