• Nenhum resultado encontrado

Esta seção apresenta uma proposta de visão da arquitetura considerando a inclu- são dos componentes da infraestrutura de autorização, como também a implementação dos componentes que não são disponibilizados pelo servidor de autorização (WSO2 IS) selecionado para este estudo.

4.2.1

Arquitetura

Na fase 1 é proposto avaliar a infraestrutura de autorização de uma aplicação existente, no nosso caso, o SUAP, e a mesma foi apresentada na figura 7 da seção que apresenta o SUAP no referencial teórico. No contexto do sistema SUAP, observa-se que a autenticação é externalizada, já que a base de usuários é gerenciada em um serviço de diretório Microsoft Active Directory, entretanto, a autorização é realizada pelo framework

Django, e as restrições aos recursos são aplicadas diretamente no código da aplicação.

Para suportar a externalização dos mecanismos de controle de acesso no SUAP foi necessário propor uma nova arquitetura de autorização. A figura 13 apresenta uma visão da arquitetura de externalização, onde sombreado na cor azul destaca-se uma visão da aplicação SUAP e suas camadas (apresentação, negócio e dados), e para proteger a aplicação/API/etc. é inserido um PEP. Os detalhes de implementação do PEP serão apre- sentados na sub-seção 4.2.2. Os componentes sombreados na cor vermelha e posicionados a direita são relacionados aos serviços de autorização. O servidor de autorização atua como uma interface PDP (decisão baseada nas políticas), e o PAP (acesso ao repositório de políticas). Opcionalmente um PIP pode ser integrado ao servidor de autorização para recuperar atributos de outras fontes (LDAP, banco, etc.). O funcionamento do PIP e um exemplo de implementação são apresentados na sub-seção 4.2.3.

Figura 13 – Visão da arquitetura de autorização externalizada para o SUAP

Fonte: Elaborado pelo autor

De uma forma geral, os componentes desta arquitetura funcionam da seguinte forma: um usuário ao tentar acessar um recurso protegido no sistema (o SUAP nesse

estudo de caso) terá sua requisição interceptada por um PEP. Este PEP irá recuperar alguns atributos da requisição (URL, usuário logado, verbo HTTP, etc.), em seguida irá encaminhar esses atributos para a interface PDP do servidor de autorização (WSO2 IS). O PDP irá recuperar a partir da interface PAP as políticas de controle de acesso que estão publicadas, e irá computar a decisão confrontando os valores dos atributos enviados pelo PEP com os valores esperados pela política cadastrada no PAP. Nos casos onde a política requer atributos que não foram enviados pelo PEP ocorre a chamada a interface PIP. A interface PIP irá conter uma lista de atributos suportados, e caso o atributo esperado pelo PDP seja suportado pelo PIP o mesmo será acionado.

4.2.2

Implementação do PEP

Inicialmente foram realizadas buscas em repositórios de códigos na internet com intuito de encontrar a implementação de um PEP de exemplo na linguagem Python, mas não foi obtido êxito. Diante do fato, é proposto, implementado, e disponibilizado publicamente o projeto DjangoPEP1.

O DjangoPEP é implementado sob a camada de middleware2 do Django, a qual

possibilita que todas as requisições HTTP direcionadas ao sistema desenvolvido em

Django sejam interceptadas antes de serem executadas, e a partir dessas requisições são

coletados alguns atributos como usuário logado (sujeito no contexto do ABAC), URL (recurso), e verbo HTTP (ação) de forma transparente. Na fase seguinte, o DjangoPEP gera uma requisição de autorização XACML (XACML Request)(PARDUCCI; LOCKHART; RISSANEN, 2013), e envia para o PDP através de uma API REST do servidor de autorização para que a decisão de permitir ou não o acesso seja computada. O PDP devolve a decisão para o DjangoPEP, e se a mesma for Permit a requisição irá prosseguir, se for diferente (deny ou outras), a requisição será negada (HTTP 403 / Forbidden).

