Creando un loing mas adecuado y metodo de creacion de un usuario. Tambien consite de creacion de entidad rol para completar las entidades de usuario y autoridad para crear las relaciones necesarias para hacer un lo in. Tambien ajustamos la encriptacion de contraseña y creamis repositorios y servicios neceasrios.Y para la creacion comprobamos si estan vacios o no, ademas creamos queries necasarias para que funciona todo

master
vicsash 4 months ago
parent 665a45d106
commit c1ab8f5a41

@ -0,0 +1,37 @@
package com.example.proyectofinal.component;
import com.example.proyectofinal.models.login.Usuario;
import com.example.proyectofinal.servicios.user.UsuarioService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
@Component
public class CustomAuth implements AuthenticationProvider{
@Autowired
private UsuarioService usuarioService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String nombreLogIn = authentication.getName();
String password = authentication.getCredentials().toString();
Usuario usuario = usuarioService.login(nombreLogIn, password);
if (usuario != null) {
return new UsernamePasswordAuthenticationToken(nombreLogIn, password, new ArrayList<>());
} else {
throw new BadCredentialsException("External system authentication failed");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}

@ -1,8 +1,7 @@
package com.example.proyectofinal.configuration.seguridad;
package com.example.proyectofinal.configuration;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

@ -0,0 +1,14 @@
package com.example.proyectofinal.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEcodingConf {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

@ -0,0 +1,93 @@
package com.example.proyectofinal.configuration;
import com.example.proyectofinal.component.CustomAuth;
import com.example.proyectofinal.servicios.user.UsuarioService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private UsuarioService usuarioService;
@Autowired
private CustomAuth customAuth;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuth);
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.sessionManagement(sessionManagement -> sessionManagement
.invalidSessionUrl("/logout") // Redirect to /logout when session is invalid
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.sessionFixation().migrateSession()
.maximumSessions(1).expiredUrl("/logout")) // Redirect to /logout when session expires
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(formLogin -> formLogin
.successHandler(customAuthenticacionHandler())
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.addLogoutHandler((request, response, authentication) -> {
if (authentication != null) {
String nombreLogIn = authentication.getName();
usuarioService.logout(nombreLogIn);
}
})
);
return http.build();
}
@Bean
public CustomAuthenticacionHandler customAuthenticacionHandler() {
return new CustomAuthenticacionHandler();
}
private void initializeAutoridadAndRolTables() {
// Check if the autoridad table is empty
Integer autoridadCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM autoridad", Integer.class);
if (autoridadCount != null && autoridadCount == 0) {
// If the table is empty, insert 'READ', 'WRITE', and 'DELETE'
jdbcTemplate.execute("INSERT INTO autoridad (nombre) VALUES ('READ'), ('WRITE'), ('DELETE')");
}
// Check if the rol table is empty
Integer rolCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rol", Integer.class);
if (rolCount != null && rolCount == 0) {
// If the table is empty, insert roles and establish many-to-many relationship with autoridad
jdbcTemplate.execute("INSERT INTO rol (nombre) VALUES ('ADMIN'), ('USER')");
}
// Check if the rol_autoridad table is empty
Integer rolAutoridadCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rol_autoridad", Integer.class);
if (rolAutoridadCount != null && rolAutoridadCount == 0) {
// If the table is empty, establish many-to-many relationship between roles and autoridades
// Manually insert authorities for 'ADM' role
jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 1)"); // 'ADM' - 'READ'
jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 2)"); // 'ADM' - 'WRITE'
jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (1, 3)"); // 'ADM' - 'DELETE'
// Manually insert authorities for 'ALU' role
jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (2, 1)"); // 'ALU' - 'READ'
jdbcTemplate.update("INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (2, 2)"); // 'ALU' - 'EDIT'
}
}
}

@ -1,47 +0,0 @@
package com.example.proyectofinal.configuration.seguridad;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(formLogin -> formLogin
.successHandler(customAuthenticacionHandler())
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
var userDetailsService= new InMemoryUserDetailsManager();
UserDetails user1 = User.builder()
.username("user")
.password(this.passwordEncoder().encode("1234"))
.authorities("read","write","delete")
.build();
userDetailsService.createUser(user1);
return userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public CustomAuthenticacionHandler customAuthenticacionHandler() {
return new CustomAuthenticacionHandler();
}
}

