API RESTful protegida que puede ser utilizada por la aplicación web (angular), iOS y Android

Tengo que diseñar un plan para desarrollar una API RESTful (Python / Flask) que podría ser utilizada por nuestra futura aplicación web (Angularjs) y aplicaciones móviles (iOS / Android).

He estado investigando durante tres días y me he encontrado con varios escenarios: El uso de HTTPS es una forma de complementar los métodos siguientes para mantenerlo más seguro. Pero https es más lento, lo que podría significar que necesitamos servidores más rápidos y más caros.

  1. Uso de Basic-Http-Auth y el envío de nombre de usuario / contraseña en llano (pero https) sobre el cable para cada solicitud a la API.
  2. El uso de Digest-Auth, que es un hash de la contraseña y el seguimiento sería automático Esto funcionaría para la aplicación web, sin embargo no pude confirmar si los iPhones y Android apoyaría esto de forma nativa. Si lo hacen, que podría ser una solución fácil!
  3. Utilizando una cabecera de http personalizada, donde enviaría una cadena de autenticación personalizada en el encabezado http después de una autenticación correcta. Pero entonces tengo que asegurarse de que estoy enviando este código de autenticación para cada solicitud que el usuario hace. Esto hace que sea exactamente como 1) con la diferencia de que las contraseñas simples no se utilizan y el código de autenticación puede caducar sin ningún riesgo. También es problemático el seguimiento del código de autorización, que ya no se automatiza como en 2)
  4. Usar OAuth es una opción. Pero es bastante difícil de configurar. Si no hay mejor manera, tal vez esa es la única manera?
  5. Asegurar la API como Amazon S3 como se describe en este gran artículo . En resumen, dice que tanto el servidor como el cliente sabrían de una clave privada, que utilizarían para manipular la comunicación. Será como un gángster apretón de manos, que sólo confiaría en el chico de entrega, si él conoce el puño de mano gangsta. Más abajo los comentarios alguien pregunta:

¿Cómo mantener la clave privada "segura" en una aplicación HTML5 pura?

Tienes razón; En una aplicación HTML5 pura (JS / CSS / HTML), no hay protección de la clave. Usted haría toda la comunicación sobre HTTPS en cuyo caso no necesitaría una llave ya que podría identificar con seguridad a un cliente usando un API_KEY estándar o algún otro identificador amistoso sin la necesidad o complejidad de un HMAC.

Así que en otras palabras, incluso no hay punto de utilizar el método para una aplicación web en primer lugar. Y honestamente no entiendo cómo esto debería funcionar en el dispositivo móvil tampoco. Un usuario descarga nuestra aplicación y ¿cómo envío la clave privada desde el iphone al servidor? En el momento en que la transfiera, se verá comprometida.

Cuanto más estoy investigando el más indeciso que estoy recibiendo.

Tenía la esperanza de pedir a algunos profesionales que han hecho esto anteriormente y podrían compartir su experiencia. Muchas gracias

Usted parece confundir / fusionar dos conceptos diferentes juntos. Empezamos a hablar sobre el cifrado de tráfico (HTTPS) y luego empezamos a hablar sobre diferentes maneras de administrar las sesiones autenticadas. En una aplicación segura, estas tareas no son mutuamente exclusivas. También parece haber un malentendido acerca de cómo la gestión de sesiones puede afectar la autenticación. Sobre la base de que voy a proporcionar una cartilla sobre la aplicación web / web api sesión de gestión, autenticación y cifrado.

Introducción

Gestión de sesiones

Las transacciones HTTP son apátridas de forma predeterminada. HTTP no especifica ningún método para que su aplicación sepa que se ha enviado una solicitud HTTP desde un usuario específico (autenticado o no).

Para aplicaciones web robustas, esto no es aceptable. Necesitamos una forma de asociar las solicitudes y los datos realizados a través de múltiples solicitudes. Para hacer esto, en la petición inicial al servidor un usuario necesita ser asignado una "sesión". Generalmente las sesiones tienen algún tipo de identificador único que se envía al cliente. El cliente envía ese identificador de sesión con cada solicitud y el servidor utiliza el ID de sesión enviado en cada solicitud para preparar adecuadamente una respuesta para el usuario.

