Autenticação + autorização + Application server + SPA

Desde já peço desculpas pelo texto longo mas preciso detalhar o problema para me fazer entender.

Estou tentando desenvolver uma aplicação SPA utilizando o ReactJS tentando utilizar a segurança nativa do servidor de aplicação (Wildfly 12, no meu caso). Li algo sobre JWT e Spring Security, mas antes de partir para essas alternativas gostaria de esgotar a possibilidade de utilizar o que já está implementado nativamente no servidor de aplicação.

Já tenho aplicações JSF + Primefaces utilizando a segurança do servidor de aplicação juntamente com meus módulos de autenticação e autorização customizados e tudo funciona bem. Eu envio o nome de usuário e senha para um ManagedBean e esse realiza a autenticação invocando o método login da requisição (HttpServletRequest.login(username, senha)). A partir desse ponto o servidor de aplicação reconhece o usuário autenticado e seus privilégios. Todas as requisições subsequentes são submetidas à segurança servidor de aplicação que cuida de verificar a autorização e tudo funciona perfeitamente.

O que estou tentando fazer é realizar o mesmo tipo de autenticação e autorização, mas a partir da minha aplicação SPA invocando um webservice restful via ajax para executar o mesmo request.login() para autenticar e autorizar o usuário, mas aparentemente isso não é tão simples quanto eu imaginei.

O processo de forma resumida é:

  1. No formulário de login o usuário informa seu username e senha clica no botão para autenticar.
  2. O webservice de autenticação recebe a requisição com essas informações e invoca o request.login(username, senha).
  3. A autenticação é feita com sucesso e o resultado retornado ao client (aplicação SPA) que em seguida invoca outro webservice para obter os privilégios do usuário autenticado (autorização) para decidir quais funcionalidades serão disponibilizadas para o usuário na interface.
  4. O webservice que consulta os privilégios identifica o usuário autenticado invocando o método request.getUserPrincipal() para a partir daí consultar seus privilégios e retorná-los ao client.

É aí que o problema ocorre. Mesmo o usuário sendo autenticado com sucesso na requisição feita anteriormente ao webservice de autenticação, o request.getUserPrincipal retorna sempre null quando o webservice para obtenção dos privilégios é invocado. É como se o usuário nunca tivesse sido autenticado ou uma nova sessão tivesse sido criada (o que eu penso ser o caso).

Já tentei realizar a mesma operação fazendo deploy da aplicação em um Tomcat para ver e era alguma coisa específica relacionada ao Wildfly mas o resultado foi o mesmo. Também tentei utilizar uma servlet no lugar de um webservice obtendo o mesmo resultado.

Não sei se estou abordando corretamente o aspecto de segurança nesse tipo de aplicação SPA ou se existem outros meios mais efetivos de se utilizar a autenticação e autorização do servidor de aplicação.

Apesar de ter bastante experiência como desenvolvedor java e jee é a primeira vez que estou tentando esse tipo de abordagem e não faço ideia de quais são as melhores práticas. Todos os materiais que encontrei não descrevem essa situação.

Qualquer ajuda será muito bem vinda. Agradeço desde já.

O que você poderia fazer é autenticar o usuário (salvar uma chave no seu endpoint de login), retornar a chave e mandar redirecionar para a api getUserPrincipal junto com a chave e nesse endpoint redirecionar novamente para uma página verificando o nível de autorização.
Ai para invalidar a chave poderia usar um scheduler no banco.

Só estou dando ideia.:grin:

E aí, @JulioCesarSF, não sei se consegui visualizar direito o que você propôs. Você poderia detalhar mais um pouco, por favor? De qualquer forma obrigado pela dica!

Falar a verdade o que falei é basicamente JWT: https://pt.linkedin.com/pulse/autenticação-baseada-em-token-uma-aplicação-rest-tarcisio-carvalho

Não sei se te ajuda.:pensive:

Opa, qualquer ajuda é bem-vinda.

É um problema meio chato isso e como eu escrevi no post original, não tenho certeza se estou abordando da maneira correta. Quando eu trabalho utilizando páginas (JSF no caso), funciona bem essa forma de autenticação, mas agora com a aplicação React estou tendo essa dificuldade.

Vou dar uma olhada nesse material. Valeu!