how google example oauth 2-legged oauth-provider

oauth - google - openid



Implementación de un proveedor de OAuth de 2 patas (2)

Daría un paso atrás y pensaría en lo que un cliente debidamente autenticado te va a enviar.

¿Puede almacenar las claves y credenciales en una base de datos común a la que se puede acceder desde ambos conjuntos de servicios, y simplemente implementar el proveedor de OAuth en un idioma? Cuando el usuario envía una solicitud a un servicio (PHP o Java), comprueba contra la tienda común. Cuando el usuario está configurando el cliente OAuth, usted hace todo eso a través de una aplicación PHP o Java (su preferencia) y almacena las credenciales en el DB común.

Hay algunos proveedores de Oauth escritos en otros idiomas que es posible que desee consultar:

Estoy tratando de encontrar mi camino en torno a las especificaciones de OAuth, sus requisitos y cualquier implementación que pueda encontrar y, hasta el momento, realmente parece ser más problemático que su valor porque tengo problemas para encontrar un solo recurso que lo junte todo . O tal vez es solo que estoy buscando algo más especializado que la mayoría de los tutoriales.

Tengo un conjunto de API existentes, algunas en Java, otras en PHP, que ahora necesito asegurar y, por una serie de razones, parece que OAuth es el camino correcto. Desafortunadamente, mi incapacidad para rastrear los recursos correctos para ayudarme a poner en marcha un proveedor es un desafío a esa teoría. Dado que la mayor parte de esto será el uso de la API de sistema a sistema, tendré que implementar un proveedor de 2 patas. Con eso en mente...

  1. ¿Alguien sabe de algún buen tutorial para implementar un proveedor OAuth de 2 patas con PHP?
  2. Dado que tengo API asegurables en 2 idiomas, ¿necesito implementar un proveedor en ambos o existe una forma de crear el proveedor como un "controlador frontal" al que puedo canalizar todas las solicitudes?
  3. Al asegurar los servicios de PHP, por ejemplo, ¿tengo que proteger cada API de forma individual al incluir los recursos necesarios del proveedor en cada uno?

Gracias por tu ayuda.


Rob, no estoy seguro de dónde aterrizaste en esto, pero quería agregar mis 2 centavos en caso de que alguien más se encontrara con esta pregunta.

Más o menos tuve la misma pregunta hace unos meses y escuché acerca de "OAuth" durante la mayor parte de un año. Estaba desarrollando una API REST que necesitaba para asegurarme, así que comencé a leer acerca de OAuth ... y entonces mis ojos comenzaron a rodar hacia atrás en mi cabeza.

Probablemente le di un buen día sólido o dos de skimming y lectura hasta que decidí, al igual que usted, que OAuth estaba confundiendo la basura y simplemente me rendí.

Entonces comencé a buscar formas de asegurar las API en general y comencé a tener una mejor comprensión de cómo hacerlo. La forma más popular parecía ser enviar solicitudes a la API junto con una suma de verificación de todo el mensaje (codificado con un secreto que solo tú y el servidor sabían) que el servidor puede usar para decidir si el mensaje fue manipulado en su camino del cliente, así:

  1. El cliente envía /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
  2. El servidor obtiene todo eso, busca al usuario "123" en la base de datos, carga su clave secreta y luego (utilizando el mismo método que utilizó el cliente) vuelve a calcular su propia suma de comprobación dados los argumentos de solicitud.
  3. Si la suma de comprobación generada por el servidor y la suma de verificación enviada del cliente coinciden, la solicitud es correcta y se ejecuta, de lo contrario, se considera manipulada y rechazada.

La suma de comprobación se denomina HMAC y, si desea un buen ejemplo de esto, es lo que usa Amazon Web Services (sin embargo, llaman al argumento ''firma'' no ''suma de comprobación'').