A figura14 apresenta a arquitetura de middleware do Django. Durante o ciclo da requisição as classes de middleware são executadas de forma sequencial iniciando pelo topo (CommonMiddleware na figura). Cada classe middleware tem sua função, como o tratamento de User-Agents na classe CommonMiddleware, sessões (SessionMiddleware), proteção contra ataques de Cross Site Request Forgery ou CSRF (CsrfViewMiddleware), autenticação de usuários (AuthenticationMiddleware), suporte a mensagens baseadas em sessões ou cookies (MessageMiddleware), entre outros.

A última caixa (destacada na cor vermelha) é o DjangoPEPMiddleware, a proposta de PEP para projetos Django, que coleta os atributos, envia para o servidor de autorização, e de acordo com a decisão do PDP permite ou não a continuidade do acesso. Caso o 1 https://github.com/welkson/DjangoPEP

acesso seja permitido, o método process_view da camada de middleware libera o acesso ao recurso (pega os dados na view function e devolve para o usuário via process_response).

Figura 14 – Arquitetura do DjangoPEP

Fonte: Elaborado pelo autor baseado em Django (2015)

A ativação do DjangoPEP é realizada no arquivo de configuração settings.py, no grupo de configuração “MIDDLEWARE”, e deve ser posicionado na última linha conforme exemplo destacado na listagem 4.1.

1 MIDDLEWARE = [ 2 'django.middleware.common.CommonMiddleware', 3 'django.contrib.sessions.middleware.SessionMiddleware', 4 'django.middleware.csrf.CsrfViewMiddleware', 5 'django.contrib.auth.middleware.AuthenticationMiddleware', 6 'django.contrib.messages.middleware.MessageMiddleware', 7 'suap.middleware.django_pep.DjangoPEPMiddleware', 8 ]

Listagem 4.1 – Registro do middleware no settings.py

Ainda no settings.py, é necessário definir os parâmetros do DjangoPEP conforme demonstra a listagem4.2. Na propriedade “DJANGOPEP_PRODUCT” deve ser informado o servidor de autorização a ser utilizado como PDP/PAP/etc., sendo o valor 1 para o WSO2- IS e 2 para o FIware AuthZForce. No “DJANGOPEP_URL” é informado a URL do servidor de autorização que fornece a interface PDP, e os parâmetros “DJANGOPEP_USER”, “DJANGOPEP_PASSWORD” e “DJANGOPEP_TOKEN” são utilizados para autenticar o DjangoPEP no servidor de autorização, sendo possível utilizar usuário e senhas, ou um token OAuth.

1 # DjangoPEP Middleware settings

2 DJANGOPEP_PRODUCT = 1 # 1-WSO2 IS, 2-AuthZForce

3 DJANGOPEP_URL = 'https://localhost:9443/api/identity/entitlement/decision/pdp' 4 DJANGOPEP_USER = 'admin'

5 DJANGOPEP_PASSWORD = 'example' 6 DJANGOPEP_TOKEN = ''

7 DJANGOPEP_DEBUG = True

8 DJANGOPEP_IGNORE = ['/$', '/admin/*', '/accounts/*', '/comum/*', '/media/*']

Listagem 4.2 – Configuração do middleware DjangoPEP no settings.py

O parâmetro “DJANGOPEP_DEBUG” por padrão é desativado (definido como “False”), no entanto pode ser habilitado (alterando para “True”) quando o desenvolvedor desejar ativar o modo de depuração, que exibe as respostas fornecidas pela interface PDP do servidor de autorização (XACML Response).

Por fim, no parâmetro “DJANGOPEP_IGNORE” é possível especificar uma lista de URLs a serem ignoradas pelo DjangoPEP durante a interceptação das requisições, por exemplo, a URL /accounts/login/ é utilizada no Django para a tela de login e deve ser ignorada, pois antes de tratar as requisições de autorização o usuário deve está pelo menos logado (fase de autenticação).

