Software Development Notions

Spring Security

April 17, 2020

Éstas dependencias nos crearán automáticamente un login para nuestra aplicación web, en el que podemos editar el usuario y contraseña de la siguiente manera en el archivo application.properties spring.security.user.name = pady spring.security.user.password= 1234 Es un ejemplo poco práctico, ya que lo óptimo sería comprobar los usuarios mediante una base de datos. Creamos la clase usuario y su repositorio.

Usuario.java

@Entity
public class Usuario {
    @Id
    private int id;
    private String nombre;
    private String clave;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getClave() {
        return clave;
    }

    public void setClave(String clave) {
        this.clave = clave;
    }
}

IUsuarioRepositorio.java

public interface IUsuarioRepositorio extends JpaRepository<Usuario,Integer> {
}

Agregamos nuestro usuario a la tabla

SpringDataApplicationTests.java

@Autowired
 private IUsuarioRepositorio repositorio_usuarios;
 @Test
 void crearUsuario() {
  Usuario usuario = new Usuario();
  usuario.setId(0);
  usuario.setClave("1234");
  usuario.setNombre("pady");
  Usuario actual = repositorio_usuarios.save(usuario);
  assertEquals("1234",actual.getClave());
 }

Vamos a crear una clase de configuración en nuestro proyecto, en la que usaremos un @Bean de Spring para cifrar las contraseñas que se guardan en la base datos.

SecurityConfig.java

@Configuration
public class SecurityConfig {
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }
}

Finalmente lo instanciamos en la clase donde interese, y usamos su método encode.

SpringDataApplicationTests.java

@Autowired
 private BCryptPasswordEncoder encoder;
 @Test
 void crearUsuario() {
  Usuario usuario = new Usuario();
  usuario.setId(1);
  usuario.setClave(encoder.encode("1234"));
  String expected = usuario.getClave();
  usuario.setNombre("pady");
  Usuario actual = repositorio_usuarios.save(usuario);
  assertEquals(expected,actual.getClave());
 }

Para habilitar @WebSecurity necesitamos que nuestra clase de configuración extienda de WebSecurityConfigureAdapter . Sobreescibrimos los métodos configure para indicar de donde sacaremos los usuarios a comparar. Pero primero debemos crear una clase UserService que extienda de UserDetailsService , en la cual instanciamos el repositorio de usuarios, y sobrescribimos el método de la clase extendida. Para configurar el método de la clase extendida, tenemos que tener un método que busque por un nombre de usuario, y no por un id, así que vamos a la interfaz repositorio de usuarios y creamos dicho método.

IUsuarioRepositorio.java

public interface IUsuarioRepositorio extends JpaRepository<Usuario,Integer> {
    Usuario findByNombre(String nombre);
}

UserService.java

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private IUsuarioRepositorio repositorio;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Usuario encontrado = repositorio.findByNombre(username);
        List<GrantedAuthority> roles = new ArrayList<>();
        roles.add(new SimpleGrantedAuthority("ADMIN"));
        UserDetails userDet = new User(encontrado.getNombre(),encontrado.getClave(),roles);
        return userDet;
    }
}

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userServiceDetails;
    @Autowired
    private BCryptPasswordEncoder bcrypt;
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userServiceDetails).passwordEncoder(bcrypt);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
}

PROYECTO DE EJEMPLO

⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️

PruebaSpringBoot


Welcome to my blog about Software Development! I would like to invite you to learning with me 👨‍💻

Search all posts