tutorial servicios por example español ejemplo autenticacion wcf security rest authorization rest-security

wcf - servicios - Mejores prácticas para asegurar un servicio web/API REST



web api tutorial español (18)

Al diseñar una API o servicio REST, ¿existen las mejores prácticas establecidas para tratar con la seguridad (autenticación, autorización, gestión de identidad)?

Al crear una API SOAP, tiene WS-Security como guía y existe mucha literatura sobre el tema. He encontrado menos información sobre cómo asegurar los puntos finales REST.

Aunque entiendo que REST intencionalmente no tiene especificaciones análogas a WS- *, espero que hayan surgido las mejores prácticas o los patrones recomendados.

Cualquier discusión o enlaces a documentos relevantes serían muy apreciados. Si importa, estaríamos usando WCF con mensajes serializados POX / JSON para nuestros API / servicios REST creados con v3.5 de .NET Framework.


Busqué mucho sobre la seguridad de ws de descanso y también terminamos usando token a través de cookies del cliente al servidor para autenticar las solicitudes. Utilicé Spring Spring para la autorización de solicitudes en servicio porque tuve que autenticar y autorizar cada solicitud en función de políticas de seguridad específicas que ya se encontraban en DB.


Como @Nathan terminó con lo que es un simple encabezado HTTP, y algunos habían dicho OAuth2 y certificados SSL del lado del cliente. La esencia de esto es que ... tu API REST no debería tener que manejar la seguridad, ya que realmente debería estar fuera del alcance de la API.

En su lugar, se debe colocar una capa de seguridad, ya sea un encabezado HTTP detrás de un proxy web (un enfoque común como SiteMinder, Zermatt o incluso Apache HTTPd), o tan complicado como OAuth 2.

La clave es que las solicitudes deben funcionar sin ninguna interacción del usuario final. Todo lo que se necesita es asegurarse de que la conexión a la API REST esté autenticada. En Java EE tenemos la noción de un userPrincipal que puede obtenerse en un HttpServletRequest . También se administra en el descriptor de implementación que un patrón de URL puede ser seguro, por lo que el código de la API REST ya no necesita ser revisado.

En el mundo de WCF, usaría ServiceSecurityContext.Current para obtener el contexto de seguridad actual. Necesitas configurar tu aplicación para requerir autenticación.

Hay una excepción a la declaración que tenía arriba y es el uso de un nonce para evitar las repeticiones (que pueden ser ataques o que alguien simplemente envíe los mismos datos dos veces). Esa parte solo puede ser manejada en la capa de aplicación.


Como dijo Tweakt, Amazon S3 es un buen modelo para trabajar. Sus firmas de solicitud tienen algunas características (como la incorporación de una marca de tiempo) que ayudan a protegerse contra la reproducción accidental y maliciosa de solicitudes.

Lo bueno de HTTP Basic es que prácticamente todas las bibliotecas HTTP lo admiten. Por supuesto, deberá requerir SSL en este caso porque el envío de contraseñas de texto simple a través de la red es casi universalmente algo malo. Básico es preferible a Digest cuando se usa SSL porque incluso si la persona que llama ya sabe que se requieren credenciales, Digest requiere un viaje de ida y vuelta adicional para intercambiar el valor de nonce. Con Basic, las personas que llaman simplemente envían las credenciales la primera vez.

Una vez que se establece la identidad del cliente, la autorización es realmente solo un problema de implementación. Sin embargo, podría delegar la autorización a algún otro componente con un modelo de autorización existente. Una vez más, lo bueno de Basic es que su servidor termina con una copia de texto simple de la contraseña del cliente que simplemente puede pasar a otro componente dentro de su infraestructura según sea necesario.


El hecho de que el mundo SOAP esté bastante bien cubierto con los estándares de seguridad no significa que esté seguro de forma predeterminada. En primer lugar, los estándares son muy complejos. La complejidad no es un buen amigo de la seguridad y las vulnerabilidades de implementación, como los ataques de ajuste de firma XML, son endémicas aquí.

