with tutorial simple rails español create crear con ruby-on-rails ruby security rest asp.net-web-api

ruby-on-rails - simple - rails api tutorial



Buscando sugerencias para construir una API REST segura dentro de Ruby on Rails (4)

Estoy empezando a construir una API REST para un proyecto en el que estoy trabajando, y esto me llevó a investigar un poco sobre la mejor manera de crear una API usando RoR. Descubrí muy rápidamente que, de forma predeterminada, los modelos están abiertos al mundo y se pueden llamar a través de URL simplemente colocando un ".xml" al final de la URL y pasando los parámetros apropiados.

Entonces llegó la siguiente pregunta. ¿Cómo aseguro mi aplicación para evitar cambios no autorizados? Al hacer algunas investigaciones, encontré un par de artículos que hablaban de attr_accessible y attr_protected y cómo se pueden usar. La URL particular que encontré hablando de estos se publicó en mayo de 2007 ( here ).

Como con todas las cosas ruby, estoy seguro de que las cosas han evolucionado desde entonces. Entonces mi pregunta es, ¿sigue siendo esta la mejor manera de asegurar una API REST dentro de RoR?

Si no, ¿qué sugiere en un escenario de "nuevo proyecto" o "proyecto existente"?


¿Cómo aseguro mi aplicación para evitar cambios no autorizados?

attr_accessible y attr_protected son útiles para controlar la capacidad de realizar asignaciones masivas en un modelo ActiveRecord. Definitivamente desea usar attr_protected para evitar ataques de inyección de formularios; mira Usar attr_protected o te piratearemos .

Además, para evitar que alguien pueda acceder a los controladores en su aplicación Rails, es casi seguro que va a necesitar algún tipo de sistema de autenticación de usuario y colocar un before_filter en sus controladores para asegurarse de que tiene un usuario autorizado haciendo el solicite antes de permitir que se ejecute la acción de controlador solicitada.

Consulte la Guía de seguridad de Ruby on Rails (parte del Proyecto de documentación de Rails) para obtener más información útil.


Existen varios esquemas para autenticar solicitudes API, y son diferentes a la autenticación normal proporcionada por complementos como restful_authentication o acts_as_authenticated. Lo más importante es que los clientes no mantendrán sesiones, por lo que no existe el concepto de inicio de sesión.

Autenticación HTTP

Puede usar autenticación HTTP básica. Para esto, los clientes de la API usarán un nombre de usuario y contraseña regulares y simplemente lo colocarán en la URL de la siguiente manera:

http://myusername:[email protected]/

Creo que restful_authentication admite esto de manera inmediata, por lo que puedes ignorar si alguien está usando tu aplicación a través de la API o a través de un navegador.

Una desventaja aquí es que les está pidiendo a los usuarios que pongan su nombre de usuario y contraseña a la vista en cada solicitud. Al hacerlo a través de SSL, puede hacer esto seguro.

Sin embargo, creo que nunca he visto una API que use esto. A mí me parece una buena idea, sobre todo porque los esquemas de autenticación actuales lo admiten de manera inmediata, así que no sé cuál es el problema.

Clave API

Otra forma sencilla de habilitar la autenticación API es usar claves API. Básicamente es un nombre de usuario para un servicio remoto. Cuando alguien se registra para usar su API, les da una clave API. Esto debe pasar con cada solicitud.

Un inconveniente aquí es que si alguien obtiene la clave de API de otra persona, puede realizar solicitudes como ese usuario. Creo que haciendo que todas sus solicitudes de API utilicen HTTPS (SSL), puede compensar este riesgo de alguna manera.

Otro inconveniente es que los usuarios usan las mismas credenciales de autenticación (la clave API) dondequiera que vayan. Si quieren revocar el acceso a un cliente API, su única opción es cambiar su clave API, lo que deshabilitará también a todos los demás clientes. Esto puede mitigarse permitiendo a los usuarios generar múltiples claves API.

Clave de API + firma de clave secreta

Obsoleto (más o menos) - ver OAuth a continuación

Significativamente más complejo es firmar la solicitud con una clave secreta. Esto es lo que Amazon Web Services (S3, EC2 y demás). Esencialmente, le das al usuario 2 claves: su clave API (es decir, nombre de usuario) y su clave secreta (es decir, contraseña). La clave API se transmite con cada solicitud, pero la clave secreta no. En su lugar, se usa para firmar cada solicitud, generalmente agregando otro parámetro.

IIRC, Amazon logra esto tomando todos los parámetros a la solicitud y ordenándolos por nombre de parámetro. Luego, esta cadena se somete a hash, usando la clave secreta del usuario como la tecla de almohadilla. Este nuevo valor se agrega como un nuevo parámetro a la solicitud antes de ser enviado. Por parte de Amazon, hacen lo mismo. Toman todos los parámetros (excepto la firma), los piden y hash usando la clave secreta. Si esto coincide con la firma, saben que la solicitud es legítima.

La desventaja aquí es la complejidad. Conseguir que este esquema funcione correctamente es un problema, tanto para el desarrollador de API como para los clientes. Espere muchas llamadas de soporte y correos electrónicos molestos de desarrolladores de clientes que no pueden hacer que las cosas funcionen.

OAuth

Para combatir algunos de los problemas de complejidad con la clave + firma secreta, ha surgido un estándar llamado OAuth . En el núcleo, OAuth es un sabor de clave + firma secreta, pero gran parte está estandarizado y se ha incluido en bibliotecas para muchos idiomas .

En general, es mucho más fácil para el productor y el consumidor de API utilizar OAuth en lugar de crear su propio sistema de clave / firma.

OAuth también segmenta de forma inherente el acceso, proporcionando diferentes credenciales de acceso para cada consumidor API. Esto permite a los usuarios revocar selectivamente el acceso sin afectar sus otras aplicaciones consumidoras.

Específicamente para Ruby, hay una joya de OAuth que ofrece asistencia inmediata para productores y consumidores de OAuth. He usado esta joya para construir una API y también para consumir API OAuth y quedé muy impresionado. Si crees que tu aplicación necesita OAuth (a diferencia del esquema de clave API más simple), entonces puedo recomendar fácilmente el uso de la gema OAuth.


Me enfrento a preguntas similares a las tuyas en este momento porque también estoy construyendo una API REST para una aplicación de rieles.

Sugiero asegurarme de que solo los atributos que pueden ser editados por el usuario estén marcados con attr_accessible. Esto configurará una lista blanca de atributos que se pueden asignar usando atributos_actualización.

Lo que hago es algo como esto:

class Model < ActiveRecord::Base attr_accessible nil end

Todos mis modelos heredan de eso, por lo que se ven obligados a definir attr_accessible para cualquier campo que quieran asignar en masa. Personalmente, me gustaría que hubiera una forma de habilitar este comportamiento por defecto (puede haber, y no lo sé).

Solo para que sepa que alguien puede asignar una propiedad en masa no solo usando la API REST sino también usando una publicación regular.


Otro enfoque que ahorra la construcción de muchas de las cosas es utilizar algo como http://www.3scale.net/ que maneja claves, tokens, cuotas, etc. para desarrolladores individuales. También realiza análisis y crea un portal para desarrolladores.

Hay un plugin de ruby ​​/ rails plugin API de ruby que se aplicará a las políticas de tráfico a medida que lleguen; puedes usarlo junto con la gema oAuth . También puede hacerlo soltando barniz en frente de la aplicación y utilizando el mod lib de barniz: Varnish API Module .