Estoy en el proceso de diseñar 3 componentes que funcionarán en sinfonía entre ellos:
- Un servicio web RESTful que requiere
BasicAuth
más de HTTPS en todas las llamadas, y que es lo que realmente hace todo el trabajo pesado para mi sistema (hace el trabajo) - Una interfaz de usuario web que traduce las acciones del usuario final en llamadas API al servicio web mencionado anteriormente; por lo tanto, la interfaz de usuario está "respaldada" por el WS
- Una herramienta de interfaz de línea de comandos (CLI) que los desarrolladores pueden instalar y ejecutar localmente, que también traduce comandos en llamadas API a la WS (por lo tanto, también está "respaldada por" la WS)
Uno de los primeros obstáculos que estoy tratando de cruzar es con respecto a la autenticación y autorización.
Supongamos que WS utiliza un servicio de directorio / LDAP (como AD o quizás Apache DS) como su dominio de autenticación. Es decir, cuando se recibe una llamada API por cable (por ejemplo, un HTTPS GET
recurso), las BasicAuth
credenciales se extraen de la solicitud y se reenvían al servicio LDAP para determinar si se trata de un usuario válido o no. Si están autenticados, digamos que se utiliza un dominio de autorización separado, tal vez una base de datos, para determinar si el usuario identificado puede hacer lo que está intentando en la solicitud HTTPS. Hasta aquí todo bien.
En el caso de la herramienta CLI, el usuario tendrá que autenticarse antes de ejecutar cualquier comando, por lo que este modelo funciona bien, ya que un solo usuario solo operará la misma instancia de CLI en un momento dado.
El problema surge cuando intentamos integrar la aplicación web (UI) con el WS, porque muchas personas pueden iniciar sesión en la aplicación al mismo tiempo, todos con diferentes permisos que dictan qué llamadas API subyacentes se les permite hacer.
Por lo que veo, parece que tengo solo 4 opciones aquí:
- Credenciales en caché : después de iniciar sesión en la aplicación, las credenciales se almacenan de alguna manera en caché (de modo que la aplicación tenga acceso a ellas), y la aplicación no aplica ningún tipo de política de autorización. Cuando los usuarios intentan hacer cosas que generan llamadas API bajo el capó, sus credenciales se buscan desde la caché y se reenvían con las llamadas API. Si el WS determina que no están autorizados, devuelve un error.
- Cuentas de nivel de servicio : la aplicación y el WS usan los mismos reinos de autenticación / autorización, excepto que la interfaz de usuario web ahora impone la autorización sobre lo que los usuarios pueden ver y hacer dentro de la aplicación. Si se les permite hacer algo que genera una llamada API subyacente, la aplicación envía las credenciales de la cuenta de servicio (por ejemplo
myapp-admin-user
) con cada llamada API en nombre del usuario. - OAuthv2 : No tengo idea de qué es OAuth o si es aplicable para este escenario, pero siento que puede ser una solución aquí de alguna manera.
- Servidores de tokens: use un servidor de tokens como CAS o tal vez Kerberos para garantizar a los usuarios, de manera similar a como se comporta la opción Cuenta de nivel de servicio. Aquí, cuando un usuario inicia sesión con éxito en la aplicación, el servidor de tokens envía a la aplicación un UUID de sesión y también registra ese UUID con el WS. Cada vez que la aplicación genera una llamada API, agrega el UUID a la solicitud, que luego se valida en el lado de WS.
La opción " Credenciales almacenadas en caché " se siente como una aberración de todo lo que es bueno y saludable en la tierra de seguridad. Simplemente se siente mal almacenar las credenciales en cualquier lugar, nunca.
El " Token Servidor opción" parece válido para una configuración de tipo SSO, pero no en este caso en particular y se siente incómodo para mí. También creo que no hay una buena manera de usar el concepto UUID de sesión y BasicAuth
/ HTTPS al mismo tiempo.
Así que esto deja a OAuthv2, de la que no sé nada, y " Cuenta de nivel de servicio (SLA) * " como las únicas opciones restantes. La opción SLA parece estar bien, pero tiene algunos inconvenientes siguientes:
- Requiere que la cuenta de servicio tenga básicamente "privilegios de Dios" sobre el WS. En otras palabras, una vez que la aplicación considera que un usuario puede hacer clic en un botón o hacer algo en la interfaz de usuario, eso se traduce en una llamada API incondicional por parte de la cuenta de servicio utilizada por la interfaz de usuario. Esto se siente mal, mkay?
- Se me ocurre que mantener dos conjuntos de permisos (el conjunto de permisos para cada usuario de la aplicación, y luego el conjunto de permisos para la cuenta de servicio utilizada por la aplicación contra el WS) puede dar como resultado que los permisos no estén sincronizados entre sí de algun modo
Parece que realmente no tengo buenas opciones aquí. Seguramente no puedo ser el primer desarrollador en toparse con esto, pero preguntarle a los Dioses de Google no me ha ayudado mucho aquí. ¿Algunas ideas?