Proteger una API REST multitranes y con múltiples bases de datos

17

Estoy buscando mejorar la seguridad de una API REST existente a la que se accede a través de SSL. El servicio web es multi-inquilino, de modo que cada inquilino tiene un TenantId asignado.

El problema al que me enfrento se puede resumir en:

  1. ¿Cómo puedo determinar el inquilino?
  2. ¿Cómo puedo determinar si el cliente es legítimo?
  3. ¿La seguridad basada en la cookie HTTP es adecuada para la tarea, o debo considerar el token?

En la actualidad

Actualmente, emitimos manualmente (es decir, fuera de proceso, por teléfono, etc.) una clave API para cada cliente, que incluyen como encabezado HTTP en cada solicitud. Esta clave API se asigna a un TenantId. Cuando el cliente envía una solicitud de inicio de sesión a la API REST, determinamos el TenantId, que a su vez nos permite verificar el nombre de usuario / contraseña en la base de datos del inquilino correcta. Una vez que tenga éxito, emitimos una cookie HTTP por tiempo limitado. Esa cookie se utiliza en las solicitudes de REST posteriores. Internamente, esa cookie está vinculada a una sesión y la sesión contiene información de perfil de usuario para reducir la carga de db.

Somos conscientes de que esto tiene algunos riesgos de seguridad inherentes. La clave API se puede extraer fácilmente del código fuente del cliente desensamblado. También pretendemos crear nuestro propio cliente como un SPA en JavaScript que sea legible para todos. Aunque podemos revocar / cambiar claves, estoy buscando una implementación estandarizada más segura.

Alternativa

Según tengo entendido, podría usar una alternativa basada en token a las cookies. HMAC es un mecanismo de autenticación común para aplicaciones web, pero esto requiere el almacenamiento de un secreto compartido en el cliente y el servidor. Este secreto parece tener el mismo problema que la clave API anterior; en que se puede filtrar.

También he leído un poco sobre JWT, que parece extender el concepto HMAC en que el servidor puede conservar los datos de "sesión" del usuario en el token, reduciendo el número de llamadas a la base de datos para obtener información del usuario / perfil. El token JWT se utiliza como resultado de un inicio de sesión de usuario / contraseña exitoso. Por lo tanto, no hay problema secreto compartido aquí, ¿verdad?

También he leído un poco sobre OAuth2, específicamente la Subvención de credenciales de contraseña del propietario del recurso . No estoy seguro de si OAuth2 resuelve mi problema.

Determinar el arrendatario

El primer paso es determinar el inquilino. En lugar de utilizar la clave API para asignar a un TenantId, podría:

  1. Pregunte por TenantId como parte de la solicitud de inicio de sesión
  2. Use un mapeo de subdominios para asignarlo a TenantId

Validación de la aplicación que llama

En segundo lugar, necesito determinar si una aplicación cliente dada tiene permiso para acceder a la API REST. En esta parte, estoy bien y verdaderamente fuera de ideas brillantes. ¿Es ahí donde OAuth2 viene al rescate?

La única forma en la que puedo pensar para resolver esto es emitir la aplicación de llamada con una clave de API que caduca temporalmente después de que el usuario haya iniciado sesión. Aunque no garantiza que la aplicación no sea fraudulenta, reduce el riesgo a un atacante que también haya obtenido acceso a las credenciales de un usuario.

¿Es aceptable mi solución de cookie HTTP actual? ¿Debo pasar a un mecanismo de autenticación basado en token en su lugar?

Doy la bienvenida a cualquier consejo que pueda tener. Estoy vibrando a través de masas de información y tratando de entender todo esto. Cualquier orientación sería felizmente recibida!

    
pregunta Rebecca 23.01.2015 - 15:27
fuente

3 respuestas

5

Debería consultar auth 2.0 (RFC 6749) ya que tiene varios flujos que podrían satisfacer sus requisitos.

Primero debe saber si los clientes son públicos o confidenciales. Emitir las claves de API del cliente como lo está haciendo es inútil si los clientes son navegadores web o aplicaciones descargadas a dispositivos móviles, ya que el secreto no puede mantenerse. Si son servidores, entonces las claves api son buenas. Así que esa es tu primera consideración. La Sección 2.1 de rfc trata con los tipos de clientes y eso determinará qué flujos son aplicables.

