BISSecurity: mudanças entre as edições

De BIS Wiki
Ir para navegação Ir para pesquisar
Sem resumo de edição
Linha 3: Linha 3:
== Chaves de Acesso ==
== Chaves de Acesso ==


O controle de acesso é gerenciado por "chaves" de acesso. Essas chaves são cadeias de caracteres (strings) únicas no sistema.
O controle de acesso é gerenciado por "chaves" de acesso. Cada chave tem a finalidade de definir o acesso a alguma ação no sistema. A ação pode ser de manipular algum dado, ou simplesmente de visualiza-lo, como gerar um relatório ou abrir uma tela de consulta, etc.
 
 
As chaves são cadeias de caracteres (strings) únicas no sistema.
 


{{nota|Conflito de Chaves|Para evitar o conflito ou a coincidência de chaves idênticas no sistema é aconselhável que as chaves sigam uma estrutura similar a usada nos pacotes de organização do código.
{{nota|Conflito de Chaves|Para evitar o conflito ou a coincidência de chaves idênticas no sistema é aconselhável que as chaves sigam uma estrutura similar a usada nos pacotes de organização do código.
Linha 22: Linha 26:
{{nota|Criar Constantes na Classe de Definitions|Assim como diversas definições do sistema, as chaves de acesso do sistema é recomendado que se crie constantes na [[Classe de Definitions]] do Plugin.}}
{{nota|Criar Constantes na Classe de Definitions|Assim como diversas definições do sistema, as chaves de acesso do sistema é recomendado que se crie constantes na [[Classe de Definitions]] do Plugin.}}


Qualquer plugin pode gerar suas próprias chaves de acesso livremente, para isso basta criar a hierarquia das chaves e devolver através da interface de implementação do [[CorePlugin]]. Uma vez que essas chaves foram passadas ao BISCore elas estão prontas para sem usadas. As chaves tornam-se disponíveis na tela de definição de acessos do Grupo de Segurança.


=== Chaves de Acesso à Objetos ===
=== Chaves de Acesso à Objetos ===


Por algumas vezes além definir o acesso do usuário à uma tela ou função, queremos que um determinado usuário tenha acesso à um objeto mas não a outro. Por exemplo, desejamos que um determinado usuário tenha acesso para fazer lançamentos em uma "conta caixa" que ele controla, mas não a fazer lançamentos em outras contas. Ver o saldo de uma determinada conta, mas não à outras. Para resolver esse tipo de acesso o plugin deve criar as chaves de forma dinâmica e devolve-las junto com a hierarquia de chaves.
Por algumas vezes além definir o acesso do usuário à uma tela ou função, queremos que um determinado usuário tenha acesso à um objeto mas não a outro. Por exemplo, desejamos que um determinado usuário tenha acesso para fazer lançamentos em uma "conta caixa" que ele controla, mas não a fazer lançamentos em outras contas. Ver o saldo de uma determinada conta, mas não à outras. Para resolver esse tipo de acesso podemos criar as chaves de forma dinâmica e devolve-las junto com a hierarquia de chaves.


As chaves dinâmicas devem seguir as seguintes regras:
As chaves dinâmicas devem seguir as seguintes regras:
* Chaves de um mesmo tipo de objeto devem ter sempre a mesma 'key', ou identificador de chave, a única diferença entre elas é o ID do objeto que é passado em cada chave;
* Chaves de um mesmo tipo de objeto devem ter sempre a mesma 'secKey', ou identificador de chave, a única diferença entre elas é o ID do objeto que é passado em cada chave;
* Chaves de um determinado tipo devem ser todas filhas de uma mesma chave pai do tipo 'genérica';
* Chaves de um determinado tipo devem ser todas filhas de uma mesma chave pai do tipo 'genérica';
* Nada impede que as chaves dinâmicas tenham chaves filhas, mas devem ser todas dinâmicas também;
* Nada impede que as chaves dinâmicas tenham chaves filhas, mas devem ser todas dinâmicas também;




{{nota|Criação de Chaves Únicas|Para manter a compatibilidade do código já existente, e mesmo manter simples o desenvolvimento atual, as chaves de segurança devem ser sempre únicas. Assim, ao criar um objeto SecurekeyVO para uma chave do tipo 'OBJECT' ele automaticamente concatenará a chave passada com o ID do objeto para gerar o ID da chave de acesso, no padrão '''<chave de acesso> + "_" + <ID do Objeto>'''. Assim, quando for salva no banco ou gerenciada solicitando permissão a chave estará sempre composta.}}
{{nota|Criação de Chaves Únicas|Para manter a compatibilidade do código já existente, e mesmo manter simples o desenvolvimento atual, as chaves de segurança devem ser sempre únicas. Assim, ao criar um objeto SecureKeyVO para uma chave do tipo 'OBJECT' ele automaticamente concatenará a chave passada com o ID do objeto para gerar o ID da chave de acesso, no padrão '''<chave de acesso> + "_" + <ID do Objeto>'''. Assim, quando for salva no banco ou gerenciada solicitando permissão a chave estará sempre composta.}}




{{stop|Exclusão de Chaves de Acesso|O BIS por padrão não exclui acessos mesmo quando não detecta que a chave foi retornada pelo Plugin. Isso porque o BIS acredita que o algum módulo do Plugin ou mesmo o Plugin todo possa ter sido desabilitado temporariamente e excluir os acessos ocasionará falha no acesso quando os módulos ou plugins forem reativados.
{{stop|Exclusão de Chaves de Acesso|O BIS por padrão '''não''' exclui acessos mesmo quando não detecta que a chave foi retornada pelo Plugin. Isso porque o BIS acredita que o algum módulo do Plugin ou mesmo o Plugin todo possa ter sido desabilitado temporariamente e excluir os acessos ocasionará falha no acesso quando os módulos ou plugins forem reativados.
Por tanto, sempre quem plugin excluir uma chave de acesso, ou excluir o objeto de associado a uma chave de acesso, ele fica responsável por excluir os eventuais acessos dado para esta chave[/objeto]. Caso contrário o banco passará a ter registros e acessos sem utilidade.}}
Por tanto, sempre quem plugin excluir uma chave de acesso, ou excluir o objeto de associado a uma chave de acesso, ele fica responsável por excluir os eventuais acessos dado para esta chave[/objeto]. Caso contrário o banco passará a ter registros e acessos sem utilidade.}}




{{nota|Exibição de Chaves de Acesso|Embora o BIS não apague os acessos dado às chaves que não estão mais disponíveis ele não exibe esses acessos nas telas de permissões. Isso porque se um plugin ou módulo foi desabilitado suas chaves e acessos não podem ser modificados, e nem utilizados.}}
{{nota|Exibição de Chaves de Acesso|Embora o BIS não apague os acessos dado às chaves que não estão mais disponíveis ele não exibe esses acessos nas telas de permissões. Isso porque se um plugin ou módulo foi desabilitado suas chaves e acessos não podem ser modificados, e nem utilizados.}}
=== Hierarquia Obrigatória ===
Quando uma chave de acesso é definida em uma hierarquia, o BIS impõe as seguintes regras:
* '''Permissões:''' Caso seja definida permissão em uma chave, todas as chaves acima devem receber permissão também;
* '''Proibição:''' Caso seja definida proibição em uma chave, todas as filhas descendentes devem receber proibição também.
Esse sistema permite que ao definir acesso em uma chave obrigue a permissão automática em chaves pai que normalmente permitem o acesso até aquela determinada função. Por exemplo a chave "Excluir Itens" pode permitir que um usuário exclua um item do sistema, já sua chave pai "Cadastro de Itens" permite o acesso a tela de cadastro onde estão as funções de excluir, alterar, incluir, duplicar, etc.
O sistema de negação dos descendentes segue a mesma lógica, uma vez que restringimos o acesso da chave pai, não faz sentido permitir o acesso nas funções filhas.
{{nota|Hierarquia Mal Estruturada|Se fizer sentido ter acesso a chave filha sem acesso a chave pai, provavelmente a hierarquia de permissões é que deve estar mal estruturada.}}


== Usuários e Grupos de Acesso ==
== Usuários e Grupos de Acesso ==
Linha 67: Linha 56:
Existem três tipos de grupos que o sistema suporta:
Existem três tipos de grupos que o sistema suporta:
* '''Grupo de Usuário''' - Este grupo é criado e mantido pelo usuário conforme ele bem entender e achar necessário.
* '''Grupo de Usuário''' - Este grupo é criado e mantido pelo usuário conforme ele bem entender e achar necessário.
* '''Grupo de Segurança''' - Esse grupo é internamente criado pelo sistema e seus módulos. Este tipo de grupo não pode ser excluído do sistema (a não ser por alguma atualização futura), nem seu Nome e descrição podem ser alterados. Ele oferece acessos predefinidos pelas atualizações do sistema, mas que podem ser alteradas pelo usuário para personalizar melhor este grupo conforme as necessidades do usuário. A vantagem em um grupo assim é que o sistema pode incluir automaticamente novas permissões nestes grupos conforme o sistema evolui, sem tirar a autonomia do usuário em adaptar o grupo a sua necessidade. Definir novas permissões automaticamente durante as atualizações é viável pois evita que após uma atualização seja necessário definir manualmente todas as novas permissões para um determinado grupo de acesso.
* '''Grupo de Segurança''' - Esse grupo é internamente criado pelo sistema. Este tipo de grupo não pode ser excluído do sistema, nem seu Nome e Descrição podem ser alterados. Ele oferece acessos predefinidos pelas atualizações do sistema, mas que podem ser alteradas pelo usuário para personalizar melhor este grupo conforme as necessidades do usuário. A vantagem em um grupo assim é que o sistema pode incluir automaticamente novas permissões nestes grupos conforme o sistema evolui, sem tirar a autonomia do usuário em adaptar o grupo a sua necessidade. Definir novas permissões automaticamente durante as atualizações é viável pois evita que após uma atualização seja necessário definir manualmente todas as novas permissões para um determinado grupo de acesso.
* '''Grupo de Sistema''' - Esse grupo é completamente fechado e não pode ser alterado em ponto algum pelo usuário. Nem ter suas permissões alteradas, nome alterado, descrição, etc. Apenas é permitido escolher quem participará deste grupo.
* '''Grupo de Sistema''' - Esse grupo é completamente fechado e não pode ser alterado em ponto algum pelo usuário. Nem ter suas permissões alteradas, nome alterado, descrição, etc. Apenas é permitido escolher quem participará deste grupo.


{{nota|Identificação do Grupo|Durante o desenvolvimento, os grupos criados devem receber um 'keyid' único utilizado para identificar o grupo. Isso porque o ID pode variar de uma instalação para outra, já que o usuário pode ter criado seus próprios grupos, e novos grupos de Segurança e Sistema receberem IDs diferentes em casa instalação do sistema.}}
 
{{nota|Identificação do Grupo|Durante o desenvolvimento, os grupos criados devem receber um 'innerID' único utilizado para identificar o grupo. Isso porque o ID pode variar de uma instalação para outra, já que o usuário pode ter criado seus próprios grupos, e novos grupos de Segurança e Sistema receberem IDs diferentes em casa instalação do sistema.}}
 


== Controle de Acesso à Métodos do Fachada ==
== Controle de Acesso à Métodos do Fachada ==


Embora ainda não implementado, o BISCore deve oferecer em breve uma maneira de garantir que métodos do core só possam ser chamados com uma autenticação de usuário definida durante a chamada. Com os seguintes requisitos:
* Essa autenticação deve ser transparente e fora da assinatura do método, se for por JNDI passar a autenticação por propriedades do ambiente na chamada, por webservice exigir a autenticação prevista no serviço, ou em algum objeto externo que encapsule a mensagem a ser passada no método. Usar as especificações do serviço de NFe para exemplo;
* Permitir que as chaves de acesso para chamada do método sejam definidas como annotations no método. O BISInterceptor pode verificar a permissão antes de chamar o método. Quanto as chaves de objeto, talvez não seja possível fazer a validação através de annotations.


A definição de chaves de acessos para chamar os métodos da fachada são importantes pois mesmo que as UI implementem e já restrinjam o acesso dos usuários, nada impede que um acesso direto à fachada por outro sistema ou por algum tipo de "ataque" estrague ou tenha acesso a dados indevidos.
A fachada do BIS tem sua segurança implementada no BISFacadeInterceptor. Todos os métodos da fachada por padrão devem receber como primeiro parâmetro uma String com o UUID da sessão do usuário. Essa UUID é fornecida quando o usuário chama o método '''doLogin()''' da fachada. O método '''doLogin()''' não exige a UUID, por razões óbvioas.


== Controle de Acesso à Interface do Usuário (UI) ==
Para configurar os métodos da fachada, o método deve usar a Annotation '''Security''' e utilizar uma de suas opções de autenticação. A exigência da sessão (mandar a UUID como primeiro parâmetro do método) é a autenticação padrão e não exige a presença a Annotation. Para que não seja exigida a UUID ou outros tipos de definições a Annotation é obrigatória.


O Controle de acesso à interface deve ser definido por cada tipo de interface criada. A BISCorePresLib oferece métodos na sua class [[BISUI]] que simplificam a verificação de acesso do usuário.
Quando o UUID está presente, o BISFacadeInterceptor recupera a sessão e a registra automaticamente no BISSessionManager para a Thread sendo utilizada.

Edição das 17h16min de 27 de julho de 2018

O serviço de BISSecurity tem a finalidade de facilitar e centralizar o controle de acesso de usuários no sistema.

Chaves de Acesso

O controle de acesso é gerenciado por "chaves" de acesso. Cada chave tem a finalidade de definir o acesso a alguma ação no sistema. A ação pode ser de manipular algum dado, ou simplesmente de visualiza-lo, como gerar um relatório ou abrir uma tela de consulta, etc.


As chaves são cadeias de caracteres (strings) únicas no sistema.


Conflito de Chaves
Para evitar o conflito ou a coincidência de chaves idênticas no sistema é aconselhável que as chaves sigam uma estrutura similar a usada nos pacotes de organização do código.

Por exemplo, algumas das chaves usadas no BISCore:

  • BIS_PDV
    • BIS_PDV_PDV
      • BIS_PDV_PDV_CONTRACT
        • BIS_PDV_PDV_CONTRACT_REPORTS_PERIODCONSUMPTION
    • BIS_PDV_PDVAPP
      • BIS_PDV_PDVAPP_CHECKOUT
        • BIS_PDV_PDVAPP_CHECKOUT_OPENCLOSECHECKOUT
        • BIS_PDV_PDVAPP_CHECKOUT_REDUCAOZ
        • BIS_PDV_PDVAPP_CHECKOUT_REDUCAOZ_FORCED


Criar Constantes na Classe de Definitions
Assim como diversas definições do sistema, as chaves de acesso do sistema é recomendado que se crie constantes na Classe de Definitions do Plugin.


Chaves de Acesso à Objetos

Por algumas vezes além definir o acesso do usuário à uma tela ou função, queremos que um determinado usuário tenha acesso à um objeto mas não a outro. Por exemplo, desejamos que um determinado usuário tenha acesso para fazer lançamentos em uma "conta caixa" que ele controla, mas não a fazer lançamentos em outras contas. Ver o saldo de uma determinada conta, mas não à outras. Para resolver esse tipo de acesso podemos criar as chaves de forma dinâmica e devolve-las junto com a hierarquia de chaves.

As chaves dinâmicas devem seguir as seguintes regras:

  • Chaves de um mesmo tipo de objeto devem ter sempre a mesma 'secKey', ou identificador de chave, a única diferença entre elas é o ID do objeto que é passado em cada chave;
  • Chaves de um determinado tipo devem ser todas filhas de uma mesma chave pai do tipo 'genérica';
  • Nada impede que as chaves dinâmicas tenham chaves filhas, mas devem ser todas dinâmicas também;


Criação de Chaves Únicas
Para manter a compatibilidade do código já existente, e mesmo manter simples o desenvolvimento atual, as chaves de segurança devem ser sempre únicas. Assim, ao criar um objeto SecureKeyVO para uma chave do tipo 'OBJECT' ele automaticamente concatenará a chave passada com o ID do objeto para gerar o ID da chave de acesso, no padrão <chave de acesso> + "_" + <ID do Objeto>. Assim, quando for salva no banco ou gerenciada solicitando permissão a chave estará sempre composta.


Exclusão de Chaves de Acesso
O BIS por padrão não exclui acessos mesmo quando não detecta que a chave foi retornada pelo Plugin. Isso porque o BIS acredita que o algum módulo do Plugin ou mesmo o Plugin todo possa ter sido desabilitado temporariamente e excluir os acessos ocasionará falha no acesso quando os módulos ou plugins forem reativados.

Por tanto, sempre quem plugin excluir uma chave de acesso, ou excluir o objeto de associado a uma chave de acesso, ele fica responsável por excluir os eventuais acessos dado para esta chave[/objeto]. Caso contrário o banco passará a ter registros e acessos sem utilidade.


Exibição de Chaves de Acesso
Embora o BIS não apague os acessos dado às chaves que não estão mais disponíveis ele não exibe esses acessos nas telas de permissões. Isso porque se um plugin ou módulo foi desabilitado suas chaves e acessos não podem ser modificados, e nem utilizados.

Usuários e Grupos de Acesso

O BIS suporta a criação de usuários de acesso ao sistema e a Criação de Grupos de Acesso. Todas as permissões de acesso devem ser definidas em um grupo, por isso chamado de grupo de acesso. Uma vez definidos os acessos no grupo, devem ser colocados os usuários para que estes ganhem o acesso.

O BIS não permite definir acessos diretamente no usuário. Acreditamos que a definição de acesso no usuário conduza o usuário a erros e definição de permissões erradas, já que teria que redefinir os acessos toda vez que um novo usuário é criado.

Grupo de Sistema, Grupo de Segurança e Grupo de Usuário

Existem três tipos de grupos que o sistema suporta:

  • Grupo de Usuário - Este grupo é criado e mantido pelo usuário conforme ele bem entender e achar necessário.
  • Grupo de Segurança - Esse grupo é internamente criado pelo sistema. Este tipo de grupo não pode ser excluído do sistema, nem seu Nome e Descrição podem ser alterados. Ele oferece acessos predefinidos pelas atualizações do sistema, mas que podem ser alteradas pelo usuário para personalizar melhor este grupo conforme as necessidades do usuário. A vantagem em um grupo assim é que o sistema pode incluir automaticamente novas permissões nestes grupos conforme o sistema evolui, sem tirar a autonomia do usuário em adaptar o grupo a sua necessidade. Definir novas permissões automaticamente durante as atualizações é viável pois evita que após uma atualização seja necessário definir manualmente todas as novas permissões para um determinado grupo de acesso.
  • Grupo de Sistema - Esse grupo é completamente fechado e não pode ser alterado em ponto algum pelo usuário. Nem ter suas permissões alteradas, nome alterado, descrição, etc. Apenas é permitido escolher quem participará deste grupo.


Identificação do Grupo
Durante o desenvolvimento, os grupos criados devem receber um 'innerID' único utilizado para identificar o grupo. Isso porque o ID pode variar de uma instalação para outra, já que o usuário pode ter criado seus próprios grupos, e novos grupos de Segurança e Sistema receberem IDs diferentes em casa instalação do sistema.


Controle de Acesso à Métodos do Fachada

A fachada do BIS tem sua segurança implementada no BISFacadeInterceptor. Todos os métodos da fachada por padrão devem receber como primeiro parâmetro uma String com o UUID da sessão do usuário. Essa UUID é fornecida quando o usuário chama o método doLogin() da fachada. O método doLogin() não exige a UUID, por razões óbvioas.

Para configurar os métodos da fachada, o método deve usar a Annotation Security e utilizar uma de suas opções de autenticação. A exigência da sessão (mandar a UUID como primeiro parâmetro do método) é a autenticação padrão e não exige a presença a Annotation. Para que não seja exigida a UUID ou outros tipos de definições a Annotation é obrigatória.

Quando o UUID está presente, o BISFacadeInterceptor recupera a sessão e a registra automaticamente no BISSessionManager para a Thread sendo utilizada.