2011-08-28 11 views
15

Actualmente estoy escribiendo una API de reposo en python con el frasco de microframework. Es una API privada y se trata de datos de usuario. Planeo usar esta API para construir una aplicación web y Android.Buscando asesoramiento para asegurar una API REST privada escrita en python-matraz

Por el momento, uso la función de autorizar automáticamente para proteger los datos privados de los usuarios. Por ejemplo, si desea publicar datos en mi servicio con el bob del usuario, realice una solicitud posterior en myapi/story/create y proporcione las credenciales de bob con el patrón de resumen.

Soy consciente de que esto no es una buena solución porque:
auth -Digest no es segura
-El cliente no se autentica (? ¿Cómo asegurar las solicitudes que no están relacionadas con el usuario actual, por ejemplo crear un nuevo usuario)

He leído muchas cosas sobre oAuth pero la autenticación de 3 patas parece excesiva porque no planeo abrir mi API a un tercero.
El oAuth de 2 patas no se ajusta porque solo proporciona autenticación para los clientes y no para los usuarios.
Otro problema con oAuth es que no he encontrado una guía completa para implementarlo en Python. Encontré la biblioteca python-oauth2, pero no entiendo el ejemplo del servidor y no puedo encontrar documentación adicional. Además, parece que muchos aspectos de OAuth no están cubiertos en este ejemplo.

Así que mis preguntas son:

  1. ¿Hay esquema alternativo (no OAuth) para autenticar el cliente y el usuario con un nivel razonable de seguridad?
  2. Si oAuth es la mejor solución:
    • Cómo omitir el proceso de autorización (porque los usuarios no tendrán que autorizar a clientes de terceros)?
    • ¿Hay documentación detallada para python-oauth2 o para cualquier otra biblioteca de Python?

Cualquier ayuda o consejo será apreciado.

+0

Con respecto a uno de sus problemas, una gran parte de los principales sitios web no deje que se suscribe a través del cliente etc., hacerte registrarte a través de su sitio web. Para aquellos sitios que sí lo permiten, su llamada API es efectivamente lo mismo que su formulario de suscripción, por lo que no importa si es seguro o no. –

Respuesta

7

La respuesta simple es exponer su API a través de HTTPS, y luego usar la autenticación básica HTTP. No creo que haya realmente ninguna razón para molestarse con Digest. La autenticación básica es insegura, pero se envía con cada solicitud para que nunca tenga que preocuparse de que su autenticación se quede obsoleta o lo que sea. Al tunelizarlo a través de HTTPS, tiene una conexión segura.

Si desea autenticar al cliente, puede usar certificados de cliente SSL.Dicho esto, en general es bastante difícil bloquear realmente al cliente contra usuarios malintencionados, por lo que consideraría la posibilidad de acceder de forma abierta a las funciones de registro y protegerse de DOS, etc. a través de la verificación de cuentas fuera de banda.

+1

Trabajé en este proyecto durante mi tiempo libre y desafortunadamente lo detuve. Utilicé oauth 3-legged. No fue fácil de implementar y dado que la API era privada, no se obtuvieron beneficios significativos en comparación con los certificados de cliente Basic + https +. No lo he intentado, pero tu respuesta responde a la parte más importante de la pregunta (alternativa a oAuth), así que la marqué como aceptada. Gracias. –

3

¿Ha considerado utilizar la Autenticación básica?

No he usado aún el framework que mencionaste, pero utilicé la autenticación básica para proteger algunos URL en una aplicación basada en web.py y funcionó bien.

Básicamente, puede usar un token en base64 que en realidad es un heeader http estándar.

Tal vez este ejemplo puede ayudar a:

class Login: 

    def GET(self): 
     auth = web.ctx.env.get('HTTP_AUTHORIZATION') 
     authreq = False 
     if auth is None: 
      authreq = True 
     else: 
      auth = re.sub('^Basic ','',auth) 
      username,password = base64.decodestring(auth).split(':') 
      if (username,password) in settings.allowed: 
       raise web.seeother('/eai') 
      else: 
       authreq = True 
     if authreq: 
      web.header('WWW-Authenticate','Basic realm="Auth example"') 
      web.ctx.status = '401 Unauthorized' 
      return 
+1

tanques para su respuesta, agradezco su participación :) pero existen exactamente los mismos problemas con la autenticación básica o implícita. ¿Cómo puedo autenticar usuario y cliente en la misma solicitud? –

0

Si está interesado en la autenticación básica, este es un atributo rápido que puede usar para decorar sus manipuladores http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute. Este ejemplo está escrito principalmente en el contexto web.py, pero supongo que se puede modificar fácilmente.

def check_auth(username, password): 
    return username == 'username' and password == 'password' 


def requires_auth(f): 
    @wraps(f)  
    def decorated(*args, **kwargs):   
     auth = web.ctx.env['HTTP_AUTHORIZATION'] if 'HTTP_AUTHORIZATION' in web.ctx.env else None 
     if auth: 
      auth = re.sub('^Basic ', '', auth) 
      username, password = base64.decodestring(auth).split(':') 
     if not auth or not check_auth(username, password): 
      web.header('WWW-Authenticate', 'Basic realm="admin"') 
      web.ctx.status = '401 Unauthorized' 
      return 

     return f(*args, **kwargs) 

    return decorated