2011-08-28 15 views
15

Obecnie piszę API odpoczynku w pythonie z kolbą microframework. To prywatne API i zajmuje się danymi użytkownika. Mam zamiar korzystać z tego interfejsu API do tworzenia stron internetowych i aplikacji na Androida.Poszukuję porady, aby zabezpieczyć prywatne API REST napisane w python-flasku

Na razie używam digest auth, aby zabezpieczyć prywatne dane użytkownika. Na przykład, jeśli chcesz opublikować dane w mojej usłudze za pomocą boba użytkownika, wysyłasz prośbę o wpis na myapi/story/create i podaj poświadczenia boba za pomocą wzorca digest.

Jestem świadomy nie jest to dobre rozwiązanie, ponieważ:
Lista -digest auth nie jest bezpieczna
-The klient nie jest uwierzytelniony (? Jak zabezpieczyć żądań nie związanych z bieżącego użytkownika, na przykład tworzenie nowego użytkownika)

Przeczytałem wiele rzeczy na temat oAuth, ale uwierzytelnienie na trzech nogach wydaje się przesadzone, ponieważ nie planuję otwierania mojego API na stronę trzecią.
Dwuetapowa autoryzacja oAuth nie będzie pasować, ponieważ zapewnia tylko uwierzytelnianie klientom, a nie użytkownikom.
Kolejnym problemem związanym z oAuth jest to, że nie znalazłem wyczerpującego przewodnika do implementacji go w Pythonie. Znalazłem bibliotekę python-oauth2, ale nie rozumiem przykładu serwera i nie mogę znaleźć dodatkowej dokumentacji. Poza tym wydaje się, że wiele aspektów OAuth nie jest opisanych w tym przykładzie.

Więc moje pytania to:

  1. Czy istnieje alternatywny system (nie OAuth) dla authenticate klient i użytkownik z rozsądnym poziomem bezpieczeństwa?
  2. Jeśli oAuth jest najlepszym rozwiązaniem:
    • Jak pominąć proces autoryzacji (ponieważ użytkownicy nie będą musieli autoryzować klientów zewnętrznych)?
    • Czy istnieje szczegółowa dokumentacja dla Pythona-oauth2 lub jakiejkolwiek innej biblioteki Pythona?

Każda pomoc lub porada zostanie doceniona.

+0

W odniesieniu do jednego ze swoich problemów, duża część z głównych stron internetowych nie pozwala rejestrować się przez klienta itp, oni sprawić, że zarejestrujesz się za pośrednictwem ich strony internetowej. W przypadku tych witryn, które to umożliwiają, ich wywołanie API jest faktycznie tym samym, co ich formularz rejestracji, więc nie ma znaczenia, czy jest bezpieczne, czy nie. –

Odpowiedz

7

Odpowiedź jest prosta narażać API tylko poprzez HTTPS, a następnie za pomocą podstawowego uwierzytelniania HTTP. Nie sądzę, żeby istniał jakiś powód, by zawracać sobie głowę Digest. Podstawowe uwierzytelnianie jest niezabezpieczone, ale jest przesyłane przy każdym żądaniu, więc nigdy nie musisz się martwić o to, że twoje uwierzytelnienie przestanie działać. Tunelując go przez HTTPS, masz bezpieczne połączenie.

Jeśli chcesz uwierzytelnić klienta, możesz użyć certyfikatów klienta SSL.Ogólnie rzecz biorąc, naprawdę trudno jest naprawdę zablokować klienta przed złośliwymi użytkownikami, dlatego chciałbym, aby funkcje rejestracji były jawnie dostępne i chroniły się przed DOS-em itp. Poprzez pozapasmową weryfikację konta.

+1

Pracowałem nad tym projektem w wolnym czasie i niestety go zatrzymałem. Użyłem oauth 3-legged. Nie było to łatwe do wdrożenia, a ponieważ interfejs API był prywatny, nie ma znaczących korzyści w porównaniu z certyfikatami klienta Basic + https +. Nie próbuję tego, ale twoja odpowiedź odpowiada na najważniejszą część pytania (alternatywa dla OAuth), więc oznaczyłam ją jako zaakceptowaną. Dzięki. –

3

Czy rozważałeś już korzystanie z podstawowego uwierzytelnienia?

Nie wykorzystałem jeszcze wspomnianej struktury, ale użyłem podstawowego uwierzytelnienia do ochrony niektórych adresów URL w aplikacji opartej na web.py i działałem dobrze.

Zasadniczo możesz użyć tokena w base64, który jest w rzeczywistości standardowym heseterem http.

Może ten przykład może pomóc:

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

Zbiorniki za odpowiedź, doceniam twoje zaangażowanie :), ale są dokładnie takie same problemy z uwierzytelnianiem Basic lub Digest. Jak mogę uwierzytelnić użytkownika i klienta w tym samym żądaniu? –

0

Jeśli jesteś zainteresowany podstawowym uwierzytelnianiem, oto krótki atrybut, który możesz wykorzystać do dekoracji swoich opiekunów http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute. Ten przykład jest napisany przede wszystkim w kontekście web.py, ale domyślam się, że można go łatwo poprawić.

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 
Powiązane problemy