Es importante recordar que un 'id de sesión' puede ser llamado muchas otras cosas. Algunos ejemplos de estos son: token de sesión, token, etc. Por coherencia usaré 'id de sesión' para el resto de esta respuesta.

Cada solicitud HTTP del cliente debe incluir el id de sesión; Esto puede hacerse de muchas maneras. Ejemplos populares son:

  1. Se puede almacenar en una cookie – las cookies para el dominio actual se envían automáticamente en cada solicitud.
  2. Se puede enviar en la URL – cada solicitud podría enviar el ID de la sesión en la URL, no se sugiere desde id de la sesión permanecerá en el historial de los clientes
  3. Se puede enviar como un encabezado HTTP – cada solicitud tendría que especificar el encabezado

La mayoría de los marcos de aplicaciones web utilizan cookies. Sin embargo, la aplicación que se basan en JavaScript y diseños de una sola página puede optar por utilizar un encabezado HTTP / almacenarlo en alguna otra ubicación que sea observable por el servidor.

Es muy importante recordar que la respuesta HTTP que notifica al cliente de su id de sesión y las solicitudes del cliente que contienen el identificador de sesión son completamente texto sin formato y 100% inseguras. Para combatir eso, todo el tráfico HTTP necesita ser cifrado; Que es donde entra HTTPS.

También es importante señalar que no hemos hablado de vincular una sesión a un usuario específico en nuestro sistema. La gestión de sesiones es simplemente la asociación de datos a un cliente específico que accede a nuestro sistema. El cliente puede estar en estados autenticados y no autenticados, pero en ambos estados generalmente tienen una sesión.

Autenticación

La autenticación es donde enlazamos una sesión con un usuario específico en nuestro sistema. Esto generalmente se maneja mediante un proceso de inicio de sesión en el que un usuario proporciona credenciales, se verifican esas credenciales y, a continuación, enlazamos una sesión a un registro de usuario específico en nuestro sistema.

A su vez, el usuario está asociado con privilegios para el control de acceso de grano fino mediante listas de control de acceso y entradas de control de acceso (ACL y ACE). Esto se conoce generalmente como "Autorización". La mayoría del sistema siempre tiene Autenticación y Autorización. En algunos sistemas sencillos, todos los usuarios autenticados son iguales, en cuyo caso no tendrá autorización previa a la autenticación sencilla. Más información sobre esto está fuera del alcance de esta pregunta, pero considere leer sobre ACE / ACL.

Una sesión específica puede ser marcada como representando un usuario autenticado de diferentes maneras.

  1. Sus datos de sesión almacenados lado del servidor podría almacenar su id de usuario / algún otro indicador que denota que el uso es autenticado como un usuario específico
  2. Otro token de usuario podría enviarse al cliente tal como un identificador de sesión (que sobre HTTP no cifrado es tan inseguro como enviar un identificador de sesión sin cifrar)

Cualquiera de las opciones está bien. Por lo general, se reduce a la tecnología que está trabajando y lo que ofrecen por defecto.

Un cliente generalmente inicia el proceso de autenticación. Esto se puede hacer mediante el envío de credenciales a una url específica (por ejemplo, yoursite.com/api/login). Sin embargo, si queremos ser 'RESTful' generalmente nos referenciamos a un recurso por algún sustantivo y realizamos la acción de 'crear'. Esto se puede hacer requiriendo un POST de las credenciales a yoursite.com/api/authenticatedSession/. Donde la idea sería crear una sesión autenticada. La mayoría de los sitios sólo POST las credenciales de / api / login o similares. Esto es una desviación de los ideales RESTful "verdaderos" o "puros", pero la mayoría de la gente encuentra esto un concepto más simple en lugar de pensar en él como "crear una sesión autenticada".

Cifrado

HTTPS se utiliza para cifrar el tráfico HTTP entre un cliente y un servidor. En un sistema que se basa en usuarios autenticados y no autenticados, todo el tráfico que depende de un usuario que está siendo autenticado debe ser cifrado a través de HTTPS; No hay forma de evitar esto.