4.2.3

Implementação do PIP

Comumente as soluções de servidores de autorização fornecem interfaces que podem ser implementadas para desenvolver um PIP customizado. No caso do WSO2, é necessário criar uma classe que implemente a interface PIPAttributeFinder ou herde a classe abstrata

AbstractPIPAttributeFinder 3. O projeto do PIP irá gerar um pacote Jar, que será registrado

no WSO2 e disponibilizado para instanciação pelo PDP durante a fase de decisão. Durante o estudo para aplicação da infraestrutura de autorização no sistema SUAP observou-se a necessidade de implementar um PIP que recupere os valores dos atributos de um serviço de diretório LDAP e de um banco de dados Postgres. A figura 15 apresenta um diagrama de classes da solução WSO2-SUAP-PIP.

A principal classe do WSO2-SUAP-PIP é a SuapAttributeFinder. Ela possui uma lista de atributos suportados pelo PIP (propriedade supportedAttributes), e implementa os métodos init(), getModuleName(), getAttributeValues() e getSupportedAttributes() que são definidos na interface PIPAttributeFinder. A lista de atributos suportados é definida com base em um arquivo de configurações localizado no diretório do WSO2. Toda interação com esse arquivo é realizada através da classe utilitária ConfigUtil.

A classe utilitária ConfigUtil é responsável por fornecer um ponto único de acesso as configurações do PIP. Com o objetivo de garantir que exista uma única instância do tipo ConfigUtil durante toda a execução do PIP, foi adotado o padrão de projeto Singleton 3 https://docs.wso2.com/display/IS550/Writing+a+Custom+Policy+Info+Point

Figura 15 – Diagrama de classes do WSO2-PIP-SUAP

Fonte: Elaborado pelo autor

(GAMMA et al.,1995). A classe localiza, lê e carrega as configurações definidas no arquivo de propriedades.

A classe Factory é responsável por criar os conectores utilizados pelo PIP. Esta classe possui um método fábrica (padrão de projeto Factory Method) (GAMMA et al., 1995), que instancia objetos do tipo Connector. Para instanciar dinamicamente cada conector, optamos pelo uso de reflexão (API Java Reflection4), e de um arquivo de configurações

(wso2-pip-suap.properties), por exemplo, o conector de LDAP pode ser utilizado para recuperar 3 atributos, e o conector do Postgres utilizado para recuperar 5 atributos, sendo portanto a lista de atributos suportados por cada conector definida no arquivo properties, e a instanciação dinâmica de cada conector é realizada de acordo com o atributo sendo requisitado no momento. Essa decisão objetiva diminuir o acoplamento entre os conectores e as demais classes, bem como simplificar a extensão ou inclusão de novos conectores à implementação atual. Da mesma forma que a classe ConfigUtil, a classe Factory também implementa o padrão de projeto Singleton.

As fontes de dados utilizadas para recuperação dos atributos no contexto desta aplicação são denominadas conectores. A implementação atual do PIP suporta dois co- 4 https://docs.oracle.com/javase/tutorial/reflect/index.html

nectores, sendo estes implementados pelas classes PgConnector e LdapConnector. Cada conector pode suportar um ou mais atributos. Por exemplo, no conector do banco Postgres (PgConnector ), atualmente é recuperado o atributo “solicitante” da central de serviços, no entanto outros atributos relacionados a esta mesma fonte de dados podem ser implementa- dos na classe. Para diminuir a quantidade de recursos alocados com as fontes de dados, os conectores implementam o padrão de projeto Singleton, mantendo uma única conexão ao recurso estabelecida.

A classe TipoAtributo e outras não representadas no diagrama, são classes acessórias responsáveis por realizar pequenas tarefas secundárias, resultantes de refatorações do código ao logo do tempo, com o objetivo de melhorar a legibilidade do código, não impactando na função do PIP. Por tal motivo, elas não foram descritas nesta seção.