Es necesario separar la identificación del servicio del cliente del usuario para el que está actuando. Su base de datos de back-end debe tener una asociación de usuarios con inquilinos y, posiblemente, claves de api con usuarios o inquilino + usuario si desea abarcar un solo arrendamiento. He implementado servicios donde los usuarios pueden participar en varios inquilinos, por lo que puede o no aplicarse a su caso. He utilizado con éxito la solicitud de concesión de credenciales de contraseña del propietario del recurso para que un usuario pueda proporcionar su nombre de usuario y contraseña desde un navegador web. Parece que ha utilizado un método fuera de banda para autorizar al cliente, por lo que no se requieren credenciales de usuario. Pero si el cliente es un navegador web o una aplicación móvil, no puede confiar en la autenticación del cliente y debe obtener la autorización del usuario y eso significa proporcionar credenciales de usuario.

Independientemente del flujo que utilice, obtendrá una respuesta de la siguiente manera:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"example",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "example_parameter":"example_value"
} 

El token de acceso devuelto es lo que el cliente utiliza en sus solicitudes para que pueda demostrar al servidor que sus solicitudes están autorizadas.

Tiene dos opciones para el encabezado de Autorización, 'portador' o 'mac'.

Authorization: Bearer xxxxxx

Si sus clientes están utilizando TLS, los tokens de portador son la forma más sencilla de avanzar. Consulte la sección 7.1 de la RFC para obtener más detalles.

Finalmente, dado que los tokens de acceso son solo temporales, sus clientes pueden usar el token de actualización para solicitar un nuevo token de acceso una vez que el token de acceso se aproxime o supere su vencimiento. Depende de usted si desea utilizar tokens de actualización o no. Los clientes deberán almacenarlos de forma segura al menos el mismo nivel de protección que utilizan para sus claves api. En su sistema, los tokens de actualización pueden ser innecesarios para las interacciones servidor-servidor si la vida útil de acceso es suficiente y no se requiere la autenticación del usuario. Si se requiere la autenticación del usuario, los tokens de actualización pueden ser útiles si el almacenamiento del cliente proporciona un nivel de protección suficiente.

    
respondido por el Andrew Hacking 24.01.2015 - 09:49
fuente
0

Creo que lo que tiene en este momento está bien con respecto a cómo identifica a un inquilino: cada cliente va a necesitar algún tipo de identificador, una clave API es tan buena como cualquier otra. Dado que todo se está ejecutando a través de SSL, realmente no tiene que preocuparse por la exposición (al menos durante el tránsito).

Parece que te preocupas por el almacenamiento del lado del cliente de la clave API, pero en última instancia ese no es tu trabajo. Es responsabilidad del cliente mantener segura su información privada (no es el trabajo de su banco mantener su PIN seguro). Su trabajo es proteger al servidor, y a sus clientes, del mal uso. Una forma de hacerlo es tener la capacidad de revocar / bloquear una clave de API y / o sesión.

El argumento cookie vs HMAC puede no ser tan importante como crees. Pregúntese qué cambia si cambia de una cookie a un token. Un HMAC es ciertamente más seguro dado que está firmado, sin embargo, usted podría cifrar fácilmente el contenido de la cookie. En última instancia, todavía le dará el mismo dolor de cabeza de almacenamiento que la cookie. La parte importante en la que hay que centrarse es en cuánto daño podría hacer alguien si lograba acceder a él. Eso lo hará pensar en A. qué seguridad debe tener la cookie / token y B. cómo puede proteger el servidor / cliente si cayera en manos maliciosas.

Si también necesita manejar la autorización del cliente, entonces probablemente debería ver OAuth, dado que es precisamente para lo que está diseñado.

    
respondido por el James 24.01.2015 - 11:05
fuente
0

una alternativa es usar claves públicas-privadas.

  1. la aplicación cliente (por ejemplo, angularjs) tendrá la clave pública del servidor (por ejemplo, web api)

  2. utilizando la clave pública del servidor, el cliente debe cifrar la credencial del usuario (por ejemplo, nombre de usuario, contraseña con hash, etc.). el token generado será enviado al servidor; ya sea por encabezados o consultas

  3. el servidor descifrará el token, obtendrá el nombre de usuario y la contraseña con hash. luego obtenga el nombre de usuario persistente + contraseña con hash de la base de datos. la autenticación es verificando si ambas contraseñas con hash coinciden (una del token y la otra de la base de datos).

en esta alternativa, la contraseña del usuario no se envía como texto sin formato. se encripta / hash antes de ser enviado. el cliente puede almacenar ese token en el almacenamiento local (navegador) o generar un token cada vez que llame al servidor.

    
respondido por el caydev2010 24.08.2017 - 05:23
fuente

Lea otras preguntas en las etiquetas