En cuanto al entorno .NET, no ayudaré mucho, pero "Crear servicios web con Java" (un bloque con ~ 10 autores) me ayudó mucho a comprender la arquitectura de seguridad WS- * y, especialmente, sus peculiaridades.


Estoy un poco sorprendido SSL con certificados de cliente no se ha mencionado todavía. Por supuesto, este enfoque solo es realmente útil si se puede contar con la comunidad de usuarios que se identifican mediante certificados. Pero varios gobiernos / empresas sí los emiten a sus usuarios. El usuario no tiene que preocuparse por crear otra combinación de nombre de usuario / contraseña, y la identidad se establece en todas y cada una de las conexiones, por lo que la comunicación con el servidor puede ser completamente sin estado, no se requieren sesiones de usuario. (No implica que cualquiera o todas las otras soluciones mencionadas requieran sesiones)


Gracias por el excelente consejo. Terminamos usando un encabezado HTTP personalizado para pasar un token de identidad del cliente al servicio, en preparación para integrar nuestra API RESTful con el próximo marco de Zermatt Identity de Microsoft. He descrito el problema here y nuestra solución here . También tweakt el consejo de tweakt y compré los servicios web RESTful , un libro muy bueno si estás creando una API RESTful de cualquier tipo.


Ha pasado un tiempo, pero la pregunta sigue siendo relevante, aunque la respuesta podría haber cambiado un poco.

Una API Gateway sería una solución flexible y altamente configurable. Probé y usé KONG bastante y realmente me gustó lo que vi. KONG proporciona una API de REST de administración propia que puede utilizar para administrar usuarios.

Express-gateway.io es más reciente y también es una puerta de enlace API.


Hay una gran lista de verificación encontrada en Github :

Autenticación

  • No reinvente la rueda en Autenticación, generación de tokens, almacenamiento de contraseñas. Usa los estándares.

  • Utilice Max Retry y funciones de la cárcel en Iniciar sesión.

  • Utilice el cifrado en todos los datos confidenciales.

JWT (token web JSON)

  • Use una clave aleatoria y complicada (JWT Secret) para hacer que la fuerza bruta obligue a la ficha muy fuerte.

  • No extraiga el algoritmo de la carga útil. Forzar el algoritmo en el backend (HS256 o RS256).

  • Haga que la caducidad del token ( TTL , RTTL ) sea lo más corta posible.

  • No almacene datos confidenciales en la carga útil de JWT , se puede descodificar fácilmente.

OAuth

  • Valide siempre el lado del servidor redirect_uri para permitir solo las URL incluidas en la lista blanca.

  • Siempre intente intercambiar por código y no tokens (no permita response_type=token ).

  • Utilice el parámetro de estado con un hash aleatorio para evitar CSRF en el proceso de autenticación de OAuth .

  • Defina el alcance predeterminado y valide los parámetros del alcance para cada aplicación.

Acceso

  • Limite las solicitudes (Limitación) para evitar los ataques DDoS / fuerza bruta.

  • Use HTTPS en el lado del servidor para evitar MITM (Man In The Middle Attack)

  • Utilice el encabezado HSTS con SSL para evitar el ataque de tira de SSL.

Entrada

  • Use el método HTTP adecuado de acuerdo con la operación: GET (leer), POST (crear), PUT/PATCH (reemplazar / actualizar) y DELETE (para eliminar un registro), y responda con 405 Method Not Allowed si el método solicitado no es No es apropiado para el recurso solicitado.

  • Valide el tipo de contenido a petición. Accept encabezado (Negociación de contenido) para permitir solo su formato compatible (por ejemplo, application/xml , application/json , etc.) y responder con 406 Not Acceptable Respuesta 406 Not Acceptable si no coincide.

  • Valide content-type de content-type de los datos publicados como acepta (por ejemplo, application/x-www-form-urlencoded , multipart/form-data , application/json , etc.).

  • Valide la entrada del usuario para evitar vulnerabilidades comunes (por ejemplo, XSS, inyección de SQL, ejecución remota de código, etc.).

  • No utilice datos confidenciales (credenciales, contraseñas, tokens de seguridad o claves de API) en la URL, pero use el encabezado de Authorization estándar.

  • Use un servicio de puerta de enlace API para habilitar el almacenamiento en caché, las políticas de Rate Limit (por ejemplo, cuota, arresto de espiga, límite de tasa concurrente) y despliegue los recursos de las API dinámicamente.

