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:
- ¿Cómo puedo determinar el inquilino?
- ¿Cómo puedo determinar si el cliente es legítimo?
- ¿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:
- Pregunte por TenantId como parte de la solicitud de inicio de sesión
- 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!