@ -5,6 +5,7 @@ import com.example.proyectofinal.models.empresas.*;
import com.example.proyectofinal.repositories.empresas.*;
import com.example.proyectofinal.servicios.*;
import com.example.proyectofinal.interfaces.IPagination;
import org.springframework.context.annotation.Role;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;

@ -0,0 +1,32 @@
package com.example.proyectofinal.controllers;
import com.example.proyectofinal.servicios.user.UsuarioService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LogOutController {
@Autowired
private UsuarioService usuarioService;
private static final Logger logger = LoggerFactory.getLogger(LogOutController.class);
@RequestMapping("/logout")
public String logout(HttpServletRequest request) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
String nombreLogIn = auth.getName();
logger.info("Logging out user: " + nombreLogIn);
usuarioService.logout(nombreLogIn);
new SecurityContextLogoutHandler().logout(request, null, null);
}
return "redirect:/login?logout";
}
}

@ -0,0 +1,26 @@
package com.example.proyectofinal.models.login;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name = "autoridad")
public class Autoridad {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 70)
private String nombre;
@ManyToMany(mappedBy = "autoridades",fetch = FetchType.EAGER)
private Set<Rol> roles;
}

@ -1,4 +0,0 @@
package com.example.proyectofinal.models.login;
public class Autoridades {
}

@ -0,0 +1,31 @@
package com.example.proyectofinal.models.login;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import java.util.Set;
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name = "rol")
public class Rol {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombre;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "rol_autoridad",
joinColumns = @JoinColumn(name = "fk_rol", referencedColumnName = "id") ,
inverseJoinColumns = @JoinColumn(name = "fk_autoridad", referencedColumnName = "id"))
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Autoridad>autoridades;
}

@ -1,4 +1,40 @@
package com.example.proyectofinal.models.login;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "usuario")
public class Usuario {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 250)
private String nombreUsuario;
@Column(length = 70)
private String nombreLogIn;
@Column(length = 100)
private String email;
@Column(length = 60)
private String password;
private boolean logedIn;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinColumn(name = "fk_rol", referencedColumnName = "id")
@OnDelete(action = OnDeleteAction.CASCADE)
private Rol rol;
}

@ -85,9 +85,9 @@ public interface OfertaRepository extends JpaRepository<Oferta, Long> {
@Query("SELECT o FROM Oferta o WHERE o.fecha > :query")
Collection<Oferta> ofertasByFechaDespuesCust(@Param("query") Date query);
@Query(value = "SELECT o FROM Oferta o WHERE YEAR(o.fecha) = :query", nativeQuery = true)
Collection<Oferta> ofertasByAnoCust(@Param("query") int query);
@Query("SELECT o FROM Oferta o JOIN o.skills s WHERE s.nombre LIKE %:query%")
Collection<Oferta> ofertasBySkillCust(@Param("query") String query);
@Query(value = "SELECT * FROM ofertas o WHERE YEAR(o.fecha) = YEAR(:dateQuery)", nativeQuery = true)
Collection<? extends Oferta> ofertasByFechaAnyoCust(Date dateQuery);
}

@ -1,7 +1,17 @@
package com.example.proyectofinal.repositories.login;
import com.example.proyectofinal.models.login.Autoridades;
import com.example.proyectofinal.models.login.Autoridad;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface AutoridadesRepository /*extends JpaRepository<Autoridades, Long> */{
}
import java.util.Collection;
public interface AutoridadesRepository extends JpaRepository<Autoridad, Long> {
@Query("SELECT a FROM Autoridad a WHERE a.nombre = ?1")
Autoridad findByNombre(String read);
@Query(value = "SELECT COUNT(a.id) FROM autoridad a JOIN rol_autoridad ra ON a.id = ra.fk_autoridad WHERE ra.fk_rol = ?1", nativeQuery = true)
int countAutoridadesByRolId(Long rolId);
}