Tratamiento

  • Compruebe si todos los puntos finales están protegidos detrás de la autenticación para evitar un proceso de autenticación defectuoso.

  • Se debe evitar el ID del recurso propio del usuario. Use / me / orders en lugar de / user / 654321 / orders.

  • No incremente automáticamente las ID. Use UUID en su lugar.

  • Si está analizando archivos XML, asegúrese de que el análisis de entidad no esté habilitado para evitar XXE (ataque de entidad externa XML).

  • Si está analizando archivos XML, asegúrese de que la expansión de la entidad no esté habilitada para evitar la bomba Billion Laughs / XML a través del ataque de expansión de la entidad exponencial.

  • Use un CDN para subir archivos.

  • Si está manejando una gran cantidad de datos, use Trabajadores y Colas para procesar la mayor cantidad posible en segundo plano y responda rápidamente para evitar el Bloqueo HTTP.

  • No te olvides de desactivar el modo DEBUG .

Salida

  • Enviar X-Content-Type-Options: nosniff encabezado X-Content-Type-Options: nosniff .

  • Enviar X-Frame-Options: deny encabezado.

  • Enviar Content-Security-Policy: default-src ''none'' encabezado Content-Security-Policy: default-src ''none'' .

  • Elimine los encabezados de huellas digitales - X-Powered-By , Server , X-AspNet-Version etc.

  • Forzar content-type de content-type para su respuesta, si devuelve application/json entonces su tipo de contenido de respuesta es application/json .

  • No devuelva datos confidenciales como credenciales, contraseñas, tokens de seguridad.

  • Devuelva el código de estado correcto de acuerdo con la operación completada. (por ejemplo, 200 OK , 400 Bad Request , 401 Unauthorized , 405 Method Not Allowed , etc.).


He usado OAuth unas cuantas veces y también he usado algunos otros métodos (BÁSICO / DIGESTADO). De todo corazón sugiero OAuth. El siguiente enlace es el mejor tutorial que he visto sobre el uso de OAuth:

http://hueniverse.com/oauth/guide/


No hay estándares para REST que no sean HTTP. Hay servicios REST establecidos por ahí. Le sugiero que les eche un vistazo y les dé una idea de cómo funcionan.

Por ejemplo, tomamos prestadas muchas ideas del servicio S3 REST de Amazon cuando desarrollamos las nuestras. Pero optamos por no utilizar el modelo de seguridad más avanzado basado en firmas de solicitud. El enfoque más simple es la autenticación HTTP básica sobre SSL. Tienes que decidir qué funciona mejor en tu situación.

Además, recomiendo altamente el libro RESTful Web Services de O''reilly. Explica los conceptos básicos y proporciona algunas de las mejores prácticas. En general, puede tomar el modelo que proporcionan y asignarlo a su propia aplicación.


OWASP (Open Web Application Security Project) tiene algunas hojas de trucos que cubren todos los aspectos del desarrollo de aplicaciones web. Este proyecto es una fuente de información muy valiosa y confiable. Con respecto a los servicios REST, puede consultar esto: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet


Para la seguridad de la aplicación web, debería echar un vistazo a OWASP ( https://www.owasp.org/index.php/Main_Page ) que proporciona hojas de trucos para varios ataques de seguridad. Puede incorporar tantas medidas como sea posible para asegurar su aplicación. Con respecto a la seguridad de la API (autorización, autenticación, gestión de identidad), hay varias formas como ya se ha mencionado (Básico, Digest y OAuth). Hay orificios de bucle en OAuth1.0, por lo que puede usar OAuth1.0a (OAuth2.0 no se adopta ampliamente debido a preocupaciones con la especificación)


Quiero agregar (en línea con stinkeymatt), la solución más simple sería agregar certificados SSL a su sitio. En otras palabras, asegúrese de que su url sea HTTPS: //. Eso cubrirá su seguridad de transporte (bang for the buck). Con RESTful url''s, la idea es mantenerlo simple (a diferencia de WS * security / SAML), puede usar oAuth2 / openID connect o incluso Basic Auth (en casos simples). Pero todavía necesitará SSL / HTTPS. Consulte la seguridad de la API web 2 de ASP.NET aquí: http://www.asp.net/web-api/overview/security (Artículos y videos)


REST no ofrece estándares de seguridad, pero cosas como OAuth y SAML se están convirtiendo rápidamente en los estándares en este espacio. Sin embargo, la autenticación y la autorización son solo una pequeña parte de lo que debe considerar. Muchas de las vulnerabilidades conocidas relacionadas con las aplicaciones web se aplican mucho a las API REST. Debe considerar la validación de entrada, el agrietamiento de sesión, los mensajes de error inapropiados, las vulnerabilidades internas de los empleados, etc. Es un gran tema.


También puede querer echar un vistazo a OAuth , un protocolo abierto emergente para la autorización basada en token que apunta específicamente a las apis de http.

Es muy similar al enfoque adoptado por flickr y recuerda los apis de "descanso" de la leche (no necesariamente buenos ejemplos de apis tranquilos, pero buenos ejemplos del enfoque basado en token).


Todos en estas respuestas han pasado por alto el verdadero control / autorización de acceso.

Si, por ejemplo, sus API / servicios web REST se refieren a POSTAR / OBTENER registros médicos, es posible que desee definir la política de control de acceso sobre quién puede acceder a los datos y en qué circunstancias. Por ejemplo:

  • los médicos pueden OBTENER el registro médico de un paciente con el que tienen una relación de cuidado
  • nadie puede POSTAR datos médicos fuera de las horas de práctica (por ejemplo, 9 a 5)
  • los usuarios finales pueden OBTENER los registros médicos que poseen o los registros médicos de los pacientes para los que son el tutor
  • las enfermeras pueden ACTUALIZAR el registro médico de un paciente que pertenece a la misma unidad que la enfermera.

Para definir e implementar esas autorizaciones detalladas, deberá utilizar un lenguaje de control de acceso basado en atributos llamado XACML, el lenguaje de marcado de control de acceso extensible.

Los otros estándares aquí son para lo siguiente:

  • OAuth: id. federación y delegación de autorización, por ejemplo, dejar que un servicio actúe en mi nombre en otro servicio (Facebook puede publicar en mi Twitter)
  • SAML: federación de identidades / web SSO. SAML tiene mucho que ver con quién es el usuario.
  • Estándares WS-Security / WS- *: estos se centran en la comunicación entre los servicios SOAP. Son específicos del formato de mensajería a nivel de la aplicación (SOAP) y tratan aspectos de la mensajería, por ejemplo, confiabilidad, seguridad, confidencialidad, integridad, atomicidad, eventos ... Ninguno cubre el control de acceso y todos son específicos de SOAP.

XACML es tecnología-agnóstica. Se puede aplicar a aplicaciones Java, .NET, Python, Ruby ... servicios web, API REST y más.

Los siguientes son recursos interesantes:


Uno de los mejores mensajes que he visto sobre la seguridad en lo que se refiere a REST se encuentra en 1 RainDrop . La API de MySpace usa OAuth también para seguridad y usted tiene acceso completo a sus canales personalizados en el código RestChess, con el que exploré mucho. Esto se demostró en Mix y puede encontrar la publicación here .