La razón de esto es que si se autentica un usuario, comparte un secreto con ellos (su id de sesión, etc) y luego comienza a desfilar ese secreto en HTTP normal su sesión puede ser secuestrada por ataques de hombre en el medio. Un hacker esperará a que el tráfico pase por una red observada y le robe el secreto (ya que su texto sin formato a través de HTTP) y luego iniciar una conexión a su servidor pretendiendo ser el cliente original.

Una manera de combatir esto es asociando las peticiones de dirección IP remota a una sesión autenticada. Esto es ineficaz solo como cualquier hacker será capaz de falsificar sus peticiones de dirección IP remota en sus solicitudes falsas y luego observar las respuestas de su servidor está enviando de nuevo. La mayoría argumentaría que esto ni siquiera vale la pena implementar a menos que esté rastreando datos históricos y usarlos para identificar los patrones de inicio de sesión de un usuario específico (como lo hace Google).

Si necesita dividir su sitio entre las secciones HTTP y HTTPS, es imprescindible que el tráfico HTTP no envíe ni reciba el ID de sesión ni ningún token utilizado para administrar el estado de autenticación de un usuario. También es importante que no envíe datos de aplicación sensibles dentro de solicitudes / respuestas no HTTP.

La única manera de asegurar datos dentro de las aplicaciones web / API es cifrar el tráfico.

Tus temas uno por uno

Basic-Http-Auth

  • Autenticación: SI
  • Gestión de sesiones: NO
  • Encriptación: NO

Este es un método para autenticar sólo por recursos web. La autenticación básica autentica los usos por recurso identificado por URL. Esto fue implementado más popularmente por Apache HTTP Web Server con el uso de la autenticación de directorio / ubicación basada en .htaccess. Las credenciales tienen que ser enviadas con cada solicitud; Los clientes generalmente lo manejaban de forma transparente para los usuarios.

La autenticación básica puede ser utilizada por otros sistemas como un modo de autenticación. Sin embargo, los sistemas que utilizan Basic-Http-Auth están proporcionando autenticación y gestión de sesión, no el Basic-Http-Auth en sí.

  • Esto no es gestión de sesión.
  • Esto no es cifrado; El contenido y las credenciales son casi 100% de texto sin formato
  • Esto no asegura el contenido de las solicitudes / respuestas HTTP de la aplicación.

Digest-Auth

  • Autenticación: SI
  • Gestión de sesiones: NO
  • Encriptación: NO

Esto es exactamente lo mismo que Basic-Http-Auth con la adición de algunos simples MD5 digerir. Esta digestión no se debe confiar en vez de usar el cifrado.

  • Esto no es gestión de sesión.
  • Esto no es cifrado; La digestión se rompe fácilmente
  • Esto no asegura el contenido de las solicitudes / respuestas HTTP de la aplicación.

OAuth

  • Autenticación: SI
  • Gestión de sesiones: NO
  • Encriptación: NO

OAuth sólo le permite tener un servicio externo validar credenciales. Después de eso, depende de usted administrar / trabajar con el resultado de la solicitud de autenticación a su proveedor de OAuth.

  • Esto no es gestión de sesión.
  • Esto no es cifrado; Su tráfico de sitios sigue siendo texto sin formato. El proceso de autenticación será seguro debido a las restricciones HTTPS, pero su aplicación sigue siendo vulnerable.
  • Esto no asegura el contenido de las solicitudes / respuestas HTTP de la aplicación.

Gangster Handshake / Cabecera HTTP personalizada

  • Autenticación: SÍ, potencialmente
  • Gestión de sesiones: SÍ, potencialmente
  • Encriptación: NO

"Custom HTTP header" es un tipo de "Gangster Handshakes"; Como tal voy a utilizar la misma sección para discutirlos. La única diferencia es que un "encabezado HTTP personalizado" especifica dónde se almacenará el hanshake (identificador de sesión, token, toke de autenticación del usuario, etc.) (es decir, en un encabezado HTTP).

Es importante tener en cuenta que éstos no especifican cómo se manejará la autenticación ni especificarán cómo se manejará la administración de la sesión. En esencia, describen cómo y dónde se almacenarán los identificadores de sesión / testigos de autenticación.

