Há muitas perguntas aqui que tratam da mecânica de autenticação e autorização de APIs RESTful, mas nenhuma delas parece entrar em detalhes de como implementar serviços seguros no nível do aplicativo.
Por exemplo, digamos que meu aplicativo da web (eu tenho Java em mente, mas isso se aplica a qualquer back-end realmente) tem um sistema de autenticação seguro que permite que os usuários da API efetuem login com um nome de usuário e senha. Quando o usuário faz uma solicitação, a qualquer momento durante o pipeline de processamento de solicitações, posso chamar um getAuthenticatedUser()
método que retornará o usuário nulo se o usuário não estiver conectado ou um objeto de domínio do Usuário que represente o usuário conectado.
A API permite que usuários autenticados acessem seus dados, por exemplo, um GET /api/orders/
retornará a lista de pedidos desse usuário. Da mesma forma, um GET /api/tasks/{task_id}
retornará dados relacionados a essa tarefa específica.
Vamos supor que existem vários objetos de domínio diferentes que podem ser associados à conta de um usuário (pedidos e tarefas são dois exemplos, também podemos ter clientes, faturas etc.). Queremos que apenas usuários autenticados possam acessar dados sobre seus próprios objetos, portanto, quando um usuário faz uma ligação /api/invoices/{invoice_id}
, precisamos verificar se o usuário está autorizado a acessar esse recurso antes de servi-lo.
Minha pergunta é: existem padrões ou estratégias para lidar com esse problema de autorização? Uma opção que estou considerando é criar uma interface auxiliar (ou seja SecurityUtils.isUserAuthorized(user, object)
), que pode ser chamada durante o processamento de solicitações para garantir que o usuário esteja autorizado a buscar o objeto. Isso não é ideal, pois polui o código do terminal do aplicativo com muitas dessas chamadas, por exemplo
Object someEndpoint(int objectId) {
if (!SecurityUtils.isUserAuthorized(loggedInUser, objectDAO.get(objectId)) {
throw new UnauthorizedException();
}
...
}
... e depois há a questão de implementar esse método para cada tipo de domínio que pode ser um pouco trabalhoso. Essa pode ser a única opção, mas eu gostaria de ouvir suas sugestões!