photo of people using laptops
COMPARTE ESTE ARTÍCULO

En este artículo, vamos a desarrollar un sistema cliente-servidor avanzado en Java que incluye funcionalidades de autenticación de usuarios y gestión de sesiones. Este proyecto te permitirá aplicar conceptos avanzados de programación en red, como la autenticación de usuarios, la gestión de sesiones mediante tokens, y la implementación de seguridad básica en un entorno cliente-servidor.


Parte 1: Implementación del Servidor HTTP en Java con Autenticación y Sesiones

El servidor que implementaremos se encargará de autenticar a los usuarios y manejar sesiones utilizando tokens únicos. Los usuarios podrán iniciar sesión proporcionando un nombre de usuario y una contraseña. Si la autenticación es exitosa, el servidor devolverá un token de sesión que el cliente utilizará para acceder a recursos protegidos.

Código del Servidor:

package cristinaleonacademiaexamen;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

public class ServidorHTTP {

    private static Map<String, String> usuarios = new HashMap<>();
    private static Map<String, String> sesiones = new HashMap<>();

    public static void main(String[] args) throws IOException {
        usuarios.put("usuario1", "password1");
        usuarios.put("usuario2", "password2");

        HttpServer server = HttpServer.create(new InetSocketAddress(8083), 0);
        server.createContext("/login", new LoginHandler());
        server.createContext("/recurso", new RecursoProtegidoHandler());
        server.setExecutor(Executors.newCachedThreadPool()); // Manejo concurrente de solicitudes
        server.start();
        System.out.println("Servidor HTTP iniciado en el puerto 8083");
    }

    static class LoginHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            if ("POST".equals(exchange.getRequestMethod())) {
                // Obtener las credenciales de la solicitud
                String[] credenciales = new String(exchange.getRequestBody().readAllBytes()).split("&");
                String nombreUsuario = credenciales[0].split("=")[1];
                String password = credenciales[1].split("=")[1];

                // Verificar las credenciales
                if (usuarios.containsKey(nombreUsuario) && usuarios.get(nombreUsuario).equals(password)) {
                    // Generar un token de sesión
                    String token = UUID.randomUUID().toString();
                    sesiones.put(token, nombreUsuario);

                    // Responder con el token de sesión
                    String respuesta = "Autenticación exitosa. Token de sesión: " + token;
                    exchange.sendResponseHeaders(200, respuesta.getBytes().length);
                    OutputStream os = exchange.getResponseBody();
                    os.write(respuesta.getBytes());
                    os.close();
                } else {
                    String respuesta = "Credenciales incorrectas.";
                    exchange.sendResponseHeaders(401, respuesta.getBytes().length);
                    OutputStream os = exchange.getResponseBody();
                    os.write(respuesta.getBytes());
                    os.close();
                }
            } else {
                exchange.sendResponseHeaders(405, -1); // Método no permitido
            }
        }
    }

    static class RecursoProtegidoHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            String token = exchange.getRequestHeaders().getFirst("Authorization");

            if (sesiones.containsKey(token)) {
                String nombreUsuario = sesiones.get(token);
                String respuesta = "Acceso concedido al recurso protegido para el usuario: " + nombreUsuario;
                exchange.sendResponseHeaders(200, respuesta.getBytes().length);
                OutputStream os = exchange.getResponseBody();
                os.write(respuesta.getBytes());
                os.close();
            } else {
                String respuesta = "No autorizado. Token de sesión inválido.";
                exchange.sendResponseHeaders(403, respuesta.getBytes().length);
                OutputStream os = exchange.getResponseBody();
                os.write(respuesta.getBytes());
                os.close();
            }
        }
    }
}

Explicación del Código:

  1. Gestión de Usuarios y Sesiones:
  • usuarios: Un HashMap que almacena los nombres de usuario y las contraseñas.
  • sesiones: Un HashMap que almacena los tokens de sesión asociados a los nombres de usuario.
  1. Autenticación de Usuarios:
  • La ruta /login maneja solicitudes POST que contienen las credenciales del usuario. Si las credenciales son correctas, se genera un token de sesión único que se devuelve al cliente.
  1. Acceso a Recursos Protegidos:
  • La ruta /recurso maneja solicitudes GET que requieren un token de sesión válido en la cabecera Authorization. Si el token es válido, se concede acceso al recurso protegido.
  1. Concurrencia:
  • Se utiliza un Executor para manejar múltiples solicitudes de manera concurrente.

