Commit f67d63c9 by Antonio Rueda

Actualización de la configuración de Spring Security al método nuevo.

parent c7e765a3
...@@ -39,40 +39,50 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -39,40 +39,50 @@ import org.springframework.web.bind.annotation.RestController;
/** /**
* Controlador REST para los servicios de UjaCoin * Controlador REST para los servicios de UjaCoin
*
* @author ajrueda * @author ajrueda
*/ */
@RestController @RestController
@RequestMapping("/ujacoin") @RequestMapping("/ujacoin")
public class ControladorREST { public class ControladorREST {
@Autowired @Autowired
ServicioUjaCoin servicios; ServicioUjaCoin servicios;
/** Handler para excepciones de violación de restricciones */ /**
* Handler para excepciones de violación de restricciones
*/
@ExceptionHandler(ConstraintViolationException.class) @ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public void handlerViolacionRestricciones(ConstraintViolationException e) { public void handlerViolacionRestricciones(ConstraintViolationException e) {
// return ResponseEntity.badRequest().body(e.getMessage()); // return ResponseEntity.badRequest().body(e.getMessage());
} }
/** Handler para excepciones de accesos de usuarios no registrados */ /**
* Handler para excepciones de accesos de usuarios no registrados
*/
@ExceptionHandler(ClienteNoRegistrado.class) @ExceptionHandler(ClienteNoRegistrado.class)
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
public void handlerClienteNoRegistrado(ClienteNoRegistrado e) { public void handlerClienteNoRegistrado(ClienteNoRegistrado e) {
} }
/** Creación de clientes */ /**
* Creación de clientes
*/
@PostMapping("/clientes") @PostMapping("/clientes")
ResponseEntity<DTOCuenta> altaCliente(@RequestBody DTOCliente cliente) { ResponseEntity<DTOCuenta> altaCliente(@RequestBody DTOCliente cliente) {
try { try {
Cuenta cuenta = servicios.altaCliente(cliente.aCliente()); Cuenta cuenta = servicios.altaCliente(cliente.aCliente());
return ResponseEntity.status(HttpStatus.CREATED).body(new DTOCuenta(cuenta)); return ResponseEntity.status(HttpStatus.CREATED).body(new DTOCuenta(cuenta));
} } catch (ClienteYaRegistrado e) {
catch(ClienteYaRegistrado e) {
return ResponseEntity.status(HttpStatus.CONFLICT).build(); return ResponseEntity.status(HttpStatus.CONFLICT).build();
} }
} }
/** Login de clientes (temporal hasta incluir autenticación mediante Spring Security */ /**
* Login de clientes (temporal hasta incluir autenticación mediante Spring
* Security
*/
@GetMapping("/clientes/{dni}") @GetMapping("/clientes/{dni}")
ResponseEntity<DTOCliente> verCliente(@PathVariable String dni) { ResponseEntity<DTOCliente> verCliente(@PathVariable String dni) {
Optional<Cliente> cliente = servicios.verCliente(dni); Optional<Cliente> cliente = servicios.verCliente(dni);
...@@ -81,19 +91,22 @@ public class ControladorREST { ...@@ -81,19 +91,22 @@ public class ControladorREST {
.orElse(ResponseEntity.notFound().build()); .orElse(ResponseEntity.notFound().build());
} }
/** Registrar tarjetas */ /**
* Registrar tarjetas
*/
@PostMapping("/clientes/{dni}/tarjetas") @PostMapping("/clientes/{dni}/tarjetas")
ResponseEntity<Void> altaTarjeta(@PathVariable String dni, @RequestBody DTOTarjeta tarjeta) { ResponseEntity<Void> altaTarjeta(@PathVariable String dni, @RequestBody DTOTarjeta tarjeta) {
try { try {
servicios.registrarTarjeta(dni, tarjeta.aTarjeta()); servicios.registrarTarjeta(dni, tarjeta.aTarjeta());
return ResponseEntity.status(HttpStatus.CREATED).build(); return ResponseEntity.status(HttpStatus.CREATED).build();
} } catch (TarjetaYaRegistrada e) {
catch(TarjetaYaRegistrada e) {
return ResponseEntity.status(HttpStatus.CONFLICT).build(); return ResponseEntity.status(HttpStatus.CONFLICT).build();
} }
} }
/** Listar tarjetas */ /**
* Listar tarjetas
*/
@GetMapping("/clientes/{dni}/tarjetas") @GetMapping("/clientes/{dni}/tarjetas")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
List<DTOTarjeta> verTarjetas(@PathVariable String dni) { List<DTOTarjeta> verTarjetas(@PathVariable String dni) {
...@@ -101,7 +114,9 @@ public class ControladorREST { ...@@ -101,7 +114,9 @@ public class ControladorREST {
.map(t -> new DTOTarjeta(t)).toList(); .map(t -> new DTOTarjeta(t)).toList();
} }
/** Obtener una tarjeta concreta */ /**
* Obtener una tarjeta concreta
*/
@GetMapping("/clientes/{dni}/tarjetas/{num}") @GetMapping("/clientes/{dni}/tarjetas/{num}")
ResponseEntity<DTOTarjeta> verTarjeta(@PathVariable String dni, @PathVariable String num) { ResponseEntity<DTOTarjeta> verTarjeta(@PathVariable String dni, @PathVariable String num) {
return servicios.verTarjetas(dni).stream() return servicios.verTarjetas(dni).stream()
...@@ -111,14 +126,18 @@ public class ControladorREST { ...@@ -111,14 +126,18 @@ public class ControladorREST {
.orElse(ResponseEntity.notFound().build()); .orElse(ResponseEntity.notFound().build());
} }
/** Crear cuentas adicionales */ /**
* Crear cuentas adicionales
*/
@PostMapping("/clientes/{dni}/cuentas") @PostMapping("/clientes/{dni}/cuentas")
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
DTOCuenta altaCuenta(@PathVariable String dni) { DTOCuenta altaCuenta(@PathVariable String dni) {
return new DTOCuenta(servicios.crearCuenta(dni)); return new DTOCuenta(servicios.crearCuenta(dni));
} }
/** Listar cuentas del cliente */ /**
* Listar cuentas del cliente
*/
@GetMapping("/clientes/{dni}/cuentas") @GetMapping("/clientes/{dni}/cuentas")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
List<DTOCuenta> verCuentas(@PathVariable String dni) { List<DTOCuenta> verCuentas(@PathVariable String dni) {
...@@ -126,7 +145,9 @@ public class ControladorREST { ...@@ -126,7 +145,9 @@ public class ControladorREST {
.map(c -> new DTOCuenta(c)).toList(); .map(c -> new DTOCuenta(c)).toList();
} }
/** Obtener una cuenta concreta */ /**
* Obtener una cuenta concreta
*/
@GetMapping("/clientes/{dni}/cuentas/{num}") @GetMapping("/clientes/{dni}/cuentas/{num}")
ResponseEntity<DTOCuenta> verCuenta(@PathVariable String dni, @PathVariable String num) { ResponseEntity<DTOCuenta> verCuenta(@PathVariable String dni, @PathVariable String num) {
return servicios.verCuentas(dni).stream() return servicios.verCuentas(dni).stream()
...@@ -136,7 +157,9 @@ public class ControladorREST { ...@@ -136,7 +157,9 @@ public class ControladorREST {
.orElse(ResponseEntity.notFound().build()); .orElse(ResponseEntity.notFound().build());
} }
/** Registrar un nuevo movimiento en la cuenta */ /**
* Registrar un nuevo movimiento en la cuenta
*/
@PostMapping("/clientes/{dni}/cuentas/{numCuenta}/movimientos") @PostMapping("/clientes/{dni}/cuentas/{numCuenta}/movimientos")
ResponseEntity<Void> registrarMovimiento(@PathVariable String dni, @PathVariable String numCuenta, @RequestBody DTOMovimiento movimiento) { ResponseEntity<Void> registrarMovimiento(@PathVariable String dni, @PathVariable String numCuenta, @RequestBody DTOMovimiento movimiento) {
if (movimiento.tipo() == null) { if (movimiento.tipo() == null) {
...@@ -144,7 +167,7 @@ public class ControladorREST { ...@@ -144,7 +167,7 @@ public class ControladorREST {
} }
try { try {
switch(movimiento.tipo()) { switch (movimiento.tipo()) {
case DTOMovimiento.INGRESO: case DTOMovimiento.INGRESO:
servicios.ingreso(numCuenta, movimiento.numTarjeta(), movimiento.importe()); servicios.ingreso(numCuenta, movimiento.numTarjeta(), movimiento.importe());
break; break;
...@@ -160,34 +183,33 @@ public class ControladorREST { ...@@ -160,34 +183,33 @@ public class ControladorREST {
default: default:
return ResponseEntity.badRequest().build(); return ResponseEntity.badRequest().build();
} }
} } catch (SaldoInsuficienteParaOperacion e) {
catch(SaldoInsuficienteParaOperacion e) {
return ResponseEntity.status(HttpStatus.PRECONDITION_FAILED).build(); return ResponseEntity.status(HttpStatus.PRECONDITION_FAILED).build();
} } catch (TarjetaNoRegistrada t) {
catch(TarjetaNoRegistrada t) {
return ResponseEntity.status(HttpStatus.FAILED_DEPENDENCY).build(); return ResponseEntity.status(HttpStatus.FAILED_DEPENDENCY).build();
} }
return ResponseEntity.status(HttpStatus.CREATED).build(); return ResponseEntity.status(HttpStatus.CREATED).build();
} }
/** Listar movimientos, acotados por fechas y paginados */ /**
* Listar movimientos, acotados por fechas y paginados
*/
@GetMapping("/clientes/{dni}/cuentas/{numCuenta}/movimientos") @GetMapping("/clientes/{dni}/cuentas/{numCuenta}/movimientos")
ResponseEntity<List<DTOMovimiento>> verMovimientos( ResponseEntity<List<DTOMovimiento>> verMovimientos(
@PathVariable String dni, @PathVariable String dni,
@PathVariable String numCuenta, @PathVariable String numCuenta,
@RequestParam(required=false) String desdeFecha, @RequestParam(required = false) String desdeFecha,
@RequestParam(required=false) String hastaFecha, @RequestParam(required = false) String hastaFecha,
@RequestParam(required=false, defaultValue="1") @Positive int pag, @RequestParam(required = false, defaultValue = "1") @Positive int pag,
@RequestParam(required=false, defaultValue="10") @Positive int num) { @RequestParam(required = false, defaultValue = "10") @Positive int num) {
LocalDateTime fechaInicial; LocalDateTime fechaInicial;
LocalDateTime fechaFinal; LocalDateTime fechaFinal;
try { try {
fechaInicial = desdeFecha != null ? LocalDateTime.parse(desdeFecha) : null; fechaInicial = desdeFecha != null ? LocalDateTime.parse(desdeFecha) : null;
fechaFinal = hastaFecha != null ? LocalDateTime.parse(hastaFecha) : null; fechaFinal = hastaFecha != null ? LocalDateTime.parse(hastaFecha) : null;
} } catch (DateTimeParseException e) {
catch(DateTimeParseException e) {
return ResponseEntity.badRequest().build(); return ResponseEntity.badRequest().build();
} }
......
...@@ -26,18 +26,6 @@ public class ServicioDatosCliente implements UserDetailsService { ...@@ -26,18 +26,6 @@ public class ServicioDatosCliente implements UserDetailsService {
@Autowired @Autowired
ServicioUjaCoin servicioUjaCoin; ServicioUjaCoin servicioUjaCoin;
/*
PasswordEncoder encoder;
public ServicioDatosCliente() {
encoder = new BCryptPasswordEncoder();
}
PasswordEncoder getEncoder() {
return encoder;
}
*/
@Override @Override
public UserDetails loadUserByUsername(String dni) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String dni) throws UsernameNotFoundException {
Cliente cliente = servicioUjaCoin.verCliente(dni) Cliente cliente = servicioUjaCoin.verCliente(dni)
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
*/ */
package es.ujaen.dae.ujacoin.seguridad; package es.ujaen.dae.ujacoin.seguridad;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
/** /**
* Proveedor de datos de seguridad de UJaCoin * Proveedor de datos de seguridad de UJaCoin
...@@ -20,25 +20,14 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; ...@@ -20,25 +20,14 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
* @author ajrueda * @author ajrueda
*/ */
@Configuration @Configuration
public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter { public class ServicioSeguridadUjaCoin {
@Autowired @Bean
ServicioDatosCliente servicioDatosCliente; PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
//@Autowired
//CacheManager cacheManager;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(servicioDatosCliente)
.passwordEncoder(new BCryptPasswordEncoder());
//.passwordEncoder(new CachedBCryptPasswordEncoder(cacheManager.getCache("claves")));
//auth.inMemoryAuthentication()
// .withUser("ujacoin").roles("CLIENTE").password("{noop}secret");
} }
@Override @Bean
protected void configure(HttpSecurity httpSecurity) throws Exception { public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// Desactivar cualquier soporte de sesión // Desactivar cualquier soporte de sesión
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
...@@ -53,5 +42,13 @@ public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter { ...@@ -53,5 +42,13 @@ public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter {
// Permitir el acceso de un cliente sólo a sus recursos asociados (datos personales, cuentas, tarjetas, etc.) // Permitir el acceso de un cliente sólo a sus recursos asociados (datos personales, cuentas, tarjetas, etc.)
httpSecurity.authorizeRequests().antMatchers("/ujacoin/clientes/{dni}/**").access("hasRole('CLIENTE') and #dni == principal.username"); httpSecurity.authorizeRequests().antMatchers("/ujacoin/clientes/{dni}/**").access("hasRole('CLIENTE') and #dni == principal.username");
return httpSecurity.build();
} }
/** Hacer visible el gestor de autenticación del sistema por si se quiere hacer login manual */
// @Bean
// public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfiguration) throws Exception {
// return authConfiguration.getAuthenticationManager();
// }
} }
...@@ -13,6 +13,7 @@ import java.time.LocalDate; ...@@ -13,6 +13,7 @@ import java.time.LocalDate;
import java.util.List; import java.util.List;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.h2.security.auth.AuthenticationException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
...@@ -22,6 +23,9 @@ import org.springframework.boot.web.client.RestTemplateBuilder; ...@@ -22,6 +23,9 @@ import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
......
package es.ujaen.dae.ujacoin.servicios;
import es.ujaen.dae.ujacoin.entidades.Cliente; import es.ujaen.dae.ujacoin.entidades.Cliente;
import es.ujaen.dae.ujacoin.entidades.Cuenta; import es.ujaen.dae.ujacoin.entidades.Cuenta;
...@@ -8,6 +7,7 @@ import es.ujaen.dae.ujacoin.entidades.movimientos.Movimiento; ...@@ -8,6 +7,7 @@ import es.ujaen.dae.ujacoin.entidades.movimientos.Movimiento;
import es.ujaen.dae.ujacoin.entidades.movimientos.TransferenciaEmitida; import es.ujaen.dae.ujacoin.entidades.movimientos.TransferenciaEmitida;
import es.ujaen.dae.ujacoin.entidades.movimientos.TransferenciaRecibida; import es.ujaen.dae.ujacoin.entidades.movimientos.TransferenciaRecibida;
import es.ujaen.dae.ujacoin.excepciones.SaldoInsuficienteParaOperacion; import es.ujaen.dae.ujacoin.excepciones.SaldoInsuficienteParaOperacion;
import es.ujaen.dae.ujacoin.servicios.ServicioUjaCoin;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
...@@ -21,10 +21,13 @@ import org.assertj.core.api.Assertions; ...@@ -21,10 +21,13 @@ import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.annotation.DirtiesContext.MethodMode;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
/** /**
* Test de integración de la aplicación * Test de integración de la aplicación
* @author ajrueda * @author ajrueda
...@@ -37,6 +40,7 @@ public class ServicioUjaCoinTest { ...@@ -37,6 +40,7 @@ public class ServicioUjaCoinTest {
@Autowired @Autowired
ServicioUjaCoin servicioUjaCoin; ServicioUjaCoin servicioUjaCoin;
@Test @Test
public void testAccesoServicioUjaCoin() { public void testAccesoServicioUjaCoin() {
Assertions.assertThat(servicioUjaCoin).isNotNull(); Assertions.assertThat(servicioUjaCoin).isNotNull();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment