Development:Plugin de Autenticação

From MoodleDocs
Revision as of 20:03, 24 May 2019 by Jeferson Rodrigues (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Introdução

Esta página, primeiramente, mostra uma visão geral de todo o processo de autenticação, e depois exemplifica como módulos de autenticação podem ser criados utilizando recursos para substituir a autenticação nativa do Moodle.

Visão geral do processo de autenticação do Moodle

File:1.9.11 login element.png
Elemento visual de login no Moodle 1.9

O caso de uso da autenticação no Moodle inicia quando um usuário clica no link Login dentro da interface, ou caso ele tente acessar uma página restrita. Existem duas classes amplas de plugins de autenticação:

  1. O método tradicional, o qual o Moodle gerencia as credenciais dos seus usuários
  2. Outros métodos que gerenciam as credenciais dos usuários por recursos fora do Moodle, como o LDAP, o SAML, o OpenID (Google, Facebook, etc...), entre outros.

No caso dos plugins tradicionais, a seguinte sequência é realizada (tirando alguns casos com pequeno detalhes e cenários raros):

  1. A página principal de login (/login/index.php) é mostrada, ou se o administrador definiu a URL de Login Alternativa ná página Gerenciar autenticação, em que a página desta URL é exibida (observar os padrões do Moodle
  2. O usuário digita suas credenciais e submete o formulário
  3. O script contido em (/login/index.php) executa:
    1. Obter uma lista de plugins de autenticação habilitados
    2. Efetua uma validação nas credenciais informadas conforme os critérios de segurança do Moodle (caracteres alfanuméricos com pontos e hifens são permitidos)
    3. Chama o método authenticate_user_login() da biblioteca /lib/moodlelib.php, que retorna um objeto $user (detalhes deste código seguem o fluxo principal)
    4. Determina se a autenticação foi bem sucedida (verificando se o objeto $user é válido e, caso contrário, retorna à página de login mostrando uma mensagem de erro. Existem outras situações que ele poderá redirecionar o usuário para páginas específicas (ex.: senha expirada, entre outras).

Para os plugins de autenticação de terceiros, o processo pode se assimilar com esse (ex.: CAS, SAML, OpenID, etc):

  1. O usuário acessa uma página protegida e não está autenticado, então o Moodle irá chamar o método pre_loginpage_hook() de cada plugin habilitado, que poderá redirecionar o usuário para uma página externa de login
  2. Ou se ele abre diretamente a página de login, o Moodle chama o método loginpage_hook() para cada plugin habilitado, que poderá redirecionar o usuário para uma página externa de login
  3. O usuário entra com suas credenciais e se autentica nesta página externa
  4. O sistema remoto de autenticação redireciona o usuário novamente ao Moodle, com um elemento de asserção, que pode ser um único token, ou uma resposta encriptada em um parâmetro
  5. O plugin de autenticação valida este elemento de asserção, faz alguma outra verificação obrigatória para então efetivamente autenticar o usuário através do método complete_user_login($user). Se isto aconteceu dentro do método pre_loginpage_hook(), o usuário continuará no seu caminho, ou se foi através do método loginpage_hook() ou alguma outra página, o plugin irá redirecioná-lo para o recurso wantsurl.

Note que neste cenário acima, o método user_login($username, $password) nunca será chamado e provavelmente retornará falso.

Histórico

Os plugins de autenticação foram implementados a partir do Moodle 1.9

Exemplos

Google / Facebook / Messenger Oauth2 Authentication plugin

Modelo

Por favor veja o plugin Nenhuma autenticação do Moodle, localizado no diretório auth/none dos seus arquivos. É um modelo de plugin perfeito para iniciar o desenvolvimento de um outro.

Estrutura de arquivos

  1. Escolha um nome para o seu plugin. Iremos utilizar sentinela como nosso nome de plugin/exemplo. Mas este é só um exemplo. Troque-o para o qual deseja.
  2. Dentro do diretório principal do Moodle, crie o diretório /auth/sentinela. Ele deve ser um "diretório irmão" de outros plugins de autenticação, como "db", "nologin", "none", entre outros.
  3. Crie o arquivo /auth/sentinela/auth.php. Com este arquivo, crie uma classe chamada auth_plugin_sentinela que extende a classe auth_plugin_base da biblioteca /lib/authlib.php (será necessário um require_once apontando para o arquivo desta biblioteca).
  4. Implemente o método user_login() dentro do seu arquivo auth.php, crie métodos adicionais ou sobrescreva os herdados conforme os requerimentos necessários do seu plugin.
  5. Autentique-se no seu Moodle como administrador e acesse, no bloco Administração do site, a página Usuários -> Autenticação -> Gerenciar autenticação. Você verá seu plugin listado na lista, aparecendo como [[auth_sentinelatitle]]. Você pode habilitá-lo então e ordená-lo para cima ou para baixo, conforme sua prioridade perante aos outros plugins. Neste ponto, com o plugin habilitado, seu plugin está registrado e será utilizado pelo processo de autenticação do Moodle.
  6. Caso você não queira ver [[auth_sentinelatitle]] como o nome do seu plugin no Moodle, você terá que criar os arquivos de idioma para o seu plugin. Veja o String API (precisa traduzir) para detalhes.
  7. Se você deseja configurar seu plugin através da interface do moodle, implemente os métodos config_form() e process_config() na classe do seu plugin. Você pode achar utilizar o plugin "db" como modelo para implementar este recurso. As configurações do plugin podem ser gerenciadas através do recurso Gerenciar autenticações, clicando nas Configurações do seu plugin, e os valores serão armazenados no banco de dados, na tabela mdl_config_plugins.

Conversando com as API's

authenticate_user_login()

Este é o método principal, portanto muita coisa interessante acontece por aqui.

  1. Ele obtém uma lista de plugins de autenticação habilitados
  2. Ele procura pelo nome de usuário dentro da tabela mdl_user para verificar se ele tem permissão para se autenticar, e qual plugin de autenticação é o responsável por validá-lo (este será o plugin que irá trabalhar primeiramente nesta requisição).
  3. Ele cria um objeto $user, que irá conter as informações da tabela mdl_user, se o registro obtido através do nome de usuário existir; caso contrário, será um objeto vazio.
  4. Ele fará o seguinte com cada um dos plugins de autenticação (note que para um usuário não reconhecido pelo Moodle, ele irá realizar estes passos para cada plugin de autenticação habilitado, até que um deles tenha sucsso, ou até encerrar as tentativas):
    1. Chama o método user_login() que irá retornar um valor booleano baseado no sucesso da autenticação das credenciais do usuário. Se o resultado for falso (autenticação falhou), ele irá interromper o restante dos passos abaixo e tentará o próximo plugin.
    2. Se o plugin autenticar através de um plugin de terceiro externo (cuja validação das credenciais não está no banco de dados do Moodle), o método update_user_record() é chamado para obter os dados do usuário.
    3. Cria um registro de usuário no Moodle, caso ainda não exista (se a opção Impedir a criação de conta ao autenticar (authpreventaccountcreation) da tela Administração do site > Plugins > Autenticação > Gerenciar autenticação estiver desmarcado).
    4. Chama o método do plugin sync_roles()
    5. Notifica cada plugin de autenticação habilitado que o usuário foi autenticado, chamando o método user_authenticated_hook() de cada um deles.
  5. O plugin retorna o objeto $user se tudo ocorreu bem, ou, caso contrário, retorna false se falhar no processo de validação das credenciais.

user_login($username, $password)

Este é o método primário utilizado pelo authenticate_user_login(), e deve sobrescrever aquele herdado pelo plugin, que, através dos valores de $username e $password, o usuário seja validado, e, sendo assim, ela deverá retornar um booleano true, caso identifique ele, ou false em caso negativo.

Retorna
boolean true ou false
Valor padrão
false

can_change_password()

Retorna se o plugin pode alterar a senha do usuário.

Retorna
boolean true ou false
Valor padrão
false

change_password_url()

Retorna a URL de alteração de senha do usuário, ou vazio se a URL padrão pode ser utilizada. Este método é utilizado quando o can_change_password() retornar true. Ele é chamado somente quando o usuário está autenticado, e ele pode utilizar o $user global. Se você estiver utilizando uma variável de configuração deste plugin neste método, tenha certeza de que o valor está definido antes de utilizá-lo, ou, se os valores não forem atribuídos, pode ser que este método seja chamado mesmo que o plugin esteja desativado.

Retorna
moodle_url $URL ou null
Valor padrão
null

can_edit_profile()

Retorna se o plugin pode editar o perfil do usuário.

Retorna
boolean true ou false
Valor padrão
true

edit_profile_url()

Retorna uma URL para que o usuário seja redirecionado à uma página específica de edição de perfil, caso contrário o padrão Moodle será utilizado.

Retorna
moodle_url $URL ou null
Valor padrão
null

is_internal()

Retorna um booleano se este plugin de autenticação for "interno". Um plugin de autenticação é considerado "interno" quando o Moodle utilizar senhas encriptadas do seu banco de dados de usuários para autenticá-los.

Retorna
boolean true ou false
Valor padrão
true

is_configured()

Retorna um booleano dizendo se este plugin está configurado, embora esteja habilitado.

Retorna
boolean true ou false
Valor padrão
false

prevent_local_passwords()

Indica se as senhas encriptadas devem ser armazenadas no banco de dados local do Moodle. Este método retorna automaticamente o inverso do retorno do método is_internal(). Retornando true, significa que as senhas encriptadas por MD5 deverão ser armazenadas na tabela de usuários, caso contrário, a flag 'not_cached' será armazenada no lugar.

Retorna
boolean true ou false
Valor padrão
!$this->is_internal()

is_synchronised_with_external()

Indica se o Moodle deve automaticamente atualizar o registro interno do usuário com os dados provenientes da fonte externa de autenticação, utilizando o retorno do método get_userinfo().

Retorna
boolean true ou false
Valor padrão
!$this->is_internal()

user_update_password($user, $newpassword)

Atualiza a senha do usuário. Em versões anteriores do Moodle, o método auth_user_update_password