2011-12-22 19 views
12

He estado atormentando mi cerebro y buscando en Google durante años sin encontrar una forma satisfactoria de manejar esto. Quiero escribir un buen servicio completamente RESTful para devolver recursos, pero los datos tienen permiso para leer (o escribir) variest por recurso en función de su función. Entonces, por ejemplo, un usuario puede ver su número de teléfono privado en su perfil, y también un administrador del sitio, pero otro no. Es posible que un visitante anónimo no pueda ver el nombre real de otro usuario, pero otros usuarios (y el administrador del sitio) podrían hacerlo. Existen alrededor de 4 o 5 niveles de acceso y reglas sobre qué atributos se pueden leer o escribir. La escritura con la que estoy contento ya que el cliente puede PONER los cambios y el servidor no está obligado a aceptarlos todos (o en absoluto), pero la lectura es mi problema.¿Cómo se representa el control de acceso a nivel de atributo RESTful?

<user> 
<id>jimbob</id> 
<real-name>Jim Roberts</real-name> <!-- only logged-in users should see this --> 
<phone-number>+1 42424151</phone-number> <!-- only the user and admin users should see this --> 
</user> 

Quiero tener un recurso de perfil de usuario correctamente puede almacenar en caché que contiene todos los datos públicos, pero ¿cómo puedo modelar todas las cosas que sólo determinados usuarios puedan ver? Podría hasta 4 enlaces a información adicional, la mayoría de los cuales devolvería errores no autorizados para la mayoría de los usuarios, con cada enlace con la información adicional relacionada con un rol. Pero eso parece muy ineficiente y también vincula a los clientes con el concepto de rol, cuando anteriormente todo lo que necesitaban saber era usuarios. ¿Hay mejores ideas?

<user> 
<id>...</id> 
<link rel="more" href="extra-user-profile-data-for-logged-in-users"/> 
<link rel="more" href="extra-user-profile-data-for-senior-users"/> 
<link rel="more" href="extra-user-profile-data-for-admin-users"/> 
<link rel="more" href="extra-user-profile-data-for-superadmin-users"/> 
</user> 

Tenga en cuenta - No estoy luchando con cualquiera de

  • autenticación
  • control de acceso
  • a nivel de recursos
  • Implementación del control de acceso o autorización en el lado del servidor

Estoy luchando con

  • Cómo representar los recursos que en un sitio HTML "normal" parecerían diferentes a diferentes personas, de una manera verdaderamente RESTful.

Parece un problema muy común que todos deben tener, pero no encuentro nada en él. ¡Por favor ayuda!

+0

Creo que es apropiado omitir los elementos XML que corresponden a las propiedades que el usuario no está autorizado a ver. Creo que eso concuerda con la cantidad de aplicaciones web basadas en roles que presentan datos en formularios HTML. – EJK

+0

Sin embargo, hace que sea descartable ya que los datos públicos se mezclarían con algún subconjunto (desconocido) de datos restringidos en la misma representación (en caché). –

+0

me parece un problema simple. 1. el usuario se autentica. 2. el usuario solicita un URI 3. el mecanismo de control de acceso que ha implementado inicia y atrapa la solicitud de URI. 4. el monitor de recursos crea una plantilla de los datos que se devolverán al usuario solicitante. esta plantilla actúa como un ticket de algún tipo. 5. El servicio cumple con la solicitud del usuario especificada por el URI en función de la plantilla que recibió del monitor de recursos. 6. El servicio devuelve el resultado al usuario. hmmmm – ultrajohn

Respuesta

8

Si se piensa en ello, el recurso User que ve un cliente de administración (con todos los campos visibles) es exactamente el mismo recurso que ve un cliente anónimo o con menos privilegios. El URI es idéntico, pero la representación que ven es diferente.

Es similar a hacer que el cliente solicite que la representación esté codificada en JSON en lugar de XML a través del encabezado Accept: el servidor puede aceptar esa solicitud pero no necesariamente tiene que hacerlo. En su caso, el servidor debe devolver una representación adecuada a las credenciales proporcionadas por el cliente.

Por lo tanto, un administrador puede recibir el contenido dentro de un tipo de medio de application/vnd.yourcompany.user.full+xml como el cuerpo devuelto por un GET en su recurso User, y contendrá todos los campos posibles.

Sin embargo, un usuario anónimo podría recibir la carga codificada como, por ejemplo, application/vnd.yourcompany.user.limited+xml que su documentación describiría claramente como una representación que puede contener o no todos los elementos de la versión full. El cliente debería usar un decodificador o esquema flexible que tolere que ciertos elementos no estén presentes.

Como alternativa, puede devolver toda la información del recurso pero el uso de un valor de campo especial para indicar que un valor particular fue redactada:

<user> 
<id>jimbob</id> 
<real-name>--FORBIDDEN--</real-name> 
</user> 

Se puede crear un tipo de papel para cada rol, pero eso sería introducir un un fuerte acoplamiento entre su esquema de seguridad y sus representaciones, y eso probablemente no sea deseable. Los esquemas flexibles de representación que usan omisión de campo o redacción de valor serían más fáciles de mantener a largo plazo.

La decisión final es si devolverá o no enlaces a otros recursos que no serían navegables según las credenciales proporcionadas por el cliente. En mi opinión, esos enlaces deberían devolverse siempre, incluso si esas credenciales no funcionarían. ¿Por qué? Debido a que el cliente teóricamente puede proporcionar otras credenciales al llamar a esos URI. Incluso si no lo hacen, el desafío 401 resultante podría llevar al cliente a proporcionarlos. Pero si nunca reciben el URI, se les impediría tomar esa decisión.

+0

Gracias por la respuesta detallada y considerada. El problema con el tipo de medios 'limitado' es que el contenido aún podría variar por rol y, por lo tanto, no se puede descartar. Como el mismo tipo de cosas se aplica a casi todos los recursos en mi sistema, esto sería un gran golpe de rendimiento. Tiene razón en que no queremos unir roles con los tipos de medios. Me gusta la idea de reducir el problema a representaciones alternativas, eso tiene sentido, pero todavía no veo la solución práctica desafortunadamente. ¿Podría haber algún encabezado en la respuesta (pero no en la Autorización) referenciado con un encabezado Vary para el almacenamiento en caché? –

+0

Idealmente me gustaría asegurar que todo lo que se sirve tenga una representación públicamente almacenable en caché para los datos públicos y una representación en caché privada para los datos específicos de la función, de modo que vuelva a golpear el sistema para el mismo recurso desde la misma el origen obtiene todo de la memoria caché. –

Cuestiones relacionadas