One place for hosting & domains

      autenticación

      Cómo configurar la autenticación basada en claves de SSH en un servidor Linux


      Introducción

      SSH, o shell seguro, es un protocolo cifrado que se usa para administrar servidores y comunicarse con ellos. Al trabajar con un servidor de Linux, es probable que pase la mayor parte de su tiempo en una sesión de terminal conectada a su servidor a través de SSH.

      Aunque existen varias formas de iniciar sesión en un servidor SSH, en esta guía nos centraremos en la configuración de las claves SSH. Las claves SSH proporcionan una forma fácil y extremadamente segura de iniciar sesión en su servidor. Por este motivo, este es el método que recomendamos a todos los usuarios.

      ¿Cómo funcionan las claves SSH?

      Un servidor SSH puede autenticar a los clientes usando varios métodos diferentes. El más básico de estos es la autenticación por contraseña, que es fácil de usar, pero no es la más segura.

      A pesar de que las contraseñas se envían al servidor de forma segura, generalmente no son lo suficientemente complejas o largas como para resistir a los constantes y persistentes atacantes. La potencia de procesamiento moderna combinada con scripts automatizados hace que sea muy posible forzar una cuenta protegida con una contraseña. A pesar de que existen otros métodos para añadir seguridad adicional (fail2ban, etc.), las claves SSH son una alternativa confiable y segura.

      Los pares de claves SSH son dos claves criptográficamente seguras que pueden usarse para autenticar a un cliente a un servidor SSH. Cada par de claves está compuesto por una clave pública y una clave privada.

      El cliente mantiene la clave privada y debe mantenerla en absoluto secreto. Poner en riesgo la clave privada permitirá al atacante iniciar sesión en los servidores que están configurados con la clave pública asociada sin autenticación adicional. Como medida de precaución adicional, puede cifrar la clave en el disco con una frase de contraseña.

      La clave pública asociada puede compartirse libremente sin ninguna consecuencia negativa. La clave pública puede usarse para cifrar mensajes que solo la clave privada puede descifrar. Esta propiedad se emplea como forma de autenticación mediante el uso del par de claves.

      La clave pública se carga a un servidor remoto, en el que quiere iniciar sesión con SSH. La clave se añade a un archivo especial dentro de la cuenta de usuario con la que iniciará sesión, llamada ~/.ssh/authorized_keys.

      Cuando un cliente intente autenticarse usando claves SSH, el servidor puede comprobar si el cliente posee la clave privada. Si el cliente puede demostrar que posee la clave privada, se genera una sesión de shell o se ejecuta el comando solicitado.

      Cómo crear claves SSH

      El primer paso para configurar la autenticación con clave SSH en su servidor es generar un par de claves SSH en su computadora local.

      Para ello, podemos usar una utilidad especial llamada ssh-keygen, que se incluye con el conjunto de herramientas estándar de OpenSSH. Por defecto, esto creará un par de claves RSA de 2048 bits, lo cual es muy útil para la mayoría de usos.

      En su computadora local, genere un par de claves SSH escribiendo lo siguiente:

      ssh-keygen
      
      Generating public/private rsa key pair.
      Enter file in which to save the key (/home/username/.ssh/id_rsa):
      

      La utilidad le solicitará que seleccione una ubicación para las claves que se generarán. Por defecto, las claves se almacenarán en el directorio ~/.ssh dentro del directorio de inicio de su usuario. La clave privada se llamará id_rsa, y la clave pública asociada se llamará id_rsa.pub.

      Normalmente, es mejor que conserve la ubicación predeterminada en esta etapa. Hacerlo permitirá a su cliente SSH encontrar automáticamente sus claves SSH al intentar autenticarse. Si desea elegir una ruta no estándar, introdúzcala ahora, de lo contrario, presione ENTER para aceptar la predeterminada.

      Si generó previamente un par de claves SSH, es posible que vea un mensaje como el siguiente:

      /home/username/.ssh/id_rsa already exists.
      Overwrite (y/n)?
      

      Si elige sobrescribir la clave en el disco, ya no podrá autenticar usando la clave anterior. Tenga mucho cuidado al convalidar la operación, ya que este es un proceso destructivo que no puede revertirse.

      Created directory '/home/username/.ssh'.
      Enter passphrase (empty for no passphrase):
      Enter same passphrase again:
      

      A continuación, se le solicitará que introduzca una frase de contraseña para la clave. Esta es una frase de contraseña opcional que puede usarse para cifrar el archivo de clave privada en el disco.

      Es posible que se esté preguntando qué ventajas ofrece una clave SSH si aún así necesita introducir una frase de contraseña. Algunas de las ventajas son las siguientes:

      • La clave SSH privada (la parte que puede protegerse con una frase de contraseña), nunca se expone en la red. La frase de contraseña solo se usa para descifrar la clave en la máquina local. Esto significa que los ataques de fuerza bruta basada en la red no podrán contra la frase de contraseña.
      • La clave privada se guarda dentro de un directorio restringido. El cliente SSH no reconocerá claves privadas que no estén guardadas en directorios restringidos. La propia clave también debe tener permisos restringidos (de lectura y escritura solo disponibles para el propietario). Esto significa que otros usuarios del sistema no pueden espiar.
      • Cualquier atacante que desee descifrar la frase de contraseña de la clave SSH privada debe tener acceso previo al sistema. Esto significa que ya tendrán acceso a su cuenta de usuario o a la cuenta root. Si se encuentra en esta posición, la frase de contraseña puede evitar que el atacante inicie sesión de inmediato en sus otros servidores. Esto le dará tiempo para crear e implementar un nuevo par de claves SSH y eliminar el acceso de la clave comprometida.

      Dado que la clave privada nunca se expone a la red y está protegida mediante permisos de archivo, nadie más que usted debería tener acceso a este archivo (y el usuario root). La frase de contraseña sirve como capa de protección adicional en caso de que estas condiciones se vean comprometidas.

      Una frase de contraseña es un complemento opcional. Si introduce una, deberá proporcionarla cada vez que utilice esta clave (a menos que esté ejecutando un software de agente SSH que almacene la clave descifrada). Recomendamos usar una frase de contraseña, pero si no desea establecer una frase de contraseña, puede simplemente pulsar ENTER para omitir esta pregunta.

      Your identification has been saved in /home/username/.ssh/id_rsa.
      Your public key has been saved in /home/username/.ssh/id_rsa.pub.
      The key fingerprint is:
      a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_host
      The key's randomart image is:
      +--[ RSA 2048]----+
      |     ..o         |
      |   E o= .        |
      |    o. o         |
      |        ..       |
      |      ..S        |
      |     o o.        |
      |   =o.+.         |
      |. =++..          |
      |o=++.            |
      +-----------------+
      

      Ahora dispondrá de una clave pública y privada que puede usar para realizar la autenticación. El siguiente paso es ubicar la clave pública en su servidor, a fin de poder utilizar la autenticación basada en la clave SSH para iniciar sesión.

      Cómo incorporar su clave pública al crear su servidor

      Si está iniciando un nuevo servidor de DigitalOcean, puede incorporar automáticamente su clave pública SSH en la cuenta root de su nuevo servidor.

      En la parte inferior de la página de creación de Droplet, existe una opción para añadir claves SSH a su servidor:

      Clave SSH incorporada

      Si ya ha añadido un archivo de clave pública a su cuenta de DigitalOcean, lo verá aquí como una opción seleccionable (hay dos claves existentes en el ejemplo anterior: “clave de trabajo” y “clave de inicio”). Para incorporar una clave existente, simplemente haga clic en ella y se resaltará Puede incorporar múltiples claves en un solo servidor:

      Selección de clave SSH

      Si aún no tiene una clave SSH pública cargada en su cuenta o si quiere añadir una nueva clave a su cuenta, haga clic en el botón “+ Add SSH Key” (+ Añadir clave SSH). Esto se ampliará a un mensaje:

      Mensaje de clave SSH

      Pegue su clave pública SSH en el cuadro “Contenido de la clave SSH”. Suponiendo que haya generado sus claves usando el método anterior, puede obtener el contenido de la clave pública en su computadora local escribiendo lo siguiente:

      cat ~/.ssh/id_rsa.pub
      
      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNqqi1mHLnryb1FdbePrSZQdmXRZxGZbo0gTfglysq6KMNUNY2VhzmYN9JYW39yNtjhVxqfW6ewc+eHiL+IRRM1P5ecDAaL3V0ou6ecSurU+t9DR4114mzNJ5SqNxMgiJzbXdhR+j55GjfXdk0FyzxM3a5qpVcGZEXiAzGzhHytUV51+YGnuLGaZ37nebh3UlYC+KJev4MYIVww0tWmY+9GniRSQlgLLUQZ+FcBUjaqhwqVqsHe4F/woW1IHe7mfm63GXyBavVc+llrEzRbMO111MogZUcoWDI9w7UIm8ZOTnhJsk7jhJzG2GpSXZHmly/a/buFaaFnmfZ4MYPkgJD username@example.com
      

      Pegue este valor completo en el cuadro más grande. En el cuadro “Comment (optional)” (Comentario [opcional]), puede elegir una etiqueta para la clave. Esta se mostrará como el nombre de la clave en la interfaz de DigitalOcean:

      Nueva clave SSH

      Cuando cree su Droplet, las claves SSH públicas que haya seleccionado se ubicarán en el archivo ~/.ssh/authorized_keys de la cuenta del usuario root. Esto le permitirá iniciar sesión en el servidor desde la computadora con su clave privada.

      Cómo copiar una clave pública en su servidor

      Si ya tiene un servidor disponible y no incorporó claves al crearlo, aún puede cargar su clave pública y usarla para autenticarse en su servidor.

      El método que utilice depende en gran medida de las herramientas que tenga disponibles y los detalles de su configuración actual. Todos los siguientes métodos producen el mismo resultado final. El método más fácil y automatizado es el primero y los que se siguen requieren pasos manuales adicionales si no puede usar los métodos anteriores.

      Cómo copiar su clave pública con SSH-Copy-ID

      La forma más sencilla de copiar su clave pública a un servidor existente es usar una utilidad llamada ssh-copy-id. Debido a su simplicidad, se recomienda este método si está disponible.

      La herramienta ssh-copy-id está incluida en los paquetes de OpenSSH en muchas distribuciones, por lo que es posible que esté disponible en su sistema local. Para que este método funcione, ya debe disponer de acceso con SSH basado en contraseña en su servidor.

      Para usar la utilidad, solo necesita especificar el host remoto al que desee conectarse y la cuenta de usuario a la que tenga acceso SSH con contraseña. Esta es la cuenta donde se copiará su clave SSH pública.

      La sintaxis es la siguiente:

      ssh-copy-id username@remote_host
      

      Es posible que vea un mensaje como el siguiente:

      The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
      ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
      Are you sure you want to continue connecting (yes/no)? yes
      

      Esto solo significa que su computadora local no reconoce el host remoto. Esto sucederá la primera vez que establezca conexión con un nuevo host. Escriba “yes” y presione ENTER para continuar.

      A continuación, la utilidad analizará su cuenta local en busca de la clave id_rsa.pub que creamos antes. Cuando la encuentre, le solicitará la contraseña de la cuenta del usuario remoto:

      /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
      /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
      username@111.111.11.111's password:
      

      Escriba la contraseña (por motivos de seguridad, no se mostrará lo que escriba) y presione ENTER. La utilidad se conectará a la cuenta en el host remoto usando la contraseña que proporcionó. Luego, copie el contenido de su clave ~/.ssh/id_rsa.pub a un archivo en el directorio principal de la cuenta remota ~/.ssh, llamado authorized_keys.

      Verá un resultado similar a este:

      Number of key(s) added: 1
      
      Now try logging into the machine, with:   "ssh 'username@111.111.11.111'"
      and check to make sure that only the key(s) you wanted were added.
      

      En este punto, su clave id_rsa.pub se habrá cargado en la cuenta remota. Puede continuar con la siguiente sección.

      Cómo copiar la clave pública con SSH

      Si no tiene ssh-copy-id disponible, pero tiene acceso de SSH basado en contraseña a una cuenta de su servidor, puede cargar sus claves usando un método de SSH convencional.

      Para ello, podemos extraer el contenido de nuestra clave pública SSH en nuestra computadora local y canalizarlo a través de una conexión SSH al servidor remoto. Por otro lado, podemos asegurarnos de que el directorio ~/.sh exista bajo la cuenta que estamos usando y luego salga el contenido que canalizamos en un archivo llamado authorized_keys dentro de este directorio.

      Usaremos el símbolo de redireccionamiento >> para añadir el contenido en lugar de sobrescribirlo. Esto nos permitirá agregar claves sin eliminar las claves previamente agregadas.

      El comando completo tendrá el siguiente aspecto:

      cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
      

      Es posible que vea un mensaje como el siguiente:

      The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
      ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
      Are you sure you want to continue connecting (yes/no)? yes
      

      Esto solo significa que su computadora local no reconoce el host remoto. Esto sucederá la primera vez que establezca conexión con un nuevo host. Escriba “yes” y presione ENTER para continuar.

      A continuación, se le solicitará la contraseña de la cuenta a la que está intentando conectarse:

      username@111.111.11.111's password:
      

      Una vez que ingrese su contraseña, el contenido de su clave id_rsa.pub se copiará al final del archivo authorized_keys de la cuenta del usuario remoto. Continúe con la siguiente sección si se realizó exitosamente.

      Copiar su clave pública de forma manual

      Si no dispone de acceso SSH con contraseña a su servidor, deberá completar el proceso anterior de forma manual.

      El contenido de su archivo id_rsa.pub deberá agregarse a un archivo en ~/.ssh/authorized_keys en su máquina remota de alguna forma.

      Para mostrar el contenido de su clave id_rsa.pub, escriba esto en su computadora local:

      cat ~/.ssh/id_rsa.pub
      

      Verá el contenido de la clave, que debería tener un aspecto similar a este:

      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test
      

      Acceda a su host remoto usando el método que esté a su disposición. Por ejemplo, si su servidor es un Droplet de DigitalOcean, puede iniciar sesión usando la consola web del panel de control:

      Acceso a la consola de DigitalOcean

      Una vez que tenga acceso a su cuenta en el servidor remoto, debe asegurarse de que el directorio ~/.ssh haya sido creado. Con este comando se creará el directorio, si es necesario. Si este último ya existe, no se creará:

      mkdir -p ~/.ssh
      

      Ahora, podrá crear o modificar el archivo authorized_keys dentro de este directorio. Puede agregar el contenido de su archivo id_rsa.pub al final del archivo authorized_keys y, si es necesario, crearlo usando el siguiente comando:

      echo public_key_string >> ~/.ssh/authorized_keys
      

      En el comando anterior, reemplace public_key_string por el resultado del comando cat ~/.ssh/id_rsa.pub que ejecutó en su sistema local. Debería iniciar con ssh-rsa AAAA....

      Si esto funciona, puede continuar con la autenticación sin contraseña.

      Autenticación en su servidor con claves SSH

      Si completó con éxito uno de los procedimientos anteriores, debería poder iniciar sesión en el host remoto sin la contraseña de la cuenta remota.

      El proceso básico es el mismo:

      ssh username@remote_host
      

      Si es la primera vez que establece conexión con este host (si empleó el último método anterior), es posible que vea algo como esto:

      The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
      ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
      Are you sure you want to continue connecting (yes/no)? yes
      

      Esto solo significa que su computadora local no reconoce el host remoto. Escriba “yes” y presione ENTER para continuar.

      Si no proporcionó una frase de contraseña para su clave privada, se iniciará sesión de inmediato. Si proporcionó una frase de contraseña para la clave privada al crearla, se le solicitará que la introduzca ahora. A continuación, se debería generar una nueva sesión de shell con la cuenta en el sistema remoto.

      Si lo realiza con éxito, continúe para averiguar cómo bloquear el servidor.

      Desactivar la autenticación por contraseña en el servidor

      Si pudo iniciar sesión en su cuenta usando SSH sin una contraseña, habrá configurado con éxito la autenticación basada en claves de SSH para su cuenta. Sin embargo, su mecanismo de autenticación basado en contraseña sigue activo. Esto significa que su servidor sigue expuesto a ataques de fuerza bruta.

      Antes de completar los pasos de esta sección, asegúrese de tener configurada la autenticación basada en claves SSH para la cuenta root en este servidor o, preferiblemente, la autenticación basada en clave SSH para una cuenta no root en este servidor con acceso sudo. Con este paso, se bloquearán los inicios de sesión basados en contraseñas. Por lo tanto, es fundamental que se asegure de que aún podrá obtener acceso administrativo.

      Una vez que se cumplan las condiciones anteriores, inicie sesión en su servidor remoto con claves SSH, ya sea como root o con una cuenta con privilegios sudo. Abra el archivo de configuración del demonio SSH:

      sudo nano /etc/ssh/sshd_config
      

      Dentro del archivo, busque una directiva llamada PasswordAuthentication. Puede insertar comentarios sobre esto. Elimine los comentarios de la línea y fije el valor en “no”. Esto inhabilitará su capacidad de iniciar sesión a través de SSH usando contraseñas de cuenta:

      PasswordAuthentication no
      

      Guarde y cierre el archivo cuando termine. Para implementar realmente los cambios que acabamos de realizar, debe reiniciar el servicio.

      En las máquinas Ubuntu o Debian, puede emitir este comando:

      sudo service ssh restart
      

      En las máquinas CentOS/Fedora, el demonio se llama sshd:

      sudo service sshd restart
      

      Después de completar este paso, ha trasladado correctamente a su demonio SHH para que responda únicamente a claves SSH.

      Conclusión

      De esta manera, la autenticación basada en claves SSH debería quedar configurada y funcionando en su servidor, lo que le permitirá iniciar sesión sin proporcionar una contraseña de cuenta. Desde aquí, hay muchas direcciones a las que puede dirigirte. Si desea obtener más información sobre cómo trabajar con SSH, consulte nuestra Guía de aspectos básicos de SSH.



      Source link

      Cómo añadir autenticación a su aplicación con Flask-Login


      Introducción

      Permitir a los usuarios iniciar sesión en su aplicación es una de las funciones más frecuentes que añadirá a su aplicación web. Este artículo explicará cómo añadir autenticación a su aplicación Flask con el paquete Flask-Login.

      Gif animado de la aplicación Flask y cuadro de inicio de sesión

      Crearemos algunas páginas de registro e inicio de sesión que permiten a los usuarios iniciar sesión y acceder a páginas protegidas que los usuarios que no hayan iniciado sesión no pueden ver. Obtendremos información del modelo de usuario y la mostraremos en nuestras páginas protegidas cuando el usuario inicie sesión para simular el aspecto que tendrá un perfil.

      En este artículo, explicaremos lo siguiente:

      • Usar la biblioteca de Flask-Login para la administración de las sesiones
      • Usar la utilidad Flask integrada para autenticar contraseñas
      • Añadir páginas protegidas a nuestra aplicación solo para los usuarios con sesión iniciada
      • Usar Flask-SQLAlchemy para crear un modelo de usuario
      • Crear formularios de registro e inicio de sesión para que nuestros usuarios creen cuentas e inicien sesión
      • Devolver mensajes intermitentes de error a los usuarios cuando algo falle
      • Usar la información de la cuenta del usuario para mostrarla en la página de perfil

      El código fuente para este proyecto está disponible en GitHub.

      Requisitos previos

      Para completar este tutorial, necesitará lo siguiente:

      Nuestra aplicación usará el patrón de fábrica de aplicación Flask con modelos. Tendremos un modelo para gestionar todo lo relacionado con la autenticación, y otro para nuestras rutas regulares, que incluyen el índice y la página de perfil protegida. En una aplicación real, puede desglosar la funcionalidad de cualquier forma que quiera, pero la solución explicada aquí funcionará bien para este tutorial.

      Aquí, tiene un diagrama que muestra cómo se verá la estructura de archivos de su proyecto una vez que haya completado el tutorial:

      .
      └── flask_auth_app
          └── project
              ├── __init__.py       # setup our app
              ├── auth.py           # the auth routes for our app
              ├── db.sqlite         # our database
              ├── main.py           # the non-auth routes for our app
              ├── models.py         # our user model
              └── templates
                  ├── base.html     # contains common layout and links
                  ├── index.html    # show the home page
                  ├── login.html    # show the login form
                  ├── profile.html  # show the profile page
                  └── signup.html   # show the signup form
      

      A medida que avancemos en el tutorial, crearemos estos directorios y archivos.

      Paso 1: Instalar paquetes

      Estos son los tres paquetes principales que necesitamos para nuestro proyecto:

      • Flask
      • Flask-Login: para administrar las sesiones del usuario tras la autenticación
      • Flask-SQLAlchemy: para representar el modelo de usuario y la interfaz con nuestra base de datos

      Usaremos SQLite para evitar tener que instalar dependencias adicionales para la base de datos.

      Primero, empezaremos por crear el directorio del proyecto:

      A continuación, debemos navegar al directorio del proyecto:

      Querrá crear un entorno Python si no tiene uno. Dependiendo de cómo se instaló Python en su equipo, sus comandos tendrán un aspecto similar a:

      • python3 -m venv auth
      • source auth/bin/activate

      Nota: Puede consultar el tutorial relevante a su entorno local para configurar venv.

      Ejecute los siguientes comandos desde su entorno virtual para instalar los paquetes necesarios:

      • pip install flask flask-sqlalchemy flask-login

      Ahora que instaló los paquetes, está listo para crear el principal archivo de la aplicación.

      Paso 2: Crear el archivo principal de la aplicación

      Empezaremos creando un directorio project:

      El primer archivo en el que trabajaremos será el archivo __init__.py para nuestro proyecto:

      Este archivo tendrá la función de crear nuestra aplicación, que iniciará la base de datos y registrará nuestros modelos. En este momento, esto no hará mucho, pero será necesario para el resto de nuestra aplicación. Debemos iniciar SQLAlchemy, establecer algunos valores de configuración y registrar nuestros modelos aquí.

      project/__init__.py

      from flask import Flask
      from flask_sqlalchemy import SQLAlchemy
      
      # init SQLAlchemy so we can use it later in our models
      db = SQLAlchemy()
      
      def create_app():
          app = Flask(__name__)
      
          app.config['SECRET_KEY'] = 'secret-key-goes-here'
          app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
      
          db.init_app(app)
      
          # blueprint for auth routes in our app
          from .auth import auth as auth_blueprint
          app.register_blueprint(auth_blueprint)
      
          # blueprint for non-auth parts of app
          from .main import main as main_blueprint
          app.register_blueprint(main_blueprint)
      
          return app
      

      Ahora que tenemos el archivo principal de la aplicación, podemos comenzar a añadir nuestras rutas.

      Paso 3: Añadir rutas

      Para nuestras rutas, usaremos dos modelos. Para nuestro modelo principal, tendremos una página principal (/) y una página de perfil (/profile) para cuando iniciemos sesión. Si el usuario intenta acceder a la página de perfil sin iniciar sesión, se lo enviará a la ruta de inicio de sesión.

      Para nuestro modelo de autenticación, tendremos rutas para recuperar la página de inicio de sesión (/login) y la página de registro (/sign-up). También tendremos rutas para gestionar las solicitudes POST desde ambas rutas. Finalmente, tendremos una ruta para cerrar sesión (/logout) para cerrar la sesión de un usuario activo.

      Por el momento, definiremos login, signup y logout con retornos simples. Los repasaremos más adelante y los actualizaremos con la funcionalidad deseada.

      Primero, cree main.py para su main_blueprint:

      project/main.py

      from flask import Blueprint
      from . import db
      
      main = Blueprint('main', __name__)
      
      @main.route('/')
      def index():
          return 'Index'
      
      @main.route('/profile')
      def profile():
          return 'Profile'
      

      A continuación, cree auth.py para su auth_blueprint:

      project/auth.py

      from flask import Blueprint
      from . import db
      
      auth = Blueprint('auth', __name__)
      
      @auth.route('/login')
      def login():
          return 'Login'
      
      @auth.route('/signup')
      def signup():
          return 'Signup'
      
      @auth.route('/logout')
      def logout():
          return 'Logout'
      

      En un terminal, puede configurar los valores FLASK_APP y FLASK_DEBUG:

      • export FLASK_APP=project
      • export FLASK_DEBUG=1

      La variable de entorno FLASK_APP indica a Flask cómo cargar la aplicación. Debería apuntar hacia donde está create_app. Para nuestros fines, apuntaremos al directorio project.

      La variable de entorno FLASK_DEBUG se habilita configurándola en 1. Esto habilitará un depurador que mostrará los errores de la aplicación en el navegador.

      Asegúrese de que está en el directorio flask_auth_app y, a continuación, ejecute el proyecto:

      Ahora, en un navegador web, debería poder navegar a las cinco URL posibles y ver el texto devuelto que se definió en auth.py y main.py.

      Por ejemplo, visitar localhost:5000/profile muestra: Profile:

      Captura de pantalla del proyecto en el puerto localhost 5000 en el navegador

      Ahora que ya verificamos que nuestras rutas se comportan como se espera, podemos crear las plantillas.

      Paso 4: Crear plantillas

      Ahora crearemos las plantillas usadas en nuestra aplicación. Este es el primer paso antes de poder implementar la funcionalidad real de inicio de sesión. Nuestra aplicación usará cuatro plantillas:

      • index.html
      • profile.html
      • login.html
      • signup.html

      También tendremos una plantilla base que tendrá un código común para cada una de las páginas. En este caso, la plantilla base tendrá enlaces de navegación y el diseño general de la página. Vamos a crearlas ahora.

      Primero, cree un directorio templates en el directorio project:

      • mkdir -p project/templates

      A continuación, cree base.html:

      • nano project/templates/base.html

      A continuación, añada el siguiente código al archivo base.html:

      project/templates/base.html

      <!DOCTYPE html>
      <html>
      
      <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>Flask Auth Example</title>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css" />
      </head>
      
      <body>
          <section class="hero is-primary is-fullheight">
      
              <div class="hero-head">
                  <nav class="navbar">
                      <div class="container">
      
                          <div id="navbarMenuHeroA" class="navbar-menu">
                              <div class="navbar-end">
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.index') }}" class="navbar-item">
                                      Home
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.profile') }}" class="navbar-item">
                                      Profile
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}" class="navbar-item">
                                      Login
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.signup') }}" class="navbar-item">
                                      Sign Up
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.logout') }}" class="navbar-item">
                                      Logout
                                  </a>
                              </div>
                          </div>
                      </div>
                  </nav>
              </div>
      
              <div class="hero-body">
                  <div class="container has-text-centered">
                     {% block content %}
                     {% endblock %}
                  </div>
              </div>
          </section>
      </body>
      
      </html>
      

      Este código creará una serie de enlaces de menú a cada página de la aplicación y un área donde aparecerá el contenido.

      Nota: En segundo plano, estamos usando Bulma para gestionar el estilo y la distribución. Para aprender más sobre Bluma, considere leer la documentación oficial de Bulma.

      A continuación, cree templates/index.html:

      • nano project/templates/index.html

      Añada el siguiente código al archivo recién creado para añadir contenido a la página:

      project/templates/index.html

      {% extends "base.html" %}
      
      {% block content %}
      <h1 class="title">
        Flask Login Example
      </h1>
      <h2 class="subtitle">
        Easy authentication and authorization in Flask.
      </h2>
      {% endblock %}
      

      Este código creará una página de índice básica con un título y un subtítulo.

      A continuación, cree templates/login.html:

      • nano project/templates/login.html

      Este código genera una página de inicio con campos para Correo electrónico y Contraseña. También hay una casilla de verificación para “recordar” una sesión iniciada.

      project/templates/login.html

      {% extends "base.html" %}
      
      {% block content %}
      <div class="column is-4 is-offset-4">
          <h3 class="title">Login</h3>
          <div class="box">
              <form method="POST" action="/login">
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="email" name="email" placeholder="Your Email" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="password" name="password" placeholder="Your Password">
                      </div>
                  </div>
                  <div class="field">
                      <label class="checkbox">
                          <input type="checkbox">
                          Remember me
                      </label>
                  </div>
                  <button class="button is-block is-info is-large is-fullwidth">Login</button>
              </form>
          </div>
      </div>
      {% endblock %}
      

      A continuación, cree templates/signup.html:

      • nano project/templates/signup.html

      Añada el siguiente código para crear una página de registro con campos para correo electrónico, nombre y contraseña:

      project/templates/signup.html

      {% extends "base.html" %}
      
      {% block content %}
      <div class="column is-4 is-offset-4">
          <h3 class="title">Sign Up</h3>
          <div class="box">
              <form method="POST" action="/signup">
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="email" name="email" placeholder="Email" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="text" name="name" placeholder="Name" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="password" name="password" placeholder="Password">
                      </div>
                  </div>
      
                  <button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
              </form>
          </div>
      </div>
      {% endblock %}
      

      A continuación, cree templates/profile.html:

      • nano project/templates/profile.html

      Añada este código para crear una página sencilla con un título codificado de forma rígida para darle la bienvenida a Anthony:

      project/templates/profile.html

      {% extends "base.html" %}
      
      {% block content %}
      <h1 class="title">
        Welcome, Anthony!
      </h1>
      {% endblock %}
      

      Más adelante, añadiremos un código para saludar dinámicamente a cualquier usuario.

      Una vez que haya añadido las plantillas, podremos actualizar las instrucciones de retorno en cada una de las rutas que tenemos para que devuelvan las plantillas en vez del texto.

      A continuación, actualice main.py modificando la línea de importación y las rutas para index y profile:

      project/main.py

      from flask import Blueprint, render_template
      ...
      @main.route('/')
      def index():
          return render_template('index.html')
      
      @main.route('/profile')
      def profile():
          return render_template('profile.html')
      

      Ahora, actualizará auth.py modificando la línea de importación y las rutas para login y signup:

      project/auth.py

      from flask import Blueprint, render_template
      ...
      @auth.route('/login')
      def login():
          return render_template('login.html')
      
      @auth.route('/signup')
      def signup():
          return render_template('signup.html')
      

      Una vez que haya realizado estos cambios, así lucirá la página de registro si navega a /sign-up:

      Página de registro en /signup

      También debería poder ver las páginas para /, /login y /profile.

      No trabajaremos con /logout por ahora porque no mostrará una plantilla cuando esté listo.

      Paso 5: Crear modelos de usuario

      Nuestro modelo de usuario representa qué significa para nuestra aplicación tener un usuario. Tendremos campos para una dirección de correo electrónico, contraseña y nombre. En su aplicación, puede decidir que quiere guardar mucha más información por usuario. Puede añadir cosas como fecha de nacimiento, perfil, imagen, ubicación o cualquier preferencia del usuario.

      Los modelos creados en Flask-SQLAlchemy se representan mediante clases y, luego, se trasladan a tablas en una base de datos. Los atributos de esas clases se convierten en columnas para esas tablas.

      Ahora crearemos ese modelo de usuario:

      Este código crea un modelo de usuario con columnas para id, email, password y name:

      project/models.py

      from . import db
      
      class User(db.Model):
          id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
          email = db.Column(db.String(100), unique=True)
          password = db.Column(db.String(100))
          name = db.Column(db.String(1000))
      

      Ahora que creó un modelo de usuario, puede configurar su base de datos.

      Paso 6: Configurar la base de datos

      Como se indicó en los requisitos previos, usaremos una base de datos SQLite. Podríamos crear una base de datos SQLite por nuestra cuenta, pero dejemos que Flask-SQLAlchemy lo haga por nosotros. Ya tenemos la ruta de la base de datos especificada en el archivo __init__.py, así que solo necesitamos indicar a Flask-SQLAlchemy que cree la base de datos en el REPL de Python.

      Si detiene su aplicación y abre un REPL de Python, podemos crear la base de datos usando el método create_all en el objeto db. Asegúrese de que aún está en el entorno virtual y en el directorio flask_auth_app.

      • from project import db, create_app
      • db.create_all(app=create_app()) # pass the create_app result so Flask-SQLAlchemy gets the configuration.

      Nota: Si el uso del intérprete de Python es nuevo para usted, puede consultar la documentación oficial.

      Ahora, verá un archivo db.sqlite en el directorio de su proyecto. Esta base de datos contendrá nuestra tabla de usuario.

      Paso 7: Configurar la función de autorización

      Para nuestra función de registro, tomaremos los datos que escriba el usuario en el formulario y los añadiremos a nuestra base de datos. Antes de añadirlo, debemos asegurarnos de que el usuario no existe ya en la base de datos. Si no es así, debemos asegurarnos de autenticar la contraseña antes de colocarla en la base de datos, porque no queremos que nuestras contraseñas se almacenen en archivo de texto.

      Empezaremos por añadir una segunda función para gestionar los datos del formulario POST. En esta función, recopilaremos primero los datos ingresados por el usuario.

      Cree la función y añada una redirección en la parte inferior. Esto proporcionará una experiencia de usuario de un registro correcto y se lo redirigirá a la página de inicio de sesión.

      Actualice auth.py modificando la línea de importación e implementando signup_post:

      project/auth.py

      from flask import Blueprint, render_template, redirect, url_for
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          # code to validate and add user to database goes here
          return redirect(url_for('auth.login'))
      

      Ahora, añadiremos el resto del código necesario para registrar a un usuario.

      Para comenzar, tendremos que usar el objeto de solicitud para obtener los datos del formulario.

      Continúe para actualizar auth.py añadiendo importaciones e implementando signup_post:

      auth.py

      from flask import Blueprint, render_template, redirect, url_for, request
      from werkzeug.security import generate_password_hash, check_password_hash
      from .models import User
      from . import db
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          email = request.form.get('email')
          name = request.form.get('name')
          password = request.form.get('password')
      
          user = User.query.filter_by(email=email).first() # if this returns a user, then the email already exists in database
      
          if user: # if a user is found, we want to redirect back to signup page so user can try again
              return redirect(url_for('auth.signup'))
      
          # create a new user with the form data. Hash the password so the plaintext version isn't saved.
          new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
      
          # add the new user to the database
          db.session.add(new_user)
          db.session.commit()
      
          return redirect(url_for('auth.login'))
      

      Nota: El almacenamiento de contraseñas en archivos de texto se considera una mala práctica de seguridad. Normalmente, querrá usar un algoritmo de autenticación complejo y una sal de contraseña para proteger las contraseñas.

      Paso 8: Probar el método de registro

      Ahora que tenemos el método de registro, deberíamos poder crear un nuevo usuario. Use el formulario para crear un usuario.

      Hay dos formas de verificar si el registro funcionó: puede usar un visor de base de datos para ver la fila que se añadió a su tabla o puede intentar registrarse con la misma dirección de correo de nuevo y, si recibe un error, sabe que el primer correo electrónico se guardó correctamente. Hagamos eso.

      Podemos añadir un código para permitir al usuario saber que el correo electrónico ya existe e indicarle que vaya a la página de inicio de sesión. Al invocar la función flash, enviaremos un mensaje a la siguiente solicitud que, en este caso, es la redirección. La página a la que llegamos tendrá acceso a ese mensaje en la plantilla.

      Primero, añadimos flash antes de redirigir a nuestra página de registro.

      project/auth.py

      from flask import Blueprint, render_template, redirect, url_for, request, flash
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          ...
          if user: # if a user is found, we want to redirect back to signup page so user can try again
              flash('Email address already exists')
              return redirect(url_for('auth.signup'))
      

      Para obtener el mensaje intermitente en la plantilla, podemos añadir este código sobre el formulario. Esto mostrará el mensaje directamente arriba del formulario.

      project/templates/signup.html

      ...
      {% with messages = get_flashed_messages() %}
      {% if messages %}
          <div class="notification is-danger">
              {{ messages[0] }}. Go to <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}">login page</a>.
          </div>
      {% endif %}
      {% endwith %}
      <form method="POST" action="/signup">
      

      Cuadro de registro mostrando el mensaje

      Paso 9: Añadir el método de inicio de sesión

      El método de inicio de sesión es similar a la función de registro porque tomaremos la información del usuario y haremos algo con ella. En este caso, compararemos la dirección de correo electrónico introducida para ver si está en la base de datos. Si es así, probaremos la contraseña proporcionada por el usuario autenticando la contraseña que el usuario introduce y comparándola con la contraseña autenticada en la base de datos. Sabemos que el usuario introdujo la contraseña correcta cuando ambas contraseñas autenticadas coinciden.

      Una vez que el usuario haya pasado la comprobación de contraseña, sabemos que tiene las credenciales correctas y puede iniciar sesión usando Flask-Login. Al invocar login_user, Flask-Login creará una sesión para ese usuario que persistirá mientras el usuario permanezca con sesión iniciada, lo que permitirá al usuario ver las páginas protegidas.

      Podemos comenzar con una nueva ruta para gestionar los datos que ya fueron procesados por POST. Redirigiremos a la página de perfil cuando el usuario inicie sesión correctamente.

      project/auth.py

      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          # login code goes here
          return redirect(url_for('main.profile'))
      

      Ahora, debemos verificar si el usuario tiene las credenciales correctas:

      project/auth.py

      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          email = request.form.get('email')
          password = request.form.get('password')
          remember = True if request.form.get('remember') else False
      
          user = User.query.filter_by(email=email).first()
      
          # check if the user actually exists
          # take the user-supplied password, hash it, and compare it to the hashed password in the database
          if not user or not check_password_hash(user.password, password):
              flash('Please check your login details and try again.')
              return redirect(url_for('auth.login')) # if the user doesn't exist or password is wrong, reload the page
      
          # if the above check passes, then we know the user has the right credentials
          return redirect(url_for('main.profile'))
      

      Añadiremos el bloque en la plantilla para que el usuario pueda ver el mensaje intermitente. Al igual que con el formulario de registro, añadiremos el potencial mensaje de error directamente arriba del formulario:

      project/templates/login.html

      ...
      {% with messages = get_flashed_messages() %}
      {% if messages %}
          <div class="notification is-danger">
              {{ messages[0] }}
          </div>
      {% endif %}
      {% endwith %}
      <form method="POST" action="/login">
      

      Ahora podemos decir que un usuario inició sesión correctamente, pero no tenemos nada para registrar la información del usuario. Aquí es donde traemos a Flask-Login para gestionar las sesiones de usuario.

      Antes de comenzar, necesitamos algunas cosas para que Flask-Login funcione. Comience añadiendo UserMixin a su modelo de usuario. El UserMixin añadirá atributos de Flask-Login al modelo de forma que Flask-Login pueda trabajar con él.

      models.py

      from flask_login import UserMixin
      from . import db
      
      class User(UserMixin, db.Model):
          id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
          email = db.Column(db.String(100), unique=True)
          password = db.Column(db.String(100))
          name = db.Column(db.String(1000))
      

      A continuación, necesitamos especificar nuestro cargador de usuario. Un cargador de usuario indica a Flask-Login cómo encontrar un usuario específico a partir del identificador que se almacena en su cookie de sesión. Podemos añadir esto en nuestra función create_app junto con el código init para Flask-Login:

      project/__init__.py

      ...
      from flask_login import LoginManager
      ...
      def create_app():
          ...
          db.init_app(app)
      
          login_manager = LoginManager()
          login_manager.login_view = 'auth.login'
          login_manager.init_app(app)
      
          from .models import User
      
          @login_manager.user_loader
          def load_user(user_id):
              # since the user_id is just the primary key of our user table, use it in the query for the user
              return User.query.get(int(user_id))
      

      Finalmente, podemos añadir la función login_user justo antes de redirigir a la página de perfil para crear la sesión:

      project/auth.py

      from flask_login import login_user
      from .models import User
      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          ...
          # if the above check passes, then we know the user has the right credentials
          login_user(user, remember=remember)
          return redirect(url_for('main.profile'))
      

      Con la configuración de Flask-Login, podemos usar la ruta /login. Cuando todo esté listo, verá la página de perfil.

      Página de perfil con

      Paso 10: Proteger las páginas

      Si su nombre no es Anthony, verá que el nombre está mal. Lo que queremos es que el perfil muestre el nombre en la base de datos. Primero debemos proteger la página y, luego, acceder a los datos del usuario para obtener el nombre.

      Para proteger una página cuando se usa Flask-Login, añadiremos el decorador @login_required entre la ruta y la función. Esto evitará que un usuario que no haya iniciado sesión vea la ruta. Si el usuario no inició sesión, se lo redirigirá a la página de inicio, según la configuración de Flask-Login.

      Con las rutas representadas con el decorador @login_required, tenemos la capacidad de usar el objeto current_user dentro de la función. Este current_user representa al usuario de la base de datos, y podemos acceder a todos los atributos de ese usuario con notación por puntos. Por ejemplo, current_user.email, current_user.password y current_user.name y current_user.id devolverán los valores reales almacenados en la base de datos para el usuario con sesión iniciada.

      Usaremos el nombre del usuario actual y lo enviaremos a la plantilla. Usaremos ese nombre y mostraremos su valor.

      project/main.py

      from flask_login import login_required, current_user
      ...
      @main.route('/profile')
      @login_required
      def profile():
          return render_template('profile.html', name=current_user.name)
      

      A continuación, en el archivo profile.html, actualice la página para mostrar el valor name:

      project/templates/profile.html

      ...
      <h1 class="title">
        Welcome, {{ name }}!
      </h1>
      

      Cuando vayamos a nuestra página de perfil, veremos que aparece el nombre del usuario.

      Página de bienvenida del usuario con el nombre del usuario con sesión iniciada actualmente

      Lo último que podemos hacer es actualizar la vista de cierre de sesión. Podemos invocar la función logout_user para cerrar sesión. Tenemos el decorador @login_required porque no tiene sentido que un usuario cierre una sesión que no inició en primer lugar.

      project/auth.py

      from flask_login import login_user, logout_user, login_required
      ...
      @auth.route('/logout')
      @login_required
      def logout():
          logout_user()
          return redirect(url_for('main.index'))
      

      Tras cerrar sesión e intentar ver la página del perfil, vemos que aparece un mensaje de error. Esto es porque Flask-Login muestra un mensaje intermitente para nosotros cuando el usuario no tiene permiso para acceder a una página.

      Página de inicio con un mensaje que muestra que el usuario debe iniciar sesión para acceder a la página

      Una última cosa que podemos hacer es poner declaraciones if en las plantillas para mostrar solo los enlaces relevantes al usuario. Antes de que el usuario inicie sesión, tendrá la opción de iniciar sesión o registrarse. Tras haber iniciado sesión, el usuario puede ir a su perfil o cerrar sesión:

      templates/base.html

      ...
      <div class="navbar-end">
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.index') }}" class="navbar-item">
              Home
          </a>
          {% if current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.profile') }}" class="navbar-item">
              Profile
          </a>
          {% endif %}
          {% if not current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}" class="navbar-item">
              Login
          </a>
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.signup') }}" class="navbar-item">
              Sign Up
          </a>
          {% endif %}
          {% if current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.logout') }}" class="navbar-item">
              Logout
          </a>
          {% endif %}
      </div>
      

      Página de inicio con la navegación de las páginas Principal, Inicio de sesión y Registro en la parte superior de la pantalla

      Con eso, creó correctamente su aplicación con autenticación.

      Conclusión

      Usamos Flask-Login y Flask-SQLAlchemy para crear un sistema de inicio de sesión para nuestra aplicación. Vimos cómo autenticar a un usuario creando primero un modelo de usuario y almacenando la información del usuario. A continuación, tuvimos que verificar que la contraseña del usuario fuera correcta autenticando la contraseña desde el formulario y comparándola con la almacenada en la base de datos. Finalmente, añadimos autorización a nuestra aplicación usando el decorador @login_required en una página de perfil de forma que solo los usuarios con sesión iniciada puedan verla.

      Lo que creamos en este tutorial será suficiente para aplicaciones más pequeñas pero, si quiere tener más funcionalidad desde el principio, quizá desee considerar usar las bibliotecas Flask-User o Flask-Security, que se desarrollaron a partir de la biblioteca Flask-Login.



      Source link

      Cómo instalar y configurar SimpleSAMLphp para la autenticación SAML en Ubuntu 18.04


      Introducción

      SimpleSAMLphp es una aplicación de autenticación PHP de código abierto que ofrece soporte para SAML 2.0 como Proveedor de servicios (SP) o Proveedor de identidad (IdP).

      SAML (Security Assertion Markup Language) es un mecanismo de comunicación seguro basado en XML para intercambiar datos de autenticación y autorización entre organizaciones y aplicaciones. Se utiliza a menudo para implementar SSO web (autenticación única). Esto elimina la necesidad de mantener múltiples credenciales de autenticación en múltiples organizaciones. O dicho de otro modo, puede usar una identidad, como un nombre de usuario y contraseña, para acceder a múltiples aplicaciones.

      Una instancia de SimpleSAMLphp se conecta con una fuente de autenticación, que es un proveedor de identidad como LDAP o una base de datos de usuarios. Autentica a los usuarios contra esta fuente de autenticación antes de conceder acceso a los recursos disponibles de los Proveedores de servicios vinculados.

      A través de este tutorial, instalará SimpleSamlPHP y lo configurará para que utilice una base de datos de MySQL como fuente de autenticación. Almacenará los usuarios y las contraseñas cifradas en la base de datos MySQL y probará que puede utilizar esos usuarios para iniciar sesión.

      Requisitos previos

      Paso 1: Descargar e instalar SimpleSAMLphp

      Es necesario realizar un par de pasos para instalar SimpleSAMLphp. Tenemos que descargar el software en sí mismo así como algunos componentes y requisitos previos adicionales. También deberemos realizar algunos cambios en la configuración de nuestro host virtual.

      Inicie sesión en su servidor si no lo ha hecho aún.

      Descargue SimpleSAMLphp desde el sitio web del proyecto. SimpleSAMLphp siempre enlaza la última versión estable de su software a la misma URL. Esto significa que podemos obtener la última versión escribiendo esto:

      • wget https://simplesamlphp.org/download?latest

      Con esto, se descargará un archivo comprimido llamado download?latest que contiene SimpleSAMLphp. Extraiga el contenido con el comando tar:

      Los archivos se extraerán a un directorio nuevo con la etiqueta simplesamlphp-1.x.y​​​, donde x.y es el número de la versión actual. Utilice el comando ls para identificar el archivo:

      Verá el nombre del archivo:

      Ouptut

      simplesamlphp-1.18.5

      Ahora, copie el contenido del directorio a /var/simplesamlphp usando el comando cp. Asegúrese de sustituir el número de versión con la versión que tenga:

      • sudo cp -a simplesamlphp-1.x.y/. /var/simplesamlphp/

      El conmutador -a garantiza que los permisos del archivo se copien junto con los archivos y carpetas. El punto al final del archivo de origen garantiza que todo en el directorio de origen, incluyendo los archivos ocultos, se copian al directorio de destino.

      Nota: Si necesita instalar los archivos en una ubicación diferente, deberá actualizar varios archivos. Consulte la documentación de instalación oficial de SimpleSAMLphp para ver los detalles específicos.

      SimpleSAMLphp necesita algunos paquetes de software adicionales, como las extensiones de PHP para trabajar con XML, cadenas de bytes múltiples, curl y LDAP. También necesita memcached. Instale estos usando su administrador de paquetes.

      Primero, actualice su lista de paquetes:

      A continuación, instale los paquetes:

      • sudo apt install php-xml php-mbstring php-curl php-memcache php-ldap memcached

      Una vez que se complete la instalación, reinicie Apache para activar las nuevas extensiones de PHP:

      • sudo systemctl restart apache2

      Ahora que SimpleSAMLphp está instalado, configuraremos Apache para presentar los archivos.

      Paso 2: Configurar Apache para presentar SimpleSAMLphp

      Ya ha configurado un dominio y apuntado a este servidor, y ha configurado un host virtual para que funcione con HTTPS protegiendo Apache con Let´s Encrypt. Usaremos eso para presentar SimpleSAMLphp.

      El único directorio de SimpleSAMLphp que debe estar visible para la web es /var/simplesamlphp/www. Para exponerlo a la Web, edite el archivo de configuración de host virtual SSL de Apache para su dominio.

      Si su archivo de configuración de host virtual se llama your_domain.conf, Let´s Encrypt creó un nuevo archivo de configuración llamado your_domain-le-ssl.conf que gestiona las solicitudes HTTPS para su dominio. Abra el archivo de configuración SSL con el siguiente comando para editar el archivo. Asegúrese de sustituir your_domain por el nombre real del archivo:

      • sudo nano /etc/apache2/sites-available/your_domain-le-ssl.conf

      El archivo debería tener el siguiente aspecto, pero el archivo real puede tener comentarios más descriptivos:

      your_domain-le-ssl.conf’>/etc/apache2/sites-available/your_domain-le-ssl.conf

      <IfModule mod_ssl.c>
      <VirtualHost *:443>
              ServerName your_domain
      
              ServerAdmin webmaster@localhost
              DocumentRoot /var/www/html
      
              ErrorLog ${APACHE_LOG_DIR}/error.log
              CustomLog ${APACHE_LOG_DIR}/access.log combined
      
      SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem
      Include /etc/letsencrypt/options-ssl-apache.conf
      </VirtualHost>
      </IfModule>
      

      La directiva ServerName aquí define el dominio base que debería coincidir con la definición de este host virtual. Este debería ser el nombre de dominio para el que configuró un certificado SSL en la sección de requisitos previos. Vamos a añadir una directiva Alias que proporciona control a SimpleSAMLphp para todas las URLs que coinciden con https://your_domain/simplesaml/*. Haga esto añadiendo la siguiente línea al archivo de configuración:

      your_domain-le-ssl.conf’>/etc/apache2/sites-available/your_domain-le-ssl.conf

      ...
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
      
        Alias /simplesaml /var/simplesamlphp/www
      
      ...
      

      Esto significa que domain_name/simplesaml/* se dirigirán al directorio /var/simplesamlphp/www que proporciona el control a SimpleSAMLphp.

      A continuación, concederemos acceso al directorio /var/simplesamlphp/www especificando un control de acceso Require all granted para el mismo. Esto hará que el servicio SimpleSAMLphp sea accesible en la Web. Haga esto añadiendo lo siguiente al archivo de configuración:

      your_domain-le-ssl.conf’>/etc/apache2/sites-available/your_domain-le-ssl.conf

      ...
        Alias /simplesaml /var/simplesamlphp/www
        <Directory /var/simplesamlphp/www/>
            Require all granted
        </Directory>
      ...
      

      Guarde y cierre el archivo. Reinicie Apache para implementar los cambios:

      • sudo systemctl restart apache2

      Ahora que Apache está configurado para presentar archivos de aplicación, vamos a configurar SimpleSAMLphp.

      Paso 3: Configurar SimpleSAMLphp

      A continuación, debemos realizar varios cambios en la configuración principal de SimpleSAMLphp ubicada en /var/simplesamlphp/config/config.php. Abra el archivo en su editor:

      • nano /var/simplesamlphp/config/config.php

      Configure la contraseña del administrador buscando la línea 'auth.adminpassword' y sustituyendo el valor predeterminado de 123 por una contraseña más segura. Esta contraseña le permite acceder a algunas de las páginas en su interfaz web de la instalación de SimpleSAMLphp:

      /var/simplesamlphp/config/config.php

      . . .
      'auth.adminpassword'        => 'your_admin_password',
      . . .
      

      A continuación, establezca un salt secreto, que debería ser una cadena de caracteres generada aleatoriamente. Algunas partes de SimpleSAMLphp utilizan este valor sal para crear hashes que ofrezcan seguridad a nivel criptográfico. Obtendrá errores si el salt no se cambia desde el valor predeterminado.

      Puede usar la función rand de OpenSSL para generar una cadena aleatoria que pueda usar como su cadena de valores sal secreta. Abra un nuevo terminal, conecte de nuevo con su servidor y ejecute el siguiente comando para generar esta cadena:

      La opción -base64 32 garantiza una cadena Base64 codificada de 32 caracteres.

      A continuación, en el archivo de configuración, localice la entrada 'secretsalt' y sustituya defaultsecretsalt por la cadena que generó:

      /var/simplesamlphp/config/config.php

      . . .
      'secretsalt' => 'your_generated_salt',
      . . .
      

      Luego establezca la información de contacto técnico. Esta información estará disponible en los metadatos generados y SimpleSAMLphp enviará informes de error generados automáticamente a la dirección de correo electrónico que especifique. Localice la siguiente sección:

      /var/simplesamlphp/config/config.php

      . . .
      'technicalcontact_name'     => 'Administrator',
      'technicalcontact_email'    => 'na@example.org',
      . . .
      

      Sustituya Administrator y na@example.org por los valores apropiados.

      A continuación, configure la zona horaria que desea usar. Localice esta sección:

      /var/simplesamlphp/config/config.php

      . . .
      'timezone' => null,
      . . .
      

      Sustituya null por una zona horaria preferida de esta lista de zonas horarias para PHP. Asegúrese de poner el valor entre comillas:

      /var/simplesamlphp/config/config.php

      . . .
      'timezone' => 'America/New_York',
      . . .
      

      Guarde y cierre el archivo. Con esto, debería poder acceder al sitio en su navegador visitando https://your_domain/simplesaml. Verá la siguiente pantalla en su navegador:

      Interfaz web de simplesaml

      Para asegurarse de que su instalación de PHP cumpla con todos los requisitos para que SimpleSAMLphp se ejecute sin problemas, seleccione la pestaña Configuration y haga clic en el enlace Login as administrator. A continuación utilice la contraseña del administrador que configuró en el archivo de configuración en el Paso 3.

      Una vez que inicie sesión, verá una lista de las extensiones necesarias y opcionales de PHP que utiliza SimpleSAMLphp. Compruebe que haya instalado todas las extensiones, a excepción de predis/predis:

      Todas las extensiones instaladas

      Si falta algún componente necesario, revise este tutorial e instale los componentes que faltan antes de continuar.

      También verá un enlace que dice Sanity check de su configuración de SimpleSAMLphp. Haga clic en este enlace para obtener una lista de los controles aplicados a su configuración para ver si se realizan correctamente.

      Ahora configuraremos una fuente de autenticación para SimpleSAMLphp.

      Paso 4: Configurar la fuente de autenticación

      Ahora que tenemos SimpleSAMLphp instalado y configurado, vamos a configurar una fuente de autenticación para poder autenticar a los usuarios. Usaremos una base de datos MySQL a fin de almacenar una lista de nombres de usuarios y contraseñas con los que se realizará la autenticación.

      Para comenzar, inicie sesión en la cuenta root de MySQL:

      Se le solicitará la contraseña root de la cuenta de MySQL. Facilítela para continuar.

      A continuación, cree una base de datos que funcionará como la fuente de autenticación. La llamaremos auth. Puede llamarla como prefiera:

      • CREATE DATABASE auth DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

      Ahora, crearemos un usuario de MySQL independiente para que funcione exclusivamente en nuestra base de datos auth. Desde un punto de vista de la administración y la seguridad, se recomienda crear bases de datos y cuentas de una función. Llamaremos a nuestro usuario authuser. Ejecute el siguiente comando para crear el usuario, configurar una contraseña y conceder a este acceso a nuestra base de datos auth. Recuerde elegir una contraseña segura para el usuario de su nueva base de datos:

      • GRANT ALL ON auth.* TO 'authuser'@'localhost' IDENTIFIED BY 'your_mysql_auth_user_password';

      Ahora, cree una tabla users que constará de dos campos: username y password. Para mayor seguridad, vamos a usar la función MySQL AES_ENCRYPT() para cifrar la cadena de contraseña de forma que no almacenemos las contraseñas en texto sin formato. Esta función cifra una cadena y muestra una cadena binaria.

      • CREATE TABLE auth.users(username VARCHAR(30), password VARBINARY(30));

      A continuación, inserte tres usuarios en la tabla recién creada. Aquí es donde usaremos la función AES_ENCRYPT() para cifrar los valores del campo de contraseña. Debe proporcionar una cadena que se utilice como clave de cifrado. Asegúrese de sustituir esta cadena con su propia cadena, que puede ser cualquier cadena que desee, siempre y cuando sea compleja.

      • INSERT INTO auth.users(username, password) VALUES
      • ('user1', AES_ENCRYPT('user1pass','your_secret_key')),
      • ('user2', AES_ENCRYPT('user2pass','your_secret_key')),
      • ('user3', AES_ENCRYPT('user3pass','your_secret_key'));

      Utilice la misma clave para cada usuario y asegúrese de recordar la clave para que pueda usarla de nuevo para crear usuarios adicionales en el futuro. También usará esta clave secreta en la configuración de SimpleSAMLphp para poder descifrar las contraseñas y compararlas con las que introduzca el usuario.

      Debemos eliminar los privilegios de modo que la instancia actual de MySQL registre los cambios recientes en el privilegio:

      Salga de la línea de comandos de MySQL escribiendo lo siguiente:

      Para habilitar la funcionalidad del proveedor de identidad en SimpleSAMLphp, debemos editar el archivo /var/simplesamlphp/config/config.php. Existen varias opciones disponibles pero, dado que esta guía se centra en el soporte SAML 2.0, queremos habilitar la opción enable.saml20-idp. Para hacerlo, abra /var/simplesamlphp/config/config.php y habilite el soporte SAML 2.0.

      • nano /var/simplesamlphp/config/config.php

      Localice esta sección del archivo y sustituya false por true:

      /var/simplesamlphp/config/config.php

      ...
      'enable.saml20-idp' => true,
      ...
      

      Guarde el archivo y cierre el editor.

      Ahora que tenemos habilitada la funcionalidad del proveedor de identidad, debemos indicar el módulo de autenticación que se utilizará. Debido a que disponemos de una tabla de usuarios en una base de datos de MySQL, usaremos el módulo de autenticación de SQL. Abra el archivo de configuración authsources:

      • nano /var/simplesamlphp/config/authsources.php

      Localice el siguiente bloque, que está eliminado:

      /var/simplesamlphp/config/authsources.php

      ...
          /*
          'example-sql' => array(
              'sqlauth:SQL',
              'dsn' => 'pgsql:host=sql.example.org;port=5432;dbname=simplesaml',
              'username' => 'simplesaml',
              'password' => 'secretpassword',
              'query' => 'SELECT uid, givenName, email, eduPersonPrincipalName FROM users WHERE uid = :username AND password = SHA2(CONCAT((SELECT salt FROM users WHERE uid = :username), :password),256);',
          ),
          */
      ...
      

      Este código define una conexión con la base de datos y una consulta que SimpleSAMLphp puede usar para buscar un usuario en una tabla de base de datos llamada users. Necesitamos habilitarla y cambiar la consulta para que busque un usuario desde nuestra tabla usando la función AES_DECRYPT() de MySQL. Necesitaremos proporcionar a la función AES_DECRYPT() la misma clave que usamos para cifrar las contraseñas en la consulta.

      Modifique la sección del archivo para especificar los datos de la conexión con la base de datos y la consulta:

      /var/simplesamlphp/config/authsources.php

      ...
          'example-sql' => array(
              'sqlauth:SQL',
              'dsn' => 'mysql:host=localhost;port=5432;dbname=auth',
              'username' => 'authuser',
              'password' => 'your_mysql_auth_user_password',
              'query' => 'SELECT username FROM users WHERE username = :username AND AES_DECRYPT(password,"your_secret_key") = :password',
          ),
      ...
      

      Asegúrese de colocar la clave secreta que especificó en lugar de your_secret_key.

      Guarde y cierre el archivo. Probaremos nuestro proveedor de identidad.

      Paso 5: Probar el proveedor de identidad con la Demo SAML 2.0 SP

      Puede probar la fuente de autenticación que acaba de configurar navegando a la pestaña Authentication y haciendo clic en el enlace Test configured authentication sources (Probar fuentes de autenticación configuradas). Se le presentará una lista de las fuentes de autenticación ya configuradas.

      La lista de fuentes de autenticación configuradas

      Haga clic en example-sql, ya que este es el proveedor que configuró en el paso anterior. Se mostrará una solicitud para introducir un nombre de usuario y contraseña. Introduzca cualquiera de las combinaciones de usuario y contraseña de prueba que insertó en la tabla de usuarios de MySQL. Pruebe user1 con la contraseña user1pass.

      Con un intento correcto, se le presentará la página SAML 2.0 SP Demo Example:

      La página de Demo correcta

      Si no puede iniciar sesión y sabe que la contraseña es correcta, asegúrese de usar la misma clave con la función AES_ENCRYPT() cuando creó el usuario, y con la función AES_DECRYPT() cuando buscó el usuario.

      Ahora puede integrar SimpleSAMLphp con sus propias aplicaciones siguiendo la documentación de la API de SimpleSAMLphp.

      Conclusión

      Ahora tiene la aplicación SimpleSAMLphp debidamente instalada y configurada en su VPS Ubuntu 18.04. SimpleSAMLphp también permite personalizar ampliamente la interfaz de usuario con temas. Puede consultar sus documentos sobre temas para obtener más información.



      Source link