O código-fonte da aplicação WSO2-SUAP-PIP está disponível publicamente no repositório GitHub 5. A configuração e integração com o WSO2 são apresentadas no arquivo README que acompanha o código da aplicação.

4.3

Demonstração

Esta seção apresenta uma demonstração da aplicação das fases de externalização descritas na seção anterior. Uma instância do SUAP é configurada seguindo o procedi- mento padrão descrito no manual de instalação do sistema, em seguida são realizados os procedimentos (fases) necessários para externalizar os mecanismos de autorização conforme descrito na seção 4.1.

A fase 1 orienta a “Avaliar mecanismos de autorização no SUAP”. Conforme descrito anteriormente, no SUAP a autorização é baseada no modelo RBAC implementada por um middleware de controle de acesso do Django, e as restrições de acesso são aplicadas diretamente no código da aplicação (hard-coded), portanto é pouco flexível no contexto de ambientes dinâmicos que necessitam mudar restrições de acesso com maior agilidade. Usando o módulo “Central de Serviços” como modelo, diversas restrições de acesso são aplicadas no código da aplicação (hard-coded) na forma de decorator (anotação de método), por exemplo, o decorator “@permission_required([’centralservicos.add_chamado’])” é aplicado ao método abrir_chamado com a finalidade de restringir a criação de novos chamados apenas para usuários com a permissão add_chamado, e neste mesmo método é aplicada uma outra restrição no código para garantir que chamados relacionados a serviços inativos sejam bloqueados (código Python: if not servico.ativo), além de outras restrições como exibir o chamado apenas para o usuário que solicitou o atendimento em questão. Essas restrições poderiam ser removidas do código e implementados em uma política XACML no servidor de autorização externo a aplicação, que possibilita a implementação 5 https://github.com/welkson/WSO2-SUAP-PIP

de políticas de granularidade fina como esta em questão, além de expor interfaces para que esta política possa ser ajustada dinamicamente em um contexto de uma infraestrutura de autorização auto-adaptativa.

A fase 2 orienta a “Definir Servidor de Autorização’. Conforme descrito no capítulo

2, há diversas soluções open-source e comerciais de servidores de autorização. No nosso estudo a solução escolhida é o WSO2 Identity Server, por ser uma ferramenta open-source de alta maturidade na indústria. O WSO2 IS irá fornecer a interface PDP (decisão) e PAP (gerenciamento de políticas), além de expor pontos de extensão a serem utilizados para

implementação do PIP descrito na seção 4.2.3.

Para manter um ambiente similar ao usado no SUAP em produção, o sistema operacional escolhido para instalação do servidor de autorização, o SUAP e demais componentes da infraestrutura de autorização é o Debian Linux 9 (Stretch) 6. A versão

wso2is-5.4.0-update27 do WSO2 é utilizada.

Após o término da inicialização do WSO2 IS, a interface web de gerenciamento (Carbon) poderá ser acessada através de um browser (exemplo: https://10.22.0.122:9443/ - onde 192.168.0.122 é o IP da máquina virtual utilizada durante os experimentos para

instalação do WSO2). Via Carbon deve ser realizada a inserção da política XACML gerada via ALFA na fase 3. Para inserir é necessário acessar Entitlement -> PAP -> Policy

Administration, em seguida clicar em Add New Entitlement Policy, e depois em Write Policy in XACML. No Policy Editor o código da política XACML (XML gerado pelo

ALFA) deve ser inserido e salvo (Save Policy). Na listagem de políticas é necessário clicar em Publish To My PDP na política que acaba de ser inserida para que a mesma seja disponibilizada para uso no PDP.

Usando como base as restrições aplicadas no código de algumas operações do módulo Central de Serviços, deu-se início a fase 3, “Definir política ABAC baseada nas políticas identificadas”. Para facilitar a implementação da política XACML é utilizado um plugin para Eclipse denominado ALFA 8, que é distribuído gratuitamente pela empresa Axiomatics. O ALFA permite implementar políticas XACML de forma simples utilizando