Parte 2: Implementación del Cliente Java con Autenticación y Gestión de Sesiones

El cliente Java se encargará de autenticar a los usuarios y acceder a recursos protegidos utilizando el token de sesión proporcionado por el servidor.

Código del Cliente:

package cristinaleonacademiaexamen;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class ClienteHTTP {

    public static void main(String[] args) {
        try {
            // Autenticación del usuario
            String urlLogin = "http://localhost:8083/login";
            String credenciales = "usuario1=password1";
            String token = autenticarUsuario(urlLogin, credenciales);
            System.out.println("Token de sesión: " + token);

            // Acceso a recurso protegido usando el token
            String urlRecurso = "http://localhost:8083/recurso";
            String respuestaRecurso = accederRecursoProtegido(urlRecurso, token);
            System.out.println("Respuesta del recurso protegido: " + respuestaRecurso);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String autenticarUsuario(String urlStr, String credenciales) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
        conexion.setRequestMethod("POST");
        conexion.setDoOutput(true);

        try (OutputStream os = conexion.getOutputStream()) {
            os.write(credenciales.getBytes());
            os.flush();
        }

        BufferedReader in = new BufferedReader(new InputStreamReader(conexion.getInputStream()));
        String inputLine;
        StringBuilder contenido = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            contenido.append(inputLine);
        }

        in.close();
        return extraerTokenDeRespuesta(contenido.toString());
    }

    private static String extraerTokenDeRespuesta(String respuesta) {
        int inicio = respuesta.indexOf("Token de sesión: ") + 17;
        return respuesta.substring(inicio);
    }

    private static String accederRecursoProtegido(String urlStr, String token) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
        conexion.setRequestMethod("GET");
        conexion.setRequestProperty("Authorization", token);

        BufferedReader in = new BufferedReader(new InputStreamReader(conexion.getInputStream()));
        String inputLine;
        StringBuilder contenido = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            contenido.append(inputLine);
        }

        in.close();
        return contenido.toString();
    }
}

Explicación del Código:

  1. Autenticación del Usuario:
  • El cliente envía una solicitud POST al servidor con las credenciales del usuario. Si la autenticación es exitosa, recibe un token de sesión que se utilizará para acceder a recursos protegidos.
  1. Acceso a Recursos Protegidos:
  • El cliente envía una solicitud GET a un recurso protegido, incluyendo el token de sesión en la cabecera Authorization. Si el token es válido, el servidor responde con el contenido del recurso.
  1. Métodos Auxiliares:
  • autenticarUsuario: Envía las credenciales del usuario al servidor y obtiene el token de sesión.
  • extraerTokenDeRespuesta: Extrae el token de sesión de la respuesta del servidor.
  • accederRecursoProtegido: Envía una solicitud GET al recurso protegido utilizando el token de sesión.

Conclusión

Este ejercicio avanzado implementa un sistema cliente-servidor en Java con funcionalidades de autenticación y gestión de sesiones. El servidor maneja la autenticación de usuarios y la emisión de tokens de sesión, que se utilizan para acceder a recursos protegidos. El cliente, por su parte, interactúa con el servidor para autenticar usuarios y acceder a recursos utilizando el token.

Este sistema proporciona una base sólida para el desarrollo de aplicaciones seguras en Java que requieren autenticación y manejo de sesiones, y puede ser extendido para incluir características adicionales como encriptación, caducidad de tokens, y autenticación de múltiples factores. ¡Espero que este ejercicio te haya sido útil y que te ayude a mejorar tus habilidades en programación de sistemas distribuidos en Java!

Contenido restringido

Acceso de usuarios existentes
   
Registro de un nuevo usuario
*Campo necesario

Categories:

Tags:

Comments are closed

Estado de acceso
ESTADO DE ACCESO
TRADUCTORES
COMPARTENOS
error: CONTENIDO PROTEGIDO