Entonces, dado que uno de los componentes clave para que esto funcione es que el cliente y el servidor tienen que generar el HMAC de la misma manera (de lo contrario no coincidirán), tiene que haber reglas sobre CÓMO combinar todos los argumentos. Entonces, de repente, entendí toda esa basura de "Octetos naturales por bytes" de OAuth ... solo estaba definiendo las reglas sobre cómo generar la firma porque era necesario.

Otro punto es que cada parámetro que incluye en la generación de HMAC es un valor que luego no se puede alterar cuando envía la solicitud.

Entonces, si codifica el origen del URI como la firma, por ejemplo:

  • /user.json == askJdla9 / kjdas + Askj2l8add

luego, la única cosa en su mensaje que no se puede manipular es el URI, todos los argumentos se pueden alterar porque no son parte del valor de "suma de comprobación" que el servidor volverá a calcular.

Alternativamente, incluso si incluye CADA parámetro en el cálculo, aún corre el riesgo de "ataques de repetición" cuando un intermediario malintencionado o evesdropped puede interceptar una llamada API y simplemente seguir reenviando al servidor una y otra vez.

Puede solucionarlo agregando una marca de tiempo (siempre use UTC) en el cálculo de HMAC también.

RECORDATORIO: dado que el servidor necesita calcular el mismo HMAC, debe enviar el valor que use en el cálculo, EXCEPTO SU CLAVE SECRETA (OAuth lo llama un consumer_secret, creo). Entonces, si agrega la marca de tiempo, asegúrese de enviar un parámetro de marca de tiempo junto con su solicitud.

Si desea proteger la API de los ataques de reproducción, puede usar un valor nonce (es un valor de uso de una vez que el servidor genera, entrega al cliente, el cliente lo usa en el HMAC, envía de vuelta la solicitud, el servidor confirma y luego marca ese valor nonce como "usado" en el DB y nunca deja que otra solicitud lo vuelva a usar).

NOTA: ''nonce'' es una forma muy exacta de resolver el problema del "ataque de repetición": las marcas de tiempo son geniales, pero como las computadoras no siempre tienen valores de marca de tiempo sincronizados, debe permitir una ventana aceptable en el lado del servidor de qué "vieja" puede ser una solicitud (digamos 10 minutos, 30 minutos, 1 hora ... Amazon usa 15 minutos) antes de aceptarla o rechazarla. En este escenario, su API es técnicamente vulnerable durante todo el intervalo de tiempo.

Creo que los valores de nonce son geniales, pero solo deberían usarse en las API que son fundamentales para mantener su integridad. En mi API, no lo necesitaba, pero sería trivial agregarlo más tarde si los usuarios lo exigieran ... Literalmente solo necesitaría agregar una tabla "nonce" en mi DB, exponer una nueva API a clientes como:

  • /nonce.json

y luego, cuando me lo vuelvan a enviar en el cálculo de HMAC, necesitaría verificar el DB para asegurarse de que nunca se haya usado antes y una vez utilizado, marcarlo como tal en el DB, de modo que si una solicitud NUNCA entrara nuevamente con ese mismo nonce lo rechazaría.

Resumen

De todos modos, para abreviar, todo lo que acabo de describir es básicamente lo que se conoce como "OAuth de 2 patas". No hay ese paso adicional de llegar a la autoridad (Twitter, Facebook, Google, lo que sea) para autorizar al cliente, ese paso se elimina y, en cambio, el servidor confía implícitamente en el cliente SI coinciden los HMAC que están enviando. Eso significa que el cliente tiene la clave secret_key correcta y está firmando sus mensajes con ella, por lo que el servidor confía en ella.

Si comienzas a buscar en línea, este parece ser el método preferido para proteger los métodos API ahora-adays, o algo así. Amazon usa casi exactamente este método, excepto que utilizan un método de combinación ligeramente diferente para sus parámetros antes de firmarlo todo para generar el HMAC.

Si estás interesado escribí todo este viaje y proceso de pensamiento mientras lo estaba aprendiendo. Eso podría ayudar a proporcionar una visita de pensamiento guiada de este proceso.