uma linguagem de alto nível. A implementação de uma regra na política XACML em ALFA para a operação “Visualizar Chamado” da central de serviços do SUAP é descrita na listagem 4.3.

1 namespace CentralServicos {

2 policy central_servicos = "central_servicos"{ 3 applydenyUnlessPermit

4

5 rulevisualizar_chamado {

6 targetclause stringRegexpMatch("^.*/centralservicos/chamado/[0-9]*/$",

7 Attributes.resourceId)

6 https://www.debian.org/index.pt.html

7 https://github.com/wso2/product-is/releases/tag/v5.4.0-update2 8 https://www.axiomatics.com/product/developer-tools-and-apis/

8 clause Attributes.actionId == "GET"

9 condition chamado.solicitante == Attributes.subjectId 10 permit

11 }

12 }

Listagem 4.3 – Política XACML em ALFA para a operação Visualizar Chamado As linhas 1, 2 definem o grupo a qual a política pertence (namespace) e o nome da política (policy central_servicos). Na linha 3 é definido que por padrão todas as requisições devem ser negadas, exceto as explicitamente definidas nas regras. Na linha 5 define-se o nome da regra, e entre 6 e 8 a clausula target define os atributos e os valores esperados. No atributo de recurso (resourceId) é definido via expressão regular que o valor esperado pode começar com qualquer domínio (ex: suap.ifrn.edu.br, suap.xyz.edu.br, entre outros), e o recurso a ser protegido é “/centralservicos/chamado/”, e por fim o número do chamado (somente números entre 0 e 9). Além do atributo de recurso, a regra define que o verbo HTTP dessa operação deve ser um “GET” (atributo de ação no contexto do ABAC), e que apenas o dono do chamado deverá ter permissão para visualiza-lo (atributo de sujeito recuperado via PIP: subjectId). Por fim, na linha 10 é definida a decisão a ser tomada caso os valores do atributos enviados pelo PEP (ou recuperados via PIP) estejam de acordo com o especificado na regra, e neste caso é permit (permitir).

Ao salvar a implementação em ALFA descrita anteriormente, o Eclipse irá gerar automaticamente o arquivo XML com o código XACML da política no diretório src-gen. Uma das formas de testar a política é instalar no ambiente de desenvolvimento uma versão do WSO2 IS, inserir a política no PAP, e efetuar testes simulando um PEP com a funcionalidade Try It9.

O exemplo citado anteriormente implementa uma regra na política de controle de acesso do módulo central de serviços do SUAP para uma determinada operação (visualizar chamado), entretanto, este módulo contém dezenas de outras operações com suas respectivas restrições aplicadas diretamente no código (hard-coded) que também devem ser consideradas na implementação da política ABAC/XACML conforme descrito na fase 3, no entanto, a implementação dessas demais regras foge do escopo deste trabalho, que tem por objetivo demonstrar o processo de externalização do controle de acesso a partir de alguns exemplos reais.

Com a política ABAC/XACML implementada, o próximo passo é implantar um PEP na aplicação legada para interceptar as requisições e encaminhar para um servidor de autorização externo à aplicação conforme descrito na fase 4. O SUAP é desenvolvido em Python e Django, e não dispõe de implementação de referência de um PEP, sendo necessário propor e implementar um PEP para continuidade desta proposta. O PEP 9 https://docs.wso2.com/display/IS530/Evaluating+a+XACML+Policy

DjangoPEP tem sua implementação descrita na seção4.2.2. A configuração do DjangoPEP no SUAP segue o que está descrito na seção de implementação do PEP.

Conforme descrito anteriormente, o PEP captura atributos da requisição como usuário logado, URL sendo acessada, verbo HTTP, entre outros, no entanto, por ser um componente genérico, o PEP não consegue recuperar atributos específicos do módulo que está sendo protegido. Na política implementada na fase 3 o atributo “chamado.solicitante” é considerado, e este por ser específico do SUAP não pode ser recuperado pelo PEP. Nesses casos é necessário implementar uma extensão ao servidor de autorização denominada PIP (fase 5)para que o mesmo recupere de fontes externas esse tipo de atributo para auxiliar na decisão do PDP. Um PIP para este estudo é proposto (WSO2-SUAP-PIP), onde atributos do banco de dados PostgreSQL e de um diretório LDAP (Microsoft AD) são recuperados. Os detalhes da implementação e configuração do PIP são descritos no capítulo 4, seção4.2.3, e o código está disponível no GitHub 10.

Com os componentes da externalização devidamente instalados, a próximo etapa é “Testar nova infraestrutura de autorização” conforme descrito na fase 6. Inicialmente o WSO2 deve ser inicializado, e os logs exibidos durante esse processo devem ser atentamente observados para detectar possíveis erros durante o registro do PIP, ou erros em outros módulos que possam comprometer o funcionamento das demais interfaces necessárias para o funcionamento da infraestrutura de autorização (PDP, PAP, etc.). O fork do SUAP onde foi instalado o middleware PEP (SUAP-Externalizado) deve ser configurado com modo

debug habilitado (DJANGOPEP_DEBUG=True no arquivo settings.py), em seguida o

SUAP deve ser iniciado (./manage.py runserver ), alguns acessos ao SUAP via browser devem ser realizados, e os trace logs do PEP via console devem ser observados com intuito de garantir que as requisições estão sendo interceptadas e que os atributos genéricos estão sendo recuperados. Após estes testes iniciais o debug do PEP pode ser desabilitado para não comprometer o desempenho da infraestrutura de autorização.

Se os testes realizados nos componentes da externalização forem bem sucedidos, a próxima etapa é Desativação dos mecanismos anteriores conforme descreve a fase 7. As restrições de controle de acesso que estavam implementadas diretamente no código da aplicação (hard-coded) devem ser removidas, pois nessa fase as mesmas já devem está devidamente implementadas em XACML e publicadas no servidor de autorização, ou seja, as restrições foram movidas para fora do código da aplicação, permitindo uma maior flexibilidade e facilidade de manutenção.

Por fim, após a implantação de toda a infraestrutura de autorização externalizada, o próximo passo é manter atualizada as políticas de controle de acesso ABAC considerando mudanças no sistema que possam surgir, como correções de bugs, implementações de novos módulos, entre outros, e também manter atualizados e sob monitoramento os novos 10 https://github.com/welkson/WSO2-SUAP-PIP

componentes, como o PEP e serviços do servidor de autorização (PDP, PIP).

4.4

Discussão

Esta capítulo apresentou um estudo sobre a externalização dos mecanismos de autorização em um sistema real, o SUAP. A documentação oficial do ABAC e outros artigos da literatura descrevem os componentes da infraestrutura de autorização como o PEP, PIP, PDP, mas não propõe um processo ou um detalhamento em fases dos procedimentos a serem realizados para externalizar os mecanismos de autorização. Alguns estudos propõe exemplos utilizando aplicações simples, que não consideram os desafios encontrados na aplicação da abordagem em um sistema real.

Diante do exposto, foi proposto uma lista de fases descrevendo os procedimentos a serem seguidos para externalizar os mecanismos de autorização, além da proposta e implementação de alguns componentes da infraestrutura de autorização como PEP e PIP. Por fim, foi realizado uma demonstração detalhando a aplicação de cada uma das fases na externalização no SUAP.

A avaliação da infraestrutura de autorização e demais componentes envolvidos na externalização do SUAP será realizada no capítulo a seguir.

5 Avaliação

Este capítulo apresenta a avaliação da proposta deste trabalho. A avaliação está dividida em 2 etapas, sendo a primeira relacionada ao suporte a auto-adaptação de políticas de controle de acesso em infraestruturas de autorização usando o SecAuthAPI (apresentado

Documentos relacionados