1
resposta

[Dúvida] Criar um controle de acesso a partir de perfis e sub perfis

Boa noite turma.

Eu implementei os codigos das aulas com sucesso, e apesar de ter esclarecido muita coisa, ainda me ficou umas duvidas. Eu vi noutros posts do forum, sobre criar um enum com a lista de perfis, para depois usar para permitir ou não com o @PreAuthorize("hasRole('ADMIN')").

Eu to com uma ideia de projeto pra desenvolver, que um usuário pode ter uma ou mais roles (ex: ter as roles STUDENT e TEACHER). Ele aproveitar o mesmo login, para acessar sistemas diferentes. Em alguns projetos que já trabalhei, faziamos um controle de acessos usando o banco de dados, onde podiamos ir modificando/adicionando/removendo os perfis de um determinado usuário. Teriam alguma sugestão de onde eu poderia colocar os esforços de implementação para liberar ou não os acessos a determinados endpoints, de acordo com os perfis de um usuário? Tipo:

  • o endpoint /student, precisa da role STUDENT, mas
    • o endpoint /student/form/score, precisa ter a role STUDENT, OWNER E/OU ADMIN
  • o endpint /teacher, precisa ter as roles TEACHER ou ADMIN, mas
    • o endpoint /teacher/form/fill, precisar ter a role TEACHER_TITULAR ou ADMIN, mas
    • o endpoint /teacher/form/view, pode ter a role TEACHER_AUXILUAR ou ADMIN pois existe uma cadeia hierarquica de perfis. Também gostaria de uma sugestão de como poderia implementar a questão do isCredentialsNonExpired() para controlar se o usuário está espirado, ativo, e confesso que me perdi um cadinho ali na parte que a gente passa o usuario e senha e como ele faz a busca no banco de dados (porque depois de um tempo a gente abstrai em alguns processos). A minha ideia de API futura, é que o usuario ao logar no sistema, informe o usuário, senha e em qual perfil ele vai querer logar(STUDENT, TEACHER, ETC). E o sistema, só o deixe logar, SE, ele tiver um dos perfis cadastrados para ele. Para que assim ele somente consiga logar nos perfis inseridos para ele, e somente utilize as funcionalidades referentes ao seu perfil quando logado.
1 resposta

Oii Diogo, tudo bem?

Fazer o que você deseja é possível com o Spring Security, e a maneira que você mencionou sobre o uso do @PreAuthorize("hasRole('ADMIN')") é uma das formas de fazer isso.

Vamos pegar como exemplo o seu endpoint /student/form/score que precisa das roles STUDENT, OWNER e/ou ADMIN. Poderia fazer algo assim:

@PreAuthorize("hasRole('STUDENT') or hasRole('OWNER') or hasRole('ADMIN')")
public ResponseEntity<?> scoreForm() {
    // código do método
}

Isso irá garantir que apenas usuários com pelo menos um desses perfis possam acessar esse método.

Quanto ao controle de acesso usando o banco de dados, você pode ter uma tabela de usuários e uma tabela de perfis, e uma tabela de associação entre eles. Assim, você pode alterar os perfis de um usuário a qualquer momento, apenas modificando as entradas na tabela de associação.

Sobre a sua dúvida em relação ao método isCredentialsNonExpired(), ele é um dos métodos da interface UserDetails do Spring Security. Ele é usado para verificar se as credenciais (senha) de um usuário expiraram. Você pode implementá-lo para retornar verdadeiro ou falso, dependendo da lógica de negócios da sua aplicação.

E, sobre a autenticação do usuário com um perfil específico, você pode adicionar um passo extra na sua lógica de autenticação para verificar se o usuário possui o perfil inserido. Se o usuário não possuir o perfil, a autenticação falha.

Espero ter ajudado com minhas ideias.

Um abraço e bons estudos.