Spring-Security en JavaFX (Parte-2)

Segunda parte del tutorial de seguridad para JavaFX con Spring Security Framework, aquí nos centraremos en eliminar el archivo de configuración security.xml y tener toda la configuración basada en código Java, a parte integraremos una base de datos donde almacenaremos la información de los usuarios registrados, por último aprenderemos a proteger las contraseñas mediante el uso de algoritmos hash.

Configuración Spring Security Usando Java


Anteriormente nuestra configuración se encontraba en el archivo security.xml, para eliminar la necesidad de utilizar XML realizaremos la configuración utilizando únicamente código Java.

Lo primero que haremos será extender la clase GlobalMethodSecurityConfiguration, a esta nueva clase le agregamos las anotaciones: @Configuration, para que Spring la use como clase de configuración y @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true), para habilitar la seguridad sobre los métodos usando las anotaciones @Secured y @PreAuthorize.

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfiguration extends GlobalMethodSecurityConfiguration {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("user1").password("123").roles("ADMIN").and()
                .withUser("user2").password("456").roles("USER", "STANDAR");
    }

    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
}

Al igual que en XML se agregan dos usuarios memoria, observamos que no usamos el prefijo ROLE_, este es añadido automáticamente por el framework, además incluimos el bean AuthenticationManager que requerimos para autenticarnos.

Para cargar esta configuración utilizamos @Import(SecurityConfiguration.class) en lugar de @ImportResource("classpath:security.xml") que usamos anteriormente.

Almacenar Usuarios en Base de Datos


Requerimos las tablas para almacenar los datos, usaremos una base de datos MySQL, la creamos con el siguiente script DDL:

create table users (
 username varchar(50) not null primary key,
 userpass varchar(50) not null,
 enabled boolean not null
) engine = InnoDb;

create table authorities (
 username varchar(50) not null,
 authority varchar(50) not null,
 foreign key (username) references users (username),
 unique index authorities_idx_1 (username, authority)
) engine = InnoDb;

mysql spring security
El siguiente script SQL inserta a los usuarios y sus correspondientes roles que ya teníamos en memoria a la base de datos:

insert into users values ('user1', '123', 1);
insert into authorities values ('user1', 'ADMIN');

insert into users values ('user2', '456', 1);
insert into authorities values ('user2', 'USER');
insert into authorities values ('user2', 'STANDAR');

Editamos pom.xml, agregamos spring-jdbc y mysql-connector-java, seguido podemos crear nuestro DataSource con la correspondiente información de conexión a la base de datos MySql, recordamos cambiar nombre de la base de datos, usuario y contraseña.

@Bean
public DataSource dataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/nombre-base-datos");
        ds.setUsername("nombre-usuario");
        ds.setPassword("password-db");
        return ds;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource())
                .rolePrefix("ROLE_")
                .usersByUsernameQuery("SELECT username, userpass, enabled FROM users WHERE username = ?")
                .authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?");
}

Nos resta configurar el administrador de autenticación para usar la base de datos, le debemos indicar la consulta usada para obtener el usuario, contraseña y si está habilitado, en una segunda consulta indicamos como obtener los roles correspondientes al usuario.

Proteger las contraseñas


Para finalizar veremos cómo utilizar el algoritmo hash MD5 para proteger las contraseñas almacenadas en la base de datos.

Para calcular el MD5 hash usaremos la clase Md5PasswordEncoder, el siguiente fragmento de código calcula el hash para la contraseña de user1 “123” y user2 “456”, este resultado será el que guardaremos en la base de datos reemplazando la contraseña anterior, la cual no está protegida.

Md5PasswordEncoder encode = new Md5PasswordEncoder();
String pass1 = encode.encodePassword("123", null);
String pass2 = encode.encodePassword("456", null);

secure database mysql
Para utilizar en nuestro sistema de login la clasde Md5PasswordEncoder solo debemos indicarle al AuthenticationManagerBuilder que este será nuestro PasswordEncoder.

auth.jdbcAuthentication()
    /.../
    .passwordEncoder(new Md5PasswordEncoder());

Si deseamos que nuestra aplicación sea capaz de registrar usuarios, debemos recordar calcular el hash antes de guardar en la base de datos.

GitHib: JavaFX Contraseña Segura.

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Detección de rostros

Instalar OpenCV para Python en Windows