Sistema de autorização e autenticação para microsserviços e consumidores

15

Planejamos refatorar o sistema da empresa em um sistema baseado em microsserviço. Esses microsserviços serão usados ​​por nossos próprios aplicativos internos da empresa e por parceiros de terceiros, se necessário. Um para reserva, outro para produtos etc.

Não temos certeza de como lidar com funções e escopos. A idéia é criar três funções básicas de usuário, como administradores, agentes e usuários finais, e permitir que os aplicativos do consumidor ajustem os escopos, se necessário.

  • Os administradores podem criar, atualizar, ler e excluir todos os recursos por padrão (para a empresa).
  • Os agentes podem criar, atualizar e ler dados para sua empresa.
  • Os usuários finais podem criar, atualizar, excluir e ler dados, mas não podem acessar os mesmos terminais que agentes ou administradores. Eles também poderão criar ou modificar dados, mas não no mesmo nível que agentes ou administradores. Por exemplo, os usuários finais podem atualizar ou ler as informações da conta, assim como o agente poderá fazer isso por eles, mas não podem ver ou atualizar as notas do administrador.

Digamos que os agentes por padrão possam criar, ler e atualizar cada recurso para sua empresa e esse seja o escopo máximo que pode ser solicitado para seu token / sessão, mas os desenvolvedores do aplicativo cliente (consumidor da API) decidiram que um de seus agentes pode leia e crie apenas alguns recursos.

É uma prática melhor lidar com isso em nossa segurança interna e permitir que eles gravem esses dados em nosso banco de dados ou que os clientes manuseiem internamente solicitando um token com escopo menor e que escrevam qual agente terá qual escopo em seu banco de dados ? Dessa forma, teríamos que rastrear apenas escopos de token.

A desvantagem disso é que nossa equipe também precisará criar mecanismos de acesso aprimorados em nossos aplicativos internos.

Com esse pensamento, os microsserviços e seu sistema de autorização não devem ser incomodados com as necessidades dos clientes, porque eles são apenas consumidores e não fazem parte do sistema (mesmo que alguns desses consumidores sejam nossos próprios aplicativos internos)?

Esta delegação é uma boa abordagem?

Robert
fonte

Respostas:

14

Autenticação e autorização são sempre bons tópicos

Tentarei explicar a você como lidamos com as autorizações no atual serviço multilocatário em que estou trabalhando. A autenticação e autorização são baseadas em token, usando o padrão aberto JSON Web Token. O serviço expõe uma API REST que qualquer tipo de cliente (aplicativos da web, móvel e de desktop) pode acessar. Quando um usuário é autenticado com sucesso, o serviço fornece um token de acesso que deve ser enviado em cada solicitação ao servidor.

Então, deixe-me apresentar alguns conceitos que usamos com base em como percebemos e tratamos os dados no aplicativo do servidor.

Recurso : qualquer unidade ou grupo de dados que um cliente possa acessar através do serviço. A todos os recursos que queremos controlar, atribuímos um único nome. Por exemplo, tendo as próximas regras de terminal, podemos nomeá-las da seguinte maneira:

product

/products
/products/:id

payment

/payments/
/payments/:id

order

/orders
/orders/:id
/orders/:id/products
/orders/:id/products/:id

Então, digamos que até agora temos três recursos em nosso serviço; product, paymentE order.

Ação : É uma operação que pode ser executada em um recurso, como, ler, criar, atualizar, excluir etc. Não é necessário ser apenas as operações clássicas de CRUD, você pode ter uma ação chamada follow, por exemplo, se deseja expor um serviço que propaga algum tipo de informação usando o WebSockets.

Habilidade : A capacidade de executar um actionem um resource. Por exemplo; leia produtos, crie produtos etc. É basicamente apenas um par de recursos / ações. Mas você também pode adicionar um nome e uma descrição.

Função : um conjunto de habilidades que um usuário pode possuir. Por exemplo, uma função Cashierpode ter as habilidades "ler pagamento", "criar pagamento" ou uma função Sellerpode ter as habilidades "ler produto", "ler ordem", "atualizar pedido", "excluir pedido".

Finalmente, um usuário pode ter várias funções atribuídas a ele.


Explicação

Como eu disse antes, usamos JSON Web Token e as habilidades que um usuário possui são declaradas na carga útil do token. Portanto, suponha que tenhamos um usuário com as funções de caixa e vendedor ao mesmo tempo, para uma pequena loja de varejo. A carga útil será assim:

{
    "scopes": {
        "payment": ["read", "create"],
        "order": ["read", "create", "update", "delete"]
    }
}

