Autenticación de doble factor con Step Functions
Tags: aws, stepfunctions
Published: 2022-03-14 17:30:06

La autenticación de doble factor lo están utilizando mucho los bancos para confirmar que somos las personas dueñas de la cuenta y no se esta realizando una suplantación para tomar nuestro dinero.

En el banco donde tengo mi cuenta de ahorros cuando, voy a realizar una transacción me solicitan que digite 4 números, estos números pueden ser enviados por SMS a mi celular o a mi correo electrónico.

Vamos a ver como podemos simular este proceso utilizando **Step Functions** de AWS.

Para este ejemplo vamos a utilizar los siguientes servicios:

**Step Functions**: Definición del flujo.
**SNS**: Envío de mensajes de texto.
**SES**: Envio de email.
**IAM**: Definición de roles

Empecemos con la configuración de **SES** para realizar el envío de nuestros correos.

1. Buscamos **SES** en el barra de búsqueda de servicios, vamos a ver una pantalla como la siguiente. Y damos click en _Create Identity_ o en _Verified identities_

![Main SES]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/main%20ses.png)

2.En la siguiente pantalla vamos a configurar el correo por el cual queremos que se envíen nuestros mensajes. Después de colocar nuestro correo damos click en _Create Identity_.

![Main SES]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/config%20email.png)

El siguiente paso es ingresar a nuestro correo y dar click en el enlace de confirmación para que el correo sea verificado y podamos enviar mensajes a través de **SES**.

**Nota**: El correo que se utiliza en este ejemplo es de _mailinator_ que es una plataforma gratuita para un buzon temporal de correo de pruebas.


![Confirmation Email]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/confirm%20email.png)

3.Lo siguiente que debemos hacer es buscar el servicio de _Step Functions_ para la creación de nuestro flujo. Ya en la pagina inicial damos click en _Create State Machine_.

![Create State Machine]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/create%20state%20machine.png)

4.En la siguiente pantalla vamos a definir cómo vamos a trabajar nuestro flujo de trabajo.

En nuestro caso vamos a seleccionar la opción del diseño visual, que es un diseñador de nuestro flujo que convierte este diseño en un texto 'JSON'. También podemos diseñar nuestro flujo escribiendo directamente el texto en formato 'JSON' o subiendo una plantilla de CloudFormation (Infraestructura como código). El tipo de flujo que utilizaremos es Standard. 

![Config State Machine]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/config%20state%20machine.png)

5.Al dar click en _Next_ vamos a ver la pantalla de inicio del diseñador del Work Flow.

![Work Flow Design]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/design%20work%20flow.png)

En la sección 1, vamos a encontrar todos los servicios que se pueden utilizar dentro del work flow de Step Functions.

En la sección 2, vamos a encontrar los tipos de flujos que podemos utilizar.

En la sección 3, vemos el work flow que estamos diseñando.

En la sección 4, vemos las opciones para el elemento (Servicio o Flujo) que este seleccionado en el momento.

6.Iniciemos con la creación del primer paso de nuestro flujo que es del tipo _Choice_. Este tipo de flujo nos sirve para definir condiciones del tipo if else, donde vamos a definir dos condiciones: que la entrada sea igual a SMS y la otra condición que sea igual a EMAIL.

![First Step]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/first%20step%20functions.png)

Ahora vamos a definir nuestras reglas.

![First Rule]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/first%20rule.png)

Para agregar la segunda regla le debemos dar click en el botón _Add new choice rule_

![Second Rule]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/second%20rule.png)

7.Después de tener definidas nuestras reglas debemos definir cuál servicio va ser ejecutado.
Iniciemos buscando el servicio de **SNS** para el envió de mensajes de texto, seleccionamos _SNS Publish_ y lo arrastramos a nuestro flujo.

![Select SNS]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/select%20sns%20step%20functions.png)