La autenticación debería ser manejada por su aplicación o por un tercero (por ejemplo, OAuth). La gestión de la sesión todavía tendrá que ser implementada también. Lo interesante es que usted puede elegir la fusión de los dos si lo desea.

  • Esto no es cifrado; Su tráfico de sitios sigue siendo texto sin formato. El proceso de autenticación será seguro debido a las restricciones HTTPS si utiliza OAuth, pero su aplicación sigue siendo vulnerable.
  • Esto no asegura el contenido de las solicitudes / respuestas HTTP de la aplicación.

Qué necesitas hacer

… Le recomiendo que se asegure de que entiende que una aplicación web robusta que es segura necesita lo siguiente:

  1. Cifrado (HTTPS es más o menos su única opción)
  2. Gestión de sesiones
  3. Autorización de autenticación

La autorización se basa en la autenticación. La autenticación se basa en la gestión de sesiones y el cifrado se asegura de que la sesión no se ha secuestrado y que las credenciales no se interceptan.

Flask-Login

Creo que deberías mirar a flask-login como una forma de evitar la reimplementación de la rueda. Yo personalmente nunca lo he usado (yo uso pirámide para aplicaciones web en python). Sin embargo, lo he visto antes mencionado en las juntas de aplicación web / python. Maneja la autenticación y la gestión de sesiones. Tire su api / aplicación web a través de HTTPS y tiene los tres (cifrado, gestión de sesiones y autenticación de usuario).

Si no puede / no puede usar flask-login, esté preparado para escribir el suyo propio, pero investigue primero sobre cómo crear mecanismos de autenticación seguros.

Si es posible, si no entiende cómo escribir un procedimiento de autenticación, no lo intente sin primero aprender cómo los hackers utilizan ataques basados ​​en patrones, ataques de sincronización, etc.

Cifre su tráfico

… pasar de la idea de que puede evitar el uso de HTTPS con algunos "inteligente" token uso. Pasar de la idea de que debe evitar el uso de HTTPS / cifrado porque "es lento", proceso intensivo, etc Es un proceso intensivo, ya que es un algoritmo de cifrado. La necesidad de garantizar la seguridad de los datos de sus usuarios y los datos de sus aplicaciones debe ser siempre su prioridad más alta. Usted no quiere pasar por el horror de notificar a sus usuarios que sus datos estaban comprometidos.

El https es más lento, pero no un no. Sólo el apretón de manos es más lento. Para nosotros el mayor problema es mantener el par de claves en el lado de los servidores móviles y los derechos. También hemos implementado un resumen de mensajes. El problema es: es difícil de configurar la versión php-android-ios correctamente. Después de esto se hace (un parámetro necesita para cambiar lo que está sugiriendo Google en los primeros resultados sólo en lado android) el problema será con dispositivos de gama baja: a mucho uso de la CPU, lento en el proceso de decrypt-encrypt, mucho más lento que https, Especialmente cuando necesita transformar 10kb String (puede tomar varios minutos).

Si no transfiero datos de la NASA a Hamas, de lo que iría con un cifrado muy sencillo sobre HTTP simple: como invertir los bits o así …

Ir con HTTPS. Es (más lento), pero la seguridad que obtiene de él por el tiempo de inversión relativamente corto (comprar el certificado SSL y simplemente cambiar las URL de http a https) vale la pena. Sin HTTPS, corre el riesgo de que las sesiones de sus usuarios sean secuestradas en redes públicas no seguras, lo cual es extremadamente fácil para alguien .

  • ¿Existe ya una biblioteca OAuth2 para Java / Android?
  • Autenticación IMAP / SMTP con el token AccountManager
  • Los botones 'cancelar' y 'aceptar' de la página de inicio de sesión de Google OAuth no están habilitados desde el 22 de agosto
  • Cómo obtener refreshToken al usar GoogleAuthUtil
  • ¿Puedo usar el AccountManager de Android para obtener el token de acceso de OAuth para AppEngine?
  • Hacer Android WebView no almacenar cookies o contraseñas
  • GoogleSignInResult devuelve DEVELOPER_ERROR en la aplicación de Android mediante Firebase
  • Crear firma para la autenticación Flickr (Android SDK)
  • Woocommerce rest api OAuth autenticación en android
  • ¿Cómo / dónde almacenar el token de actualización en Android?
  • Cómo usar la API de inicio de sesión de Google con Cordova / Phonegap
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.