diff --git a/documentation/reference/pt-BR/security.xml b/documentation/reference/pt-BR/security.xml index a37797c..4dc906b 100644 --- a/documentation/reference/pt-BR/security.xml +++ b/documentation/reference/pt-BR/security.xml @@ -1,6 +1,6 @@ + "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]> Segurança @@ -9,19 +9,21 @@ Neste capítulo será tratada uma questão de grande importância para a maioria das aplicações e motivo de infindáveis discussões nas equipes de desenvolvimento: controle de acesso. Assim como tudo relacionado ao framework, a implementação de segurança foi projetada de forma simples e flexível, independente de camada de apresentação ou - tecnologia, te deixando livre para implementar sua própria solução ou utilizar as extensões prontas, como a que - atualmente provemos baseada no Apache Shiro (). + tecnologia, te deixando livre para implementar sua própria solução ou utilizar as extensões existentes. - Para utilizar o modelo de segurança proposto basta utilizar o Demoiselle, pois no núcleo do Framework estão as + Para utilizar o modelo de segurança proposto basta utilizar o Framework Demoiselle, pois no núcleo do framework estão as interfaces e anotações que definem o comportamento básico da implementação.
Configurando + - Para um correto funcionamento do Demoiselle é necessário inserir os interceptadores de segurança no arquivo src/main/WEB-INF/beans.xml. + Para um correto funcionamento da segurança no Framework Demoiselle é necessário inserir os interceptadores de segurança no arquivo beans.xml, localizado + na pasta WEB-INF em projetos WEB ou na pasta META-INF em projetos SE ou EJB. + br.gov.frameworkdemoiselle.security.RequiredRoleInterceptor ]]> + + + Opcionalmente é possível configurar o comportamento do módulo de segurança definindo propriedades no arquivo demoiselle.properties + da sua aplicação. + + + + Propriedades de segurança do Framework Demoiselle + + + + + + + + Propriedade + Descrição + Valor padrão + + + + + frameworkdemoiselle.security.enabled + + + Habilita ou desabilita o mecanismo de segurança + + + true + + + + frameworkdemoiselle.security.authenticator.class + + + Define a classe que implementa o mecanismo de autenticação. + (Detalhes na seção Criando sua implementação) + + + + - + + + + + frameworkdemoiselle.security.authorizer.class + + + Define a classe que implementa o mecanismo de autorização. + (Detalhes na seção Criando sua implementação) + + + + - + + + + +
+
Autenticação - O mecanismo de autenticação busca verificar a identidade do usuário de um sistema. A forma mais conhecida, e comum, - para executar essa verificação se dá por meio de um formulário de login, geralmente solicitando um nome de usuário e + O mecanismo de autenticação busca verificar a identidade do usuário de um sistema. A forma mais conhecida - e comum - para + executar essa verificação se dá por meio de um formulário de login, geralmente solicitando um nome de usuário e sua respectiva senha. No entanto, outras formas como reconhecimento biométrico e autenticação por token, para citar - apenas duas, têm ganhado um grande número de adeptos. + apenas duas, tem ganhado um grande número de adeptos. - O Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua conveniência e necessidade. - A peça chave para tornar isso possível é o contexto de segurança, representado pela interface SecurityContext. Nessa + O Framework Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua conveniência e necessidade. + A peça chave para tornar isso possível é o contexto de segurança, representado pela interface SecurityContext. Nessa estão definidos os métodos responsáveis por gerenciar os mecanismos de autenticação como, por exemplo, executar login/logout de usuários e verificar se os mesmos estão ou não autenticados. - O contexto de segurança irá direcionar as requisições para a implementação definida pela aplicação. A autenticação será - efetuada por uma classe que implemente a interface Authenticator, cujo método authenticate() é responsável por - executar os passos necessários para validar a identidade de um usuário. Nesta mesma interface serão encontrados, - ainda, os métodos unAuthenticate() e getUser(), responsáveis por, respectivamente, desautenticar e retornar o usuário - autenticado. - - - Para exemplificar, consideremos a autenticação baseada em nome de usuário e senha. O primeiro passo é criar um bean para - armazenar essas informações: + Para utilizar o SecurityContext, basta injetá-lo em seu código. O método login ativa o mecanismo de autenticação + e o método logout remove as credenciais atualmente autenticadas do sistema. A classe SecurityContext possui + outros métodos que permitem verificar se há um usuário autenticado e acessar o objeto gerente (representado pela + classe javax.security.Principal), um objeto que contém dados adicionais sobre o usuário atualmente autenticado. Consulte + a documentação da classe SecurityContext para consultar as funcionalidades que ela oferece. - - Feito isso, podemos implementar a classe na qual se deseja adicionar o mecanismo de segurança: + Um exemplo do uso do SecurityContext para autenticação segue abaixo: - - - Neste caso, a interface SecurityContext e o bean Credential estão sendo injetados na classe utilizando o CDI. - Dentro do método, ao definir o usuário e a senha e invocar “context.login()”, a implementação de segurança definida irá - tratar essa requisição de acordo com os critérios estabelecidos. -
Autorização - O mecanismo de autorização é responsável por garantir que apenas usuários autorizados tenham o acesso concedido a - determinados recursos de um sistema. No modelo de segurança do Demoiselle 2, a autorização pode acontecer de duas + Em certos sistemas é necessário não apenas autenticar um usuário, mas também proteger funcionalidades individuais e separar + usuários em grupos que possuem diferentes autorizações de acesso. O mecanismo de autorização é responsável por garantir que apenas + usuários autorizados tenham o acesso concedido a determinados recursos de um sistema. + + + + No modelo de segurança do Framework Demoiselle, a autorização pode acontecer de duas formas: - Permissão por usuário, através da anotação @RequiredPermission + Permissão por funcionalidade, através da anotação @RequiredPermission Permissão por papel, através da anotação @RequiredRole - - Novamente a interface SecurityContext é a responsável pela interação entre as funcionalidades da aplicação e a implementação de - segurança. Nela estão definidos os métodos que verificam se o usuário possui permissão para acessar um recurso ou se o - usuário está associado a um papel. - - - A anotação @RequiredPermission pode ser utilizada tanto em classes como em métodos e possui dois parâmetros opcionais: - “operation” e “resource”. O primeiro define a operação para a qual se deseja permissão e o segundo define em qual - recurso essa operação será realizada. Abaixo serão exemplificadas algumas formas de utilização: - - + Protegendo o sistema com <emphasis>@RequiredPermission</emphasis> + + + A anotação @RequiredPermission permite marcar uma classe ou método e informar que acesso a esse recurso requer + a permissão de executar uma operação. Operação nesse contexto é um nome definido pelo desenvolvedor + que representa uma funcionalidade do sistema. Por exemplo, determinada classe pode ter métodos responsávels por criar, editar, + listar e remover bookmarks, o desenvolvedor pode decidir agrupar esses métodos sobre a operação gerenciar bookmark. + + + listarBookmarks() { + //Código do método + } + + @RequiredPermission + public List apagarBookmark(Long idBookmark) { + public List listarBookmarks() { + } }]]> + + + Perceba que a anotação @RequiredPermission sobre o método apagarBookmark não contém parâmetros. Quando não + são passados parâmetros o valor padrão para o parâmetro resource é o nome da classe e o valor padrão para operation + é o nome do método. + + + + É possível anotar a classe inteira com @RequiredPermission, isso protegerá o acesso a todos os métodos dessa classe. + + listarBookmarks() { + //Código do método + } + + public List apagarBookmark(Long idBookmark) { + public List listarBookmarks() { + } +}]]> + +
+ +
+ Protegendo o sistema com <emphasis>@RequiredRole</emphasis> + + + Diferente de @RequiredPermission, a anotação @RequiredRole utiliza o conceito + de papéis - ou perfís - para proteger recursos. Uma classe ou método anotado com @RequiredRole + exigirá que o usuário autenticado possua o papel indicado para acessar o recurso. + + + + Voltando ao exemplo de nosso aplicativo de bookmarks, vamos supor que a função de listar os bookmarks existentes + pode ser acessada por qualquer usuário autenticado, mas apenas administradores podem criar um novo bookmark. A classe + responsável por tais funcionalidades pode ser criada da seguinte forma: + + + listarBookmarks() { + } + +}]]> + + + É possível informar mais de um papel para a anotação @RequiredRole, neste caso basta que o usuário + autenticado possua um dos papéis listados para ter acesso ao recurso. + + + + Da mesma forma que a anotação @RequiredPermission, a anotação @RequiredRole pode ser usada + a nível de classe para proteger todos os métodos contidos nessa classe. + +
+ +
+ Protegendo porções do código + + + É possível proteger apenas parte de um código ao invés de todo o método ou toda a classe. Isso pode ser necessário em + expressões condicionais, onde um trecho só deve ser executado caso o usuário possua a autorização necessária. + Para isso voltamos a usar a interface SecurityContext, pois ela contém métodos que são funcionalmente equivalentes + às anotações @RequiredPermission e @RequiredRole. + + + + Como um exemplo, vamos supor que ao remover um bookmark um email seja enviado ao administrador, mas se o próprio + administrador executou a operação não é necessário enviar o email. + + + + +
+ +
+ Protegendo porções de páginas <code>Java Server Faces</code> + + + As restrições de segurança podem ser utilizadas ainda em páginas web, com o auxílio de Expression Language. A interface + SecurityContext está automaticamente disponível para páginas Java Server Faces como um bean + de nome securityContext, bastando então acessar seus métodos a partir deste bean. + + + ]]> + + + Nesse caso, a habilitação de um botão está condicionada à existência de permissão para o usuário autenticado no momento + executar a operação “insert” no recurso “contact”. + +
+ + +
+ Redirecionando automaticamente para um formulário de acesso + + + Se sua aplicação usa a extensão demoiselle-jsf ou se você utilizou o arquétipo demoiselle-jsf-jpa + durante a criação de seu projeto, então você pode definir uma página de login e o Framework Demoiselle vai automaticamente lhe redirecionar + para essa página caso haja a tentativa de acessar um recurso protejido e nenhum usuário esteja autenticado no sistema. + + + + Para acrescentar a extensão demoiselle-jsf em um projeto Maven, adicione a dependência abaixo + no arquivo pom.xml. + + + br.gov.frameworkdemoiselle + demoiselle-jsf + compile +]]> + + + O arquétipo demoiselle-jsf-jpa já contém essa extensão, se você criou seu projeto + baseado nesse arquétipo nada precisa ser feito. + + + - Observe o método cuja anotação não possui parâmetros. Nesse caso serão considerados como recurso e operação o nome da classe e - do método, respectivamente. Uma outra possibilidade seria utilizar a anotação @Name, tanto na classe como no método, de - forma a possibilitar uma descrição mais amigável para o usuário. + Por padrão a página contendo o formulário de login deve se chamar login.jsp ou login.xhtml + (a depender de como sua aplicação esteja configurada para mapear páginas JSF). Para mudar esse padrão, é possível + editar o arquivo demoiselle.properties para configurar qual página deve ser utilizada. + + + Propriedades de segurança da extensão <emphasis>demoiselle-jsf</emphasis> + + + + + + + + Propriedade + Descrição + Valor padrão + + + + + frameworkdemoiselle.security.login.page + + + Define a página de login da aplicação. + + + "/login" + + + frameworkdemoiselle.security.redirect.after.login + + + Define a tela para qual o usuário será redirecionado após o processo de login bem sucedido. + + + "/index" + + + frameworkdemoiselle.security.redirect.after.logout + + + Define a tela para qual o usuário será redirecionado após o processo de logout bem sucedido. + + + "/login" + + + frameworkdemoiselle.security.redirect.enabled + + + Habilita ou desabilita o redirecionamento automático para a página de login após uma tentativa + de acessar recurso protegido. + + + true + + + +
+ +
+ +
+ Integrando o Framework Demoiselle com a especificação JAAS + - Assim como na autenticação, o contexto de segurança possui métodos destinados a delegar as requisições de autorização para - a implementação de segurança. No caso da anotação @RequiredPermission, o método hasPermission(String resource, String - operation) executa esta tarefa. Para tanto, deve existir uma classe que implemente a interface Authorizer, cujo - método hasPermission(Object resource, String operation) verifica se o usuário logado possui permissão para executar - uma determinada operação em um recurso específico. + Até agora vimos como criar código protegido em uma aplicação Demoiselle, mas nada foi dito sobre a tecnologia que implementa essa + proteção. A verdade é que o Framework Demoiselle dá ao desenvolvedor a liberdade de implementar a solução que mais se adequa ao sistema + desenvolvido, mas o framework também conta com suporte nativo à especificação JAAS (Java Authentication and + Authorization Service). + - Ainda na interface Authorizer, pode-se notar a existência do método hasRole(String role), responsável por verificar se o - usuário logado possui um papel específico. Este método é chamado pelo contexto de segurança, por meio do seu método - hasRole(String role), para tratar as requisições que possuam a anotação @RequiredRole. Essa anotação possui um - parâmetro obrigatório, no qual podem ser definidos uma simples role ou um array delas. + O suporte a JAAS é fornecido para aplicações WEB e está implementado na extensão + demoiselle-servlet, então é necessário declarar a dependência a essa extensão em sua aplicação. - + Para acrescentar a extensão demoiselle-servlet em um projeto Maven, adicione a dependência abaixo + no arquivo pom.xml. + + + br.gov.frameworkdemoiselle + demoiselle-servlet + compile +]]> + + + + + O arquétipo demoiselle-jsf-jpa já conta com a dependência à extensão demoiselle-jsf, que + por sua vez depende da extensão demoiselle-servlet. Se sua aplicação é baseada no arquétipo + demoiselle-jsf-jpa você já possui a extensão demoiselle-servlet. + + + + + Uma vez que sua aplicação contenha a extensão demoiselle-servlet, tudo que você precisa fazer é configurar + o suporte a JAAS em seu servidor de aplicação e criar os usuários e papéis necessários. Esta configuração depende do servidor de + aplicação utilizado e foge ao escopo deste documento. + + + + Para autenticar um usuário presente no servidor de aplicação através do JAAS, a extensão demoiselle-servlet + oferece a classe Credentials, que deve ser injetada em seu código. O código abaixo mostra como realizar a autenticação a partir de um servlet. + + + + - As restrições de segurança pode ser utilizadas, ainda, em páginas web, com o auxílio de Expression Language, como no - exemplo abaixo: - - ]]> - - Nesse caso, a habilitação de um botão está condicionada à existência de permissão para o usuário autenticado no momento - executar a operação “insert” no recurso “contact”. + Uma vez autenticado o usuário, a anotação @RequiredRole passará a verificar se o usuário presente no JAAS possui o papel informado. + + + + A especificação JAAS não prevê o uso de permissões para proteger recursos, apenas papéis de usuários. Por isso ao utilizar a segurança + da especificação JAAS o uso da anotação @RequiredPermission fica vetado. Utilizar essa anotação em um sistema que utilize + JAAS para autorização causará uma exceção quando o recurso for acessado. + + + + + + É possível utilizar o JAAS para autenticar e autorizar papéis de usuários mas criar sua própria implementação para + implementar a autorização de permissões. Para isso crie uma classe que herde a classe + br.gov.frameworkdemoiselle.security.ServletAuthorizer e sobrescreva o método hasPermission(String resource, String operation) + para implementar seu próprio mecanismo. Feito isso, basta definir sua classe no arquivo demoiselle.properties usando + a propriedade frameworkdemoiselle.security.authorizer.class. + + + + Mais detalhes sobre como criar sua própria implementação ou extender uma implementação existente podem + ser vistos na seção Criando sua implementação. + + +
-
+
Criando sua implementação + - Após toda essa explicação, fica a dúvida: como implementar um esquema de segurança sem utilizar a extensão existente? + Para os mecanismos de autenticação não cobertos pelo Framework Demoiselle, é possível criar sua própria implementação e integra-la + ao framework. Também é possível extender uma implementação existente e acrescentar funcionalidades inexistentes. + - O primeiro passo é criar classes para implementar as interfaces Authenticator e Authorizer. O Demoiselle detecta automaticamente - a implementação, e torna essa classe a implementação padrão dessas interfaces: + O ponto de extensão para o módulo de segurança são as interfaces Authenticator e Authorizer. Para criar + um novo mecanismo de autenticação e autorização, é necessário apenas implementar essas duas interfaces em sua aplicação. Segue + abaixo um exemplo de implementação. + - + Pronto! Sua aplicação já possui uma implementação de segurança definida. - + + + + Você nunca deve chamar diretamente em sua aplicação as implementações das interfaces Authenticator + e Authorizer, o Framework Demoiselle vai automaticamente chamar os métodos implementados + quando for necessário. + + + - Caso sua aplicação detecte o uso das anotações @RequiredRole e @RequiredPermission mas nenhuma classe - implemente essas interfaces, no momento em que os recursos anotados forem acessados, o framework lançará uma exceção informando que a - aplicação precisa implementá-las. + Em um sistema que use as anotações @RequiredRole ou @RequiredPermission, deve haver pelo menos uma implementação + dessas duas interfaces. Ao processar essas anotações, o Framework Demoiselle vai buscar uma implementação para essas interfaces + e disparar uma exceção caso não encontre uma implementação adequada. + - Se você tem mais de uma implementação de Authenticator e/ou Authorizer (o que pode acontecer, por exemplo, quando - se necessite de uma implementação na aplicação principal, e outra para os testes), deverá definir no arquivo demoiselle.properties - qual classe será a padrão: - frameworkdemoiselle.security.authenticator.class=projeto.MeuAuthenticatorPadrao -frameworkdemoiselle.security.authorizer.class=projeto.MeuAuthorizerPadrao + Se existe mais de uma implementação de Authenticator e/ou Authorizer (o que pode acontecer, por exemplo, quando + seja necessário uma implementação na aplicação principal e outra para os testes), é possível definir no arquivo demoiselle.properties + a classe que deve ser usada por padrão: + + + + + + + + + + Propriedade + Descrição + Valor padrão + + + + + frameworkdemoiselle.security.authenticator.class + + + Define a classe concreta utilizada como implementação da interface Authenticator + + + + + nenhum, se houver apenas uma implementação o framework a detectará + automaticamente sem necessidade de definir essa propriedade + + + + + + frameworkdemoiselle.security.authorizer.class + + + Define a classe concreta utilizada como implementação da interface Authorizer + + + + + nenhum, se houver apenas uma implementação o framework a detectará + automaticamente sem necessidade de definir essa propriedade + + + + + +
- O Demoiselle também oferece o componente - demoiselle-authorization - que facilita o uso de segurança com JAAS. Obviamente, não é possível utilizá-los ao mesmo tempo. Há arquétipos Maven que já trazem esse componente - como dependência, por isso sempre confira o arquivo pom.xml e se for o caso retire essa dependência. - + \ No newline at end of file -- libgit2 0.21.2