Como você pode ver na scopesreivindicação, não especificamos o nome das funções (caixa, vendedor). Em vez disso, apenas os recursos e as ações implicadas são especificados. Quando um cliente envia uma solicitação para um terminal, o serviço deve verificar se o token de acesso contém o recurso e a ação necessários. Por exemplo, uma GETsolicitação para o terminal /payments/88terá êxito, mas uma DELETEsolicitação para o mesmo terminal deve falhar.


  • Como agrupar e nomear os recursos e como definir e nomear as ações e habilidades será uma decisão tomada pelos desenvolvedores.

  • Quais são os papéis e quais habilidades terão esses papéis, são decisões tomadas pelos clientes.


Obviamente, você deve adicionar propriedades extras à carga útil para identificar o usuário e o cliente (inquilino) que emitiu o token.

{
    "scopes": {
        ...
    },
    "tenant": "acme",
    "user":"coyote"
}

Com esse método, você pode ajustar o acesso de qualquer conta de usuário ao seu serviço. E o mais importante, você não precisa criar várias funções estáticas e predefinidas, como Administrador, Agentes e Usuários finais, como aponta sua pergunta. Um superusuário será um usuário que possui um rolecom todo resourcese actionso serviço atribuído a ele.

Agora, e se houver 100 recursos e queremos um papel que dê acesso a todos ou quase todos? Nossa carga útil de token seria enorme. Isso é resolvido aninhando os recursos e apenas adicionando o recurso pai no escopo do token de acesso.


Autorização é um tópico complicado que deve ser tratado dependendo das necessidades de cada aplicativo.

missô
fonte
Obrigado por sua resposta. Isso é muito útil. Eu tenho uma pergunta relacionada a várias funções por usuário. Você já teve um caso em que as permissões de função se sobrepõem? Como caixa tem payment:[read], vendedor tem payment: [create]. Você agrega permissões nesse caso?
Robert
Se você tem papéis com habilidades repetidas (resource/action), deve mesclá-los. Se as permissões se sobrepuserem, você deverá agregá-las. A idéia é definir apenas os recursos e ações permitidos no token, deixando as funções como uma abstração usada para fornecer aos clientes uma maneira menos complicada de lidar com a autorização.
Miso
1
e se um usuário puder apenas executar ações nos recursos que possui. Como uma conta bancária, por exemplo, certamente "bank_account": ["read", "update"] não especifica isso. Além disso, exatamente ONDE o processo de autorização ocorre em um sistema de microsserviços? Em um servidor de autorização centralizado, ou cada serviço possui sua própria autorização?
Rocketspacer
@rocketspacer. É por isso que o token possui a userpropriedade em sua carga útil. A maneira como bloqueio um recurso de propriedade de um usuário é mapeando a userreivindicação para o URL. Por exemplo: /users/coyote/back-accountseria acessível apenas por um token com userreivindicação igual a coyote. Espero que ajude.
Mmo
3

Eu acho que não importa o quê, você desejará que seus serviços aceitem um token de autenticação fornecido por um serviço de autenticação que você escreve para validar usuários. Essa é a maneira mais direta / segura de evitar o uso indevido de seus microsserviços. Além disso, em geral, se você deseja que um cliente tenha uma boa experiência, implemente os recursos críticos e faça um teste completo para garantir que os recursos oferecidos sejam bem implementados.

