Commit de6e3ef3 by Antonio Rueda

Autenticación básica HTTP mediante Spring Security para acceso al API.

parent 9e6ce320
......@@ -34,6 +34,11 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
......
......@@ -11,7 +11,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
@SpringBootApplication(scanBasePackages={
"es.ujaen.dae.ujacoin.servicios",
"es.ujaen.dae.ujacoin.repositorios",
"es.ujaen.dae.ujacoin.controladoresREST"
"es.ujaen.dae.ujacoin.controladoresREST",
"es.ujaen.dae.ujacoin.seguridad"
})
@EntityScan(basePackages="es.ujaen.dae.ujacoin.entidades")
public class UjaCoinApp {
......
......@@ -74,8 +74,8 @@ public class ControladorREST {
/** Login de clientes (temporal hasta incluir autenticación mediante Spring Security */
@GetMapping("/clientes/{dni}")
ResponseEntity<DTOCliente> loginCliente(@PathVariable String dni, @RequestParam String clave) {
Optional<Cliente> cliente = servicios.loginCliente(dni, clave);
ResponseEntity<DTOCliente> verCliente(@PathVariable String dni) {
Optional<Cliente> cliente = servicios.verCliente(dni);
return cliente
.map(c -> ResponseEntity.ok(new DTOCliente(c)))
.orElse(ResponseEntity.notFound().build());
......
package es.ujaen.dae.ujacoin.entidades;
import es.ujaen.dae.ujacoin.util.ExprReg;
import es.ujaen.dae.ujacoin.util.CodificadorMd5;
import es.ujaen.dae.ujacoin.util.CodificadorPassword;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
......@@ -80,7 +80,8 @@ public class Cliente implements Serializable {
this.tlf = tlf;
this.email = email;
this.clave = (clave != null ? CodificadorMd5.codificar(clave) : null);
this.clave = (clave != null ? CodificadorPassword.codificar(clave) : null);
// this.clave = clave;
tarjetas = new ArrayList<>();
cuentas = new ArrayList<>();
......@@ -116,7 +117,12 @@ public class Cliente implements Serializable {
* @return
*/
public boolean claveValida(String clave) {
return this.clave.equals(CodificadorMd5.codificar(clave));
return CodificadorPassword.igual(clave, this.clave);
//return this.clave.equals(clave);
}
public String getClave() {
return clave;
}
/**
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import es.ujaen.dae.ujacoin.entidades.Cliente;
import es.ujaen.dae.ujacoin.servicios.ServicioUjaCoin;
import org.springframework.beans.factory.annotation.Autowired;
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.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
/**
* Servicio que proporciona los datos del cliente
* @author ajrueda
*/
@Service
public class ServicioDatosCliente implements UserDetailsService {
@Autowired
ServicioUjaCoin servicioUjaCoin;
PasswordEncoder encoder;
public ServicioDatosCliente() {
encoder = new BCryptPasswordEncoder();
}
PasswordEncoder getEncoder() {
return encoder;
}
@Override
public UserDetails loadUserByUsername(String dni) throws UsernameNotFoundException {
Cliente cliente = servicioUjaCoin.verCliente(dni)
.orElseThrow(() -> new UsernameNotFoundException(""));
return User.withUsername(cliente.getDni())
.roles("CLIENTE").password(cliente.getClave())
.build();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Proveedor de datos de seguridad de UJaCoin
*
* @author ajrueda
*/
@Configuration
@EnableWebSecurity
public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter {
@Autowired
ServicioDatosCliente servicioDatosCliente;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(servicioDatosCliente)
.passwordEncoder(new BCryptPasswordEncoder());
// auth.inMemoryAuthentication()
// .withUser("ujacoin").roles("CLIENTE").password("{noop}secret");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable();
httpSecurity.httpBasic();
httpSecurity.authorizeRequests().antMatchers(HttpMethod.POST, "/ujacoin/clientes").anonymous();
// 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");
}
}
......@@ -83,6 +83,21 @@ public class ServicioUjaCoin {
}
/**
* Realiza un login de un cliente
* @param dni el DNI del cliente
* @param clave la clave de acceso
* @return el objeto de la clase Cliente asociado
*/
@Transactional
public Optional<Cliente> verCliente(@NotBlank String dni) {
Optional<Cliente> clienteLogin = repositorioClientes.buscar(dni);
// Asegurarnos de que se devuelve el cliente con los datos precargados
clienteLogin.ifPresent(c -> c.verCuentas().size());
return clienteLogin;
}
/**
* Crear una cuenta adicional para el cliente
* @param dni el DNI delcliente
* @return la cuenta creada
......
package es.ujaen.dae.ujacoin.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Codificador sencillo para contraseñas basado en Md5 (no seguro)
* @author ajrueda
*/
public class CodificadorMd5 {
public class CodificadorPassword {
static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
private CodificadorMd5() {
private CodificadorPassword() {
}
public static String codificar(String cadena) {
/*
String cadenaCodificada = null;
try {
......@@ -25,6 +26,11 @@ public class CodificadorMd5 {
// No debe ocurrir puesto que MD5 es un algoritmo que existe en la
// implementación Java estándar
}
return cadenaCodificada;
*/
return encoder.encode(cadena);
}
public static boolean igual(String password, String passwordCodificado) {
return encoder.matches(password, passwordCodificado);
}
}
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