@ -0,0 +1,21 @@
package com.example.proyectofinal.repositories.login;
import com.example.proyectofinal.models.login.Autoridad;
import com.example.proyectofinal.models.login.Rol;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.ArrayList;
import java.util.Optional;
public interface RolRepository extends JpaRepository<Rol, Long> {
@Query("SELECT r FROM Rol r WHERE r.nombre = ?1")
Rol findByName(String name);
@Query("SELECT r FROM Rol r WHERE r.id = ?1")
Rol findRolById(Long rolId);
@Query(value = "SELECT a.* FROM autoridad a JOIN rol_autoridad ra ON a.id = ra.fk_autoridad WHERE ra.fk_rol = ?1", nativeQuery = true)
ArrayList<Autoridad> findAutoridadesByRolId(Long rolId);
}

@ -1,7 +1,23 @@
package com.example.proyectofinal.repositories.login;
import org.apache.catalina.User;
import com.example.proyectofinal.models.login.Usuario;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface UserRepository /*extends JpaRepository<User, Long> */{
import java.util.Optional;
public interface UserRepository extends JpaRepository<Usuario, Long>{
@Query("SELECT u FROM Usuario u WHERE u.nombreLogIn = ?1")
Optional<Usuario> findByNombreUsuario(String nombreLogIn);
@Modifying
@Query("UPDATE Usuario u SET u.logedIn = true WHERE u.id = ?1")
void updateLogedIn(Long id);
@Modifying
@Query("UPDATE Usuario u SET u.logedIn = false WHERE u.id = ?1")
void resetLogedIn(Long id);
}

@ -176,6 +176,28 @@ public class OfertaService implements IOferta {
listEmpPrime.addAll(ofertaRepository.ofertasByEmpresaCust(query));
} else if (secondaryOption.equals("Skill")) {
listEmpPrime.addAll(ofertaRepository.ofertasBySkillCust(query));
}else if(secondaryOption.equals("Fecha antes")){
try {
Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query);
listEmpPrime.addAll(ofertaRepository.ofertasByFechaAntesCust(dateQuery));
} catch (ParseException e) {
e.printStackTrace();
}
}else if(secondaryOption.equals("Fecha despues")){
try {
Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query);
listEmpPrime.addAll(ofertaRepository.ofertasByFechaDespuesCust(dateQuery));
} catch (ParseException e) {
e.printStackTrace();
}
}else if(secondaryOption.equals("Año")){
try {
Date dateQuery = new SimpleDateFormat("yyyy-MM-dd").parse(query);
listEmpPrime.addAll(ofertaRepository.ofertasByFechaAnyoCust(dateQuery));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,24 @@
package com.example.proyectofinal.servicios.user;
import com.example.proyectofinal.models.login.Autoridad;
import com.example.proyectofinal.models.login.Rol;
import com.example.proyectofinal.repositories.login.AutoridadesRepository;
import com.example.proyectofinal.repositories.login.RolRepository;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
@Service
public class RolAutoService {
@Autowired
private RolRepository rolRepository;
@Autowired
private AutoridadesRepository autoridadRepository;
}

@ -0,0 +1,115 @@
package com.example.proyectofinal.servicios.user;
import com.example.proyectofinal.models.login.Autoridad;
import com.example.proyectofinal.models.login.Usuario;
import com.example.proyectofinal.models.login.Rol;
import com.example.proyectofinal.repositories.login.AutoridadesRepository;
import com.example.proyectofinal.repositories.login.UserRepository;
import com.example.proyectofinal.repositories.login.RolRepository;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UsuarioService {
@Autowired
private UserRepository userRepository;
@Autowired
private RolRepository rolRepository;
@Autowired
private AutoridadesRepository autoridadRepository;
private PasswordEncoder passwordEncoder;
@Autowired
JdbcTemplate jdbcTemplate;
private static final Logger logger = LoggerFactory.getLogger(UsuarioService.class);
@Autowired
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Transactional
public Usuario login(String nombreLogIn, String password) {
Usuario usuario = userRepository.findByNombreUsuario(nombreLogIn)
.orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado"));
if (usuario.isLogedIn()) {
throw new AlreadyLoggedInException("User is already logged in");
}
if (passwordEncoder.matches(password, usuario.getPassword())) {
userRepository.updateLogedIn( usuario.getId());
return usuario;
} else {
throw new BadCredentialsException("Invalid password");
}
}
private static class AlreadyLoggedInException extends RuntimeException {
public AlreadyLoggedInException(String message) {
super(message);
}
}
@Transactional
public void logout(String nombreLogIn) {
Usuario usuario = userRepository.findByNombreUsuario(nombreLogIn)
.orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado"));
logger.info("Resetting loggedIn status for user: " + nombreLogIn);
userRepository.resetLogedIn(usuario.getId());
}
@PostConstruct
@Transactional
public void createDefaultRolesAuthoritiesAndAdmin() {
try {
if (userRepository.findByNombreUsuario("admin").isEmpty()) {
Rol adminRole = rolRepository.findByName("ADMIN");
createUsuario("admin", "admin",
"admin@example.com",
"$2a$10$uTJY6B1H7MzEFrv2MX9K2uBgk1crVMtnuHgUgbTaQ/Cv7O.k0kUi2",
false, adminRole.getId());
}
} catch (Exception e) {
System.out.println("Exception in createDefaultRolesAuthoritiesAndAdmin: " + e.getMessage());
e.printStackTrace();
}
}
public Usuario createUsuario(String nombreUsuario, String nombreLogIn, String email, String password, boolean loged, Long rolId) {
// Insert into usuario table
String insertUsuarioSql = "INSERT INTO usuario (nombre_usuario, nombre_log_in, email, password, loged_in, fk_rol) VALUES (?, ?, ?, ?, ?, ?)";
jdbcTemplate.update(insertUsuarioSql, nombreUsuario, nombreLogIn, email, password, loged, rolId);
// Get the last inserted id
Long usuarioId = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class);
// Get all autoridades
List<Autoridad> autoridadList = autoridadRepository.findAll();
// For each autoridad, check if it's already associated with the rol
for (Autoridad autoridad : autoridadList) {
String checkSql = "SELECT COUNT(*) FROM rol_autoridad WHERE fk_rol = ? AND fk_autoridad = ?";
Integer count = jdbcTemplate.queryForObject(checkSql, Integer.class, rolId, autoridad.getId());
// If not associated, insert into rol_autoridad table
if (count == 0) {
String insertRolAutoridadSql = "INSERT INTO rol_autoridad (fk_rol, fk_autoridad) VALUES (?, ?)";
jdbcTemplate.update(insertRolAutoridadSql, rolId, autoridad.getId());
}
}
Usuario usuario = userRepository.findById(usuarioId).orElse(null);
return usuario;
}
}

@ -1,7 +1 @@
listEmpPrime: TEST[Empresa(id=4, nombre=Keytara, cif=123456789W4, correo=keytara@example.com, telefono=12345678904,
keywords=programador, sector=Sector(id=4, nombre=Musica)),
Empresa(id=9, nombre=FinTrack, cif=123456789W9, correo=fintrack@example.com, telefono=12345678909,
keywords=finance,investment, sector=Sector(id=4, nombre=Musica)),
Empresa(id=14, nombre=WealthTrack, cif=123456789W9, correo=wealthtrack@example.com, telefono=12345678909,
keywords=finance,investment, sector=Sector(id=4, nombre=Musica))]
listEmpSec: TEST[]
currently for the login I'm using the default and not recomened way of creating user, and log in witht the default ligin provided by spring. Can I rework my login to a more complex level with the clases Autoridad, wich has the authorities

@ -16,3 +16,4 @@ server.port=8080
#Dialecto
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

@ -0,0 +1,7 @@
-- Insert 'READ', 'WRITE', and 'DELETE' into the autoridad table if the table is empty
INSERT INTO autoridad (nombre)
SELECT 'READ' WHERE NOT EXISTS (SELECT 1 FROM autoridad);
INSERT INTO autoridad (nombre)
SELECT 'WRITE' WHERE NOT EXISTS (SELECT 1 FROM autoridad);
INSERT INTO autoridad (nombre)
SELECT 'DELETE' WHERE NOT EXISTS (SELECT 1 FROM autoridad);

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Primer Usuario</title>
</head>
<body>
</body>
</html>
Loading…
Cancel
Save

Powered by INFORMATICA.FP.EDU.ES.