seguridad por español ejemplo basada autenticacion arquitectura php api authentication rest authorization

php - por - seguridad api rest



Autorización y autenticación de la API REST(web+móvil) (1)

Como siempre, la mejor manera de proteger una clave es no transmitirla.

Dicho esto, normalmente utilizamos un esquema, donde cada "clave de API" tiene dos partes: una ID no secreta (por ejemplo, 1234) y una clave secreta (por ejemplo, byte [64]).

  • Si entrega una clave API, guárdela (salada y hash) en la base de datos de su servicio.
  • Si regala cuentas de usuario (protegidas por contraseña), almacene las contraseñas (salados y hash) en la base de datos de su servicio

Ahora cuando un consumidor primero accede a su API, para conectarse, tenerlo

  • Enviar un parámetro de "nombre de usuario" ("john.doe" no es secreto)
  • Envíe un parámetro "APIkeyID" ("1234", no en secreto)

y devolverlo

  • las sales de su base de datos (en caso de que uno de los parámetros sea incorrecto, simplemente devuelva una sal repetible, por ejemplo, sha1 (username + "notverysecret").
  • La marca de tiempo del servidor

El consumidor debe almacenar la sal por la duración de la sesión para mantener las cosas rápidas y sin problemas, y debe calcular y mantener la diferencia horaria entre el cliente y el servidor.

El consumidor ahora debe calcular los valores hash salados de la clave API y la contraseña. De esta forma, el consumidor tiene exactamente los mismos valores hash para la contraseña y la clave API, como lo que se almacena en su base de datos, pero sin nada que pueda pasar por alto.

Ahora cuando un consumidor accede subsecuentemente a su API, para hacer un trabajo real, tenerlo

  • Enviar un parámetro de "nombre de usuario" ("john.doe" no es secreto)
  • Envíe un parámetro "APIkeyID" ("1234", no en secreto)
  • Enviar un parámetro "RequestSalt" (byte [64], aleatorio, no secreto)
  • Enviar un parámetro "RequestTimestamp" (calculado a partir de la hora del cliente y el desplazamiento conocido)
  • Enviar un parámetro "RequestToken" (hash (passwordhash + request_salt + request_timestamp + apikeyhash))

El servidor no debería aceptar marcas de tiempo más que en 2 segundos en el pasado, para que esto sea seguro contra un ataque de repetición.

El servidor ahora puede calcular el mismo hash (passwordhash + request_salt + request_timestamp + apikeyhash) como cliente, y asegúrese de que

  • el cliente conoce la clave API,
  • el cliente conoce la contraseña correcta

He leído sobre oAuth, API de REST de Amazon, HTTP Basic / Digest, etc., pero no puedo obtener todo en "una sola pieza". Esta es probablemente la situación más cercana - Crear una API para aplicaciones móviles - Autenticación y autorización

Me gustaría construir un sitio web centrado en API: servicio. Entonces (al principio) tendría una API en el centro y el sitio web (PHP + MySQL) se conectaría a través de cURL , Android y iPhone a través de sus interfaces de red. Entonces 3 clientes principales: 3 claves de API. Y cualquier otro desarrollador también podría desarrollar a través de la interfaz API y obtendría su propia clave API. Las acciones de API serían aceptadas / rechazadas según el estado de UserLevel, si soy administrador, puedo eliminar cualquier cosa, etc., todas las demás pueden manipular solo sus datos locales (de cuenta).

En primer lugar, autorización: ¿debo usar oAuth + xAuth o alguna implementación de mi tipo (ver http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197 )? Según entiendo, en Amazon el usuario del servicio es == usuario de API (tiene clave de API) . En mi servicio, debo separar usuarios / cuenta estándar (el que se registró en el sitio web) y cuentas de desarrollador (que deben tener su clave API).

Entonces, primero necesitaría autorizar la clave API y luego autenticar al usuario . Si utilizo el esquema de Amazon para verificar las claves de la API del desarrollador (autorizo ​​su aplicación), ¿qué sheme debería usar para la autenticación del usuario?

Leí acerca de obtener un token a través de api.example.org/auth después (a través de HTTPS , HTTP Basic) publicando mi nombre de usuario y contraseña y luego reenviarlo en cada solicitud siguiente. ¿Cómo administro tokens si estoy conectado simultáneamente en Android y un sitio web ? ¿Qué pasa con man-in-the-middle-attack si estoy utilizando SSL solo en la primera solicitud (cuando se transmiten el nombre de usuario y la contraseña) y solo HTTP en todos los demás? ¿No es un problema en este ejemplo la contraseña que protege un servicio REST?