Como todos os chamadores precisam fornecer aos seus microsserviços evidência de que foram autenticados, você também pode vincular permissões a essa autenticação. Se você fornecer a capacidade de vincular um usuário a um grupo de acesso arbitrário (ou grupos, se desejar, embora seja mais difícil lidar com permissões adicionar ou subtrair aqui.), Haverá menos perguntas dos seus clientes sobre por que o usuário x conseguiu executar uma operação indesejada. De qualquer forma, alguém precisa fazer a verificação da lista de acesso para cada serviço, para que também seja você. É algo que seria muito facilmente codificado no início de todos os serviços (if ( !TokenAuthorized(this.ServiceName, this.token) { Raise error }) Você também pode fazer isso e acompanhar os grupos de usuários. É verdade que você precisará ter um gerente de grupo de permissões e trabalhar com ele na interface do usuário de gerenciamento de usuários (usar existente / criar novo grupo para permissões de usuários) Liste definitivamente os usuários vinculados a um grupo quando editar a definição, para evitar confusão. . Mas, não é um trabalho difícil. Basta ter metadados para todos os serviços e vincular a pesquisa do mapeamento entre grupo e serviço ao tratamento de tokens de autenticação.

Ok, existem alguns detalhes, mas cada um de seus clientes que deseja essa funcionalidade precisaria codificá-la em qualquer caso, e se você oferecer suporte às permissões de usuário de três níveis, poderá estendê-la apenas para acesso por usuário grupos. Provavelmente, uma interseção lógica entre as permissões do grupo de base e as permissões específicas do usuário seria a agregação correta, mas se você quiser adicionar e remover permissões de base, das permissões de administrador, agente e base de usuário final, será necessário o sinalizador tri-state usual nos grupos de permissões: Adicionar permissão, Negar permissão, Permissão padrão e combinar permissões adequadamente.

(Como uma observação, tudo isso deve acontecer em algo como SSL ou SSL bidirecional, se você estiver preocupado com a segurança dos dois lados da conversa. Se você "vazar" esses tokens para um invasor, ele estará como se ele estivesse " d quebrou uma senha.)

BenPen
fonte
Enquanto pensava em infraestrutura e implementação, esqueci completamente a experiência do cliente. Gosto da ideia de criar um conjunto de regras que serão mais com nossos negócios. Administradores, agentes e usuários finais são muito genéricos e planejamos implementar mais tipos de usuários, que são mais descritivos e vinculados aos nossos negócios e à linguagem ubíqua.
Robert
Não pude corrigir o erro de digitação "anded" na última frase porque não consegui descobrir.
Tulains Córdova
Não é um erro de digitação necessariamente, mas eu vou fazer isso mais claro ..
BenPen
1

Minha opinião é que você tem duas opções aqui.

  • Se você só precisa ter acesso configurável a essencialmente o mesmo aplicativo, solicite aos serviços que verifique as permissões e forneça aos seus clientes uma interface que permita alterar as permissões concedidas a cada função. Isso permite que a maioria dos usuários use a configuração de função padrão, na qual os clientes 'problemáticos' podem ajustar as funções ou criar novas para atender às suas necessidades.

  • Se seus clientes estiverem desenvolvendo seus próprios aplicativos, eles deverão apresentar sua própria API intermediária. Que se conecta ao seu como administrador, mas verifica a solicitação recebida em relação aos seus próprios requisitos de autenticação personalizada antes de chamar seus serviços

Ewan
fonte
1

Consideração de segurança

Se eu entendi bem o seu design, você pretende delegar alguns mecanismos de controle de acesso a recursos para o lado do cliente, ou seja, um aplicativo consumidor reduz os itens que um usuário pode ver. Sua suposição é:

micro-serviços e seu sistema de autorização não devem ser incomodados com as necessidades dos clientes, porque eles são apenas consumidores e não fazem parte do sistema

Vejo aqui dois problemas sérios para negócios sérios:

  • E se algum usuário não autorizado lá fora (por exemplo, em uma das instalações de seu parceiro) fizer engenharia reversa do aplicativo cliente e descobrir sobre a API, contornar as restrições impostas por sua empresa ao cliente e usar essas informações para prejudicar sua empresa? Sua empresa reivindicará danos, mas a empresa parceira argumentará que você não forneceu os meios para proteger seus dados suficientemente bem.
  • Normalmente, é apenas uma questão de tempo que dados confidenciais são mal utilizados (ou a auditoria descobrirá o risco) e seu gerenciamento acabará solicitando um controle mais rígido desses dados.

É por isso que aconselho antecipar esses eventos e cuidar de solicitações de autorização. Você está em uma fase inicial de reengenharia e será muito mais fácil levar isso em conta na sua arquitetura (mesmo que você não os implemente todos) mais tarde.

Se você exercer sua posição atual, consulte pelo menos o seu oficial de segurança da informação.

Como implementá-lo

Você tem o truque:

Dessa forma, teríamos que rastrear apenas escopos de token.

Ok, você pretende usar alguns tokens gerais escolhidos pelo cliente. Novamente uma fraqueza em meus olhos, porque alguns clientes podem estar fora de seu controle.

Não sei se você já usa o JWT ou se usa outras técnicas. Mas se você usar o JWT, poderá ter um token de identidade que carrega a identidade do usuário (e até um segundo token que identifica com segurança o aplicativo de origem, o que pode permitir diferenciar o nível de confiança entre clientes internos e externos )

Como você pretende adotar uma arquitetura de microsserviço, gostaria de sugerir uma diferença entre o gerenciamento de usuários e o processo de autenticação (que deve ser executado como um serviço dedicado) e o controle de acesso (que é específico para cada microsserviço e deve sejam tratados localmente por cada um deles). É claro que algum cliente administrador deve fornecer uma visão geral abrangente de vários serviços, para facilitar o uso).

Christophe
fonte
1
Muito bom conselho aqui. Gosto da ideia com o segundo token.
Robert
1

Aqui, há uma resposta curta também. Você deve implementar todos os principais recursos que deseja oferecer aos seus "clientes". Parece problemático fazer com que os clientes adicionem um comportamento fundamental como as próprias permissões de usuário, pois você já está fazendo autenticação do usuário; se você deixar para o cliente implementá-lo, poderá acabar "suportando" várias implementações do mesmo código de permissões. Mesmo que você não "seja o proprietário", haverá erros no código e você deseja que seus clientes tenham a funcionalidade que eles esperavam, dentro do razoável, para apoiar a resolução dos problemas que um cliente está enfrentando. Apoiar várias bases de código não é divertido.

BenPen
fonte