Ahora que tenemos el servicio en nuestro flujo debemos realizar su configuración. Damos click en _Edit as JSON_ y colocamos el mensaje y el numero de teléfono.

![Select SNS]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/configure%20sns%20step%20functions.png)

```
{
  "PhoneNumber.$": "$.data.numerotelefono",
  "Message": "Hola"
}
```
_PhoneNumber.$_ : Indica que la propiedad va a ser utilizada como parametro.
_$.data.numerotelefono_: es el campo que se va utilizar del JSON de entrada del Work Flow.

8.Ahora debemos agregar el servicio **SES** que nos va a servir para el envió del correo electrónico.Buscamos el servicio **SES** y seleccionamos _Amazon SES V1 Send Email_

![Select SES]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/select%20ses%20step%20functions.png)

En la sección Api Parameters vamos a reemplazar el JSON predeterminado por el siguiente:

```
{
  "Destination": {
    "ToAddresses.$": "$.data.para"
  },
  "Message": {
    "Body": {
      "Text": {
        "Data.$": "$.data.mensaje"
      }
    },
    "Subject": {
      "Data": "Mensaje Step Function"
    }
  },
  "Source.$": "$.data.de"
}
```
_Source.$_: Debemos colocar el correo autorizado en **SES** para el envió de correos.

9.Como en nuestro flujo quedo una opción por defecto podemos hacer dos cosas.
Entrar en la edición de la opción _Default_ y dar en el bóton _Clear_ para que ya no este en el flujo o podemos agregar un flujo de error.Para nuestro caso vamos agregar un flujo de error.

![Error Flow]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/error%20step%20functions.png)

Podemos configurar el mensaje del tipo de error o de la causa en la sección de configuración (son opcionales).

10.Ahora que tenemos definido nuestro flujo vamos a dar click en el botón _Next_. 

![Error Flow]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/design%20flow%20and%20json.png)

En la pantalla nuestra el diseño de nuestro flujo y el 'JSON' que genero el diseñador.

11.En la siguiente pantalla le asignamos un nombre a nuestro Work Flow, seleccionamos _Create new role_ y seleccionamos en la sección de _Log level_ ALL, que nos va a servir para ver en detalle cómo se ejecuto nuestro Flujo.

![Create Flow]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/create%20work%20flow.png)

12.En el caso que el rol que creamos no se le hallan asignado los permisos para enviar correos, debemos ir al _ROL_ en _IAM_ y asignarle los permisos totales sobre **SES** (Solo para pruebas).

13.Ahora que tenemos todo configurado, vamos a ejecutar nuestro Work Flow dando click en el bóton _Start Execution_.

![Start Execution]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/start%20execution.png)

Vamos a iniciar con la prueba del envió del mensaje de texto. Ingresamos el siguiente mensaje de JSON:

```
{
  "data":{
    "tipo":"SMS",
    "numerotelefono":"573105015690"
}
}
```
EL numero de teléfono esta compuesto por él indicativo del país y el numero de teléfono. En este caso es un numero (ejemplo) de Colombia.

![Start Execution SNS]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/start%20execution%20SNS%20Step%20Functions.png)

Después de ejecutar nuestro Work Flow vamos a ver gráficamente cómo se realizo la ejecución y el detalle del log.

![Result Execution SNS]
(https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/result%20execution%20sns%20step%20functions.png)

Con esto hemos realizado la creación, configuración y ejecución de nuestro Work Flow.

Los invito a que realicen la ejecución del Work Flow para el envío de correo o para que el flujo se ejecute donde no cumple ninguna de las condiciones.

```
{
  "data":{
    "tipo":"EMAIL",
    "para":["prueba@gmail.com"],
     "mensaje":"Hola mundo",
     "de":"prueba@mailinator.com"
   }
}
```



# Referencias
[Step Functions](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html)

Me pueden encontrar en

[Camilo Cabrales](https://www.linkedin.com/in/camilo-cabrales-31a0bb53/)