Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Apresentando um novo autenticador para o JupyterHub

Apresentando um novo autenticador para o JupyterHub

Palestra dada no 47o meetup da Python Floripa

96f6148ae5af63f90246a3817686b457?s=128

Leticia Portella

May 23, 2020
Tweet

Transcript

  1. Um novo autenticador para o JupyterHub

  2. LETICIA PORTELLA /in/leportella @leportella @leleportella leportella.com pizzadedados.com

  3. Quem não ama Jupyter notebooks? <3

  4. Mas… e se existirem mais pessoas além de mim?

  5. None
  6. JupyterHub HTTP Proxy Hub All icons where obtain on Flaticon

  7. JupyterHub HTTP Proxy Hub Authenticator All icons where obtain on

    Flaticon /hub/<url>
  8. JupyterHub HTTP Proxy Hub Authenticator Spawners All icons where obtain

    on Flaticon /hub/<url>
  9. JupyterHub HTTP Proxy Hub Authenticator Spawners All icons where obtain

    on Flaticon /hub/<url> /user/<name>
  10. JupyterHub HTTP Proxy Hub Authenticator Spawners Database All icons where

    obtain on Flaticon /hub/<url> /user/<name>
  11. JupyterHub HTTP Proxy Hub Authenticator Spawners Database All icons where

    obtain on Flaticon /user/<name> /hub/<url> Admin /hub/admin
  12. JupyterHub HTTP Proxy Hub Authenticator Spawners Database Config.py All icons

    where obtain on Flaticon /user/<name> /hub/<url> Admin /hub/admin
  13. JupyterHub HTTP Proxy Hub Authenticator Spawners Database Config.py All icons

    where obtain on Flaticon /user/<name> /hub/<url> Admin /hub/admin
  14. JupyterHub Authenticator Options PAM LDAP OAuth FirstUse Dummy

  15. JupyterHub Authenticator Options PAM LDAP OAuth FirstUse Dummy

  16. JupyterHub Authenticator Options PAM LDAP OAuth FirstUse Dummy Native Authenticator

  17. Vamos ver como foi a experiência!

  18. Criando um Autenticador / USERNAME + SENHA

  19. Criando um Autenticador / USERNAME + SENHA LOGIN HANDLER MÉTODO

    POST POST
  20. Criando um Autenticador / USERNAME + SENHA LOGIN HANDLER AUTHORIZED

    CLASSE DO AUTHENTICATOR MÉTODO POST POST MÉTODO AUTHENTICATE UNAUTHORIZED
  21. Criando um Autenticador from jupyterhub.auth import Authenticator from tornado import

    gen class NewAuth(Authenticator): # ... @gen.coroutine def authenticate(self, handler, data): if self.can_login: return data['username'] return
  22. Vamos mais a fundo?

  23. Native Authenticator /SIGNUP USUÁRIA

  24. Jupyterhub + Tornado class NewAuth(Authenticator): # ... def get_handlers(self, app):

    native_handlers = [ (r'/signup', SignUpHandler), ] return native_handlers
  25. Jupyterhub + Tornado class SignUpHandler(LocalBase): async def get(self): # …

    html = self.render_template(‘signup.html’) self.finish(html) async def post(self): user_info = { 'username': self.get_body_argument(‘username’) 'pw': self.get_body_argument(‘pw') } # do stuff… html = self.render_template(‘signup.html’, message='succesful') self.finish(html)
  26. Native Authenticator /SIGNUP CRIA NOVA USUÁRIA USUÁRIA ESTÁ DESAUTORIZADA USUÁRIA

  27. Native Authenticator /SIGNUP CRIA NOVA USUÁRIA USUÁRIA ESTÁ DESAUTORIZADA USUÁRIA

    EU PRECISO DE INFORMAÇÃO EXTRA!
  28. Criando uma nova usuária from jupyterhub.orm import User

  29. Criando uma nova usuária from jupyterhub.orm import User

  30. Criando uma nova usuária from .orm import UserInfo class NewAuth(Authenticator):

    # ... def add_new_table(self): inspector = inspect(self.db.bind) if 'users_info' not in inspector.get_table_names(): UserInfo.__table__.create(self.db.bind)
  31. Quer saber mais? SQLBasic Tutorial Adding relationship tables already created

    on SQLAlchemy
  32. Native Authenticator /SIGNUP CRIA NOVA USUÁRIA USUÁRIA ESTÁ DESAUTORIZADA /AUTHORIZE

    USUÁRIA É AUTORIZADA ADMIN USUÁRIA
  33. Native Authenticator /SIGNUP CRIA NOVO USUÁRIO USUÁRIA ESTÁ DESAUTORIZADO /

    USUÁRIA CONSEGUE ACESSO /AUTHORIZE USUÁRIA É AUTORIZADA ADMIN USUÁRIA USUÁRIA
  34. Native Authenticator Features: Cadastro de novos usuários Limpeza de username

    Bloqueio dinâmico
  35. Native Authenticator

  36. Native Authenticator Features: Permite troca de senha dos usuários Permite

    adicionar checks de segurança de senhas Pedido de informações extras no signup 2fa
  37. Native Authenticator Features: Bloqueando após múltiplas tentativas falhas de login

  38. Bloqueando múltiplas tentativas de login • Usuária tenta logar X

    vezes ela é bloqueada • Usuária pode tentar de novo depois de X minutos • Usuária tem a contagem zerada quando tem uma tentativa bem sucedida
  39. class NewAuth(Authenticator): # ... @gen.coroutine def authenticate(self, handler, data): #

    pega username e senha… # se não tiver validado… self.add_login_attempt(username) Bloqueando múltiplas tentativas de login
  40. Bloqueando múltiplas tentativas de login class NewAuth(Authenticator): def add_login_attempt(self, username):

    if not self.login_attempts.get(username): self.login_attempts[username] = { 'count': 1, 'time': datetime.now() } else: self.login_attempts[username]['count'] += 1 self.login_attempts[username]['time'] = datetime.now()
  41. class NewAuth(Authenticator): # ... @gen.coroutine def authenticate(self, handler, data): #

    pega username e senha… # antes de validar… if self.is_blocked(username): return Bloqueando múltiplas tentativas de login
  42. Bloqueando múltiplas tentativas de login class NewAuth(Authenticator): def is_blocked(self, username):

    logins = self.login_attempts.get(username) if not logins or logins['count'] < self.allowed_failed_logins: return False if self.can_try_to_login_again(username): return False return True
  43. Bloqueando múltiplas tentativas de login class NewAuth(Authenticator): def is_blocked(self, username):

    logins = self.login_attempts.get(username) if not logins or logins['count'] < self.allowed_failed_logins: return False if self.can_try_to_login_again(username): return False return True PERSONALIZADA!!!
  44. Bloqueando múltiplas tentativas de login class NewAuth(Authenticator): def can_try_to_login_again(self, username):

    login_attempts = self.login_attempts.get(username) if not login_attempts: return True time_last_attempt = datetime.now() - login_attempts['time'] if time_last_attempt.seconds > self.seconds_before_next_try: return True return False
  45. Bloqueando múltiplas tentativas de login class NewAuth(Authenticator): def can_try_to_login_again(self, username):

    login_attempts = self.login_attempts.get(username) if not login_attempts: return True time_last_attempt = datetime.now() - login_attempts['time'] if time_last_attempt.seconds > self.seconds_before_next_try: return True return False PERSONALIZADA!!!
  46. Configurações personalizadas?

  47. Adicionando configurações personalizadas class NewAuth(Authenticator): # ... allowed_failed_logins = Integer(

    config=True, default=0, help=("Configures the number of failed attempts a user can have before being blocked.”) )
  48. Adicionando configurações personalizadas # jupyter.config c.Authenticator.allowed_failed_logins = 3

  49. Native Authenticator Mas trabalho open-source não é só escrever código!

  50. E como EU fui parar aqui??

  51. E como EU fui parar aqui? Crie um perfil no

    outreachy.org Seja aceita na primeira etapa de avaliação :) Selecione um projeto que você preenche os requisitos Resolva uma micro-tarefa do projeto Peça ajuda dos mentores! Submita um pull request
  52. E como EU fui parar aqui? Preencha o formulário final

    Aguarde os resultados Seja parte de um time maravilhoso <3
  53. Quer saber mais? Report I Report II Report III Report

    IV Report V Blog post oficial
  54. Jupyter <3

  55. LETICIA PORTELLA /in/leportella @leportella @leleportella leportella.com pizzadedados.com