73

Estoy construyendo una aplicación web con una capa de servicios. La capa de servicios se construirá utilizando un diseño RESTful. La idea es que en algún momento en el futuro podamos construir otras aplicaciones (iPhone, Android, etc.) que usen la misma capa de servicios que la aplicación web. Mi pregunta es esta: ¿cómo implemento el inicio de sesión? Creo que tengo problemas para pasar de un diseño basado en verbos más tradicional a un diseño basado en recursos. Si estuviera compilando esto con SOAP, probablemente tendría un método llamado Login. En REST debería tener un recurso. Tengo dificultades para entender cómo debería construir mi URI para iniciar sesión. ¿Debería ser algo como esto:¿Cómo implemento el inicio de sesión en un servicio web RESTful?

http://myservice/ {usuario} = {p} contraseña

EDIT:? La aplicación web extremo frontal utiliza el marco ASP.NET para la autenticación tradicional. Sin embargo, en algún momento del proceso de autenticación, necesito validar las credenciales proporcionadas. En una aplicación web tradicional haría una búsqueda en la base de datos. Pero en este escenario estoy llamando a un servicio en lugar de hacer una búsqueda en la base de datos. Entonces necesito algo en el servicio que validará las credenciales proporcionadas. Y además de validar las credenciales proporcionadas, probablemente también necesite algún tipo de información sobre el usuario después de que se hayan autenticado con éxito, como su nombre completo, su ID, etc. Espero que esto aclare la pregunta.

¿O no estoy pensando en esto de la manera correcta? Siento que estoy teniendo dificultades para describir mi pregunta correctamente.

Corey

Respuesta

55

Como S. Lott señaló ya, tenemos dos cosas dobladas aquí: Inicio de sesión y autenticación

La autenticación es fuera del alcance de este trabajo, ya que es ampliamente discutido y hay un acuerdo común. Sin embargo, ¿qué necesitamos realmente para que un cliente se autentique con éxito contra un servicio web RESTful? Bien, algún tipo de token, vamos a llamarlo token de acceso.

Cliente) Entonces, todo lo que necesito es un token de acceso, pero ¿cómo obtenerlo con tanto REST?
Servidor) ¿Por qué no simplemente crearlo?
Cliente) ¿Cómo viene?
Servidor) Para mí, un token de acceso no es más que un recurso. Por lo tanto, crearé uno para usted a cambio de su nombre de usuario y contraseña.

De este modo, el servidor podría ofrecer la URL de recursos "/ accesstokens", por publicar el nombre de usuario y contraseña para, volviendo el enlace al recurso recién creado "/ accesstokens/{} accessToken". Alternativamente, se vuelve un documento que contiene el acceso token y a href con el enlace del recurso:

 
<access-token 
    id="{access token id goes here; e.g. GUID}" 
    href="/accesstokens/{id}" 
/> 

Lo más probable es que no crea realmente el token de acceso como subrecurso y por lo tanto, no incluirá su href en la respuesta.
Sin embargo, si lo hace, el cliente podría generar el enlace en su nombre o no? ¡No!
Recuerde, los servicios web realmente RESTful unen recursos de una manera que el cliente puede navegar por sí mismo sin la necesidad de generar ningún enlace de recursos.

La última pregunta que probablemente tenga es si debe ENVIAR el nombre de usuario y la contraseña como un formulario HTML o como un documento, p. XML o JSON - que depende ... :-)

+3

No se sigue perfectamente el REST, pero es simple y medible mejor que otros. Plus compartido con buen humor. –

+1

Patrick, ¿estás proponiendo lo mismo que esta respuesta? http://stackoverflow.com/a/1135995/14731 – Gili

+0

¿El código de estado 403 es correcto cuando el nombre de usuario y/o la contraseña no coinciden? – sevteen

-4

He tenido el mismo problema antes. El inicio de sesión no se adapta bien al diseño basado en recursos.

La forma en que manejan generalmente es por tener los recursos de sesión y pasando nombre de usuario y contraseña en la cadena de parámetros, básicamente haciendo

conseguir en http://myservice/login?u= {usuario} & p = {password}

La respuesta es algún tipo de sesión o cadena de autenticación que luego se puede pasar a otras API para su validación.

Una alternativa para hacer OBTENER en el recurso de inicio de sesión está haciendo un POST, REST los puristas probablemente ya no me quieran :), y pasen los creds en el cuerpo. La respuesta sería la misma.

+11

contraseña? ¿Clave de texto sin formato?Como una cadena de consulta? ¿De verdad quiso decir eso, o quiere decir un resumen de la contraseña? –

+0

Gracias. Eso tiene sentido. Aquí hay una pregunta de seguimiento: para una aplicación grande, ¿crearía un gran servicio RESTful para todo o dividiría las cosas en diferentes servicios? Estaba pensando en tener un servicio solo para autenticación y luego diferentes servicios para los diferentes módulos de mi aplicación. ¿Hay alguna razón por la que lo haría o no lo haría de una manera u otra? –

+2

S. Lott: Depende de lo que trates de hacer. Por supuesto, si puedes hacer un resumen, entonces por supuesto. A veces, un resumen no es posible. Si la única opción abierta para usted es enviar una contraseña de texto sin formato, hágalo a través de SSL, en este caso también es mejor utilizar un POST en lugar de GET para evitar que el navegador recuerde lo que envió. – Alex

22

Usted no "inicia sesión". Usted "autentica". Mundo de la diferencia

Tiene muchas alternativas de autenticación.

HTTP Basic, Digest, NTLM and AWS S3 Authentication

  • básica HTTP y la autenticación implícita. Esto usa el encabezado HTTP_AUTHORIZATION. Esto es muy lindo, muy simple. Pero puede generar mucho tráfico.

  • Autenticación de nombre de usuario/firma. A veces se llama autenticación "ID y KEY". Esto puede usar una cadena de consulta.

    ?username=this&signature=some-big-hex-digest

    Esto es lo coloca como el uso de Amazon. El nombre de usuario es el "id". La "clave" es un resumen, similar al utilizado para la autenticación HTTP Digest. Ambas partes tienen que acordar el resumen para proceder.

  • Algún tipo de autenticación basada en cookies. OpenAM, por ejemplo, se puede configurar como un agente para autenticar y proporcionar una cookie que tu servidor web RESTful puede usar. El cliente se autentica primero y luego proporciona la cookie con cada solicitud RESTful.

+0

Quizás necesito aclarar mi pregunta. Los usuarios que visiten el sitio web no interactuarán directamente con el servicio RESTful. Ellos interactuarán con la aplicación web. Por lo tanto, cuando un usuario intenta iniciar sesión en la aplicación web, la aplicación web realiza una llamada al servicio web (usando el código C#). Luego, según la respuesta del servicio web, el código ingresará o no a la aplicación web. ¿Tiene sentido? No estoy seguro de si los métodos de autenticación que sugirió funcionarán, ya que el navegador del usuario no interactúa directamente con el servicio. –

+0

@Corey Burnett: Correcto. Los usuarios no pueden interactuar con un servicio web RESTful. Correcto. Las aplicaciones web llaman a servicios web. Todos estos métodos están diseñados específicamente para que una aplicación C# realice una solicitud RESTful con las credenciales adecuadas y obtenga una respuesta. Un servicio web RESTful nunca maneja el "inicio de sesión" porque no tiene sesiones. Puede manejar la autenticación al aceptar que la solicitud es válida. Tenemos una solicitud "ficticia" que simplemente responde con un "200 OK" si las credenciales son buenas. –

+2

@ S.Lott @Corey Los usuarios absolutamente pueden interactuar con los sistemas RESTful. La mayoría de los sitios web HTML estáticos son RESTful "servicios". –

0

Desde un poco ha cambiado desde 2011 ...

Si usted está abierto a la utilización de una herramienta de tercera parte, y ligeramente desviarse ligeramente de REST la interfaz de usuario web, considere http://shiro.apache.org.

Shiro básicamente le proporciona un filtro de servlet para autenticación y autorización. Puede utilizar todos los métodos de inicio de sesión enumerados por @ S.Lott, incluida una autenticación basada en formularios simples.

Filtra el resto de las URL que requieren autenticación, y Shiro hará el resto.

Actualmente estoy usando esto en mi propio proyecto y me ha funcionado bastante bien hasta ahora.

Aquí es algo que la gente más puede interesarle. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme

1

Gran pregunta, bien planteado. Realmente me gusta la respuesta de Patrick.Yo uso algo así como

-/usuarios/{nombre de usuario}/loginsession

Con POST y GET que se manejan. Entonces publico una nueva sesión con credenciales y puedo ver la sesión actual como un recurso a través de GET.

El recurso es una sesión de inicio de sesión, y que puede tener un token de autenticación o código, caducidad, etc.

extraño que parezca el acceso, de llamante MVC debe presentar en sí un símbolo de clave/al portador a través de una cabecera para demostrar que tiene derecho a intentar crear nuevas sesiones de inicio de sesión ya que el sitio MVC es un cliente de la API.

Editar

Creo que algunas otras respuestas y comentarios aquí están resolviendo el problema con una banda fuera de secreto compartido y justo autenticación con una cabecera. Eso está bien en muchas situaciones o para llamadas de servicio a servicio.

La otra solución es enviar un token, OAuth o JWT u otros, lo que significa que el "inicio de sesión" ya ha tenido lugar por otro proceso, probablemente una IU de inicio de sesión normal en un navegador basado en un formulario POST.

Mi respuesta es para el servicio que se encuentra detrás de la interfaz de usuario, asumiendo que usted quiere iniciar la sesión y autenticación y gestión de usuarios colocado en un servicio REST y no en el código MVC sitio. ES el servicio de inicio de sesión de usuario.

También permite a otros servicios "login" y obtener un token de expirar, en lugar de utilizar una clave previamente compartida, así como scripts de prueba en un CLI o cartero.

+2

Pase la ficha en un encabezado, sí. Pasarlo como parte de la URL, no. La URL se cifra en tránsito cuando usa HTTPS. Sin embargo; la URL también se almacena en el historial del navegador y en los registros del servidor. Hay muchas buenas razones para evitar pasar datos sensibles a la seguridad en los parámetros de consulta de URL. – Craig

0

Lo primero que debe entender acerca resto es que es un recurso basado simbólico access.Unlike formas tradicionales, se concede el acceso basado en la validación de token. En palabras simples, si tiene el token derecho, puede acceder a los recursos. Ahora hay muchas otras cosas para la creación y manipulación de tokens.

Para su primera pregunta, puede diseñar una API Restfull. Las credenciales (nombre de usuario y contraseña) se pasarán a su capa de servicio. Capa de servicio luego valida estas credenciales y otorga un token. Las credenciales pueden ser simples nombre de usuario/contraseña o pueden ser certificados SSL. Los certificados SSL usan el protocolo OAUTH y son más seguros.

Puede diseñar su URI como este- URI para solicitud de token->http://myservice/some-directory/token? (Puede pasar Credentilals en este URI para Token)

Para usar este token para el acceso a los recursos, puede agregar esto [Authorization: Bearer (token)] a su encabezado http.

Este token puede ser utilizado por el cliente para acceder a diferentes componentes de su capa de servicio. También puede cambiar el período de caducidad de este token para evitar el uso indebido.

Para su segunda pregunta, una cosa que puede hacer es otorgar token diferente para acceder a diferentes componentes de recursos de su capa de servicio. Para esto puede especificar un parámetro de recurso en su token y un gran permiso basado en este campo.

También puede seguir estos enlaces para obtener más detallada http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

Cuestiones relacionadas