Commit cbed5367285694954990d5903812bbd79bf27192

Authored by Dancovich
1 parent 6b429231
Exists in master

Escrita documentação atualizada de segurança

Showing 1 changed file with 501 additions and 123 deletions   Show diff stats
documentation/reference/pt-BR/security.xml
1 1 <?xml version='1.0' encoding="utf-8"?>
2 2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3   - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
  3 + "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]>
4 4 <chapter id="security">
5 5  
6 6 <title>Segurança</title>
... ... @@ -9,19 +9,21 @@
9 9 Neste capítulo será tratada uma questão de grande importância para a maioria das aplicações e motivo de infindáveis
10 10 discussões nas equipes de desenvolvimento: controle de acesso. Assim como tudo relacionado ao framework, a
11 11 implementação de segurança foi projetada de forma simples e flexível, independente de camada de apresentação ou
12   - tecnologia, te deixando livre para implementar sua própria solução ou utilizar as extensões prontas, como a que
13   - atualmente provemos baseada no Apache Shiro (<ulink url="http://shiro.apache.org" />).
  12 + tecnologia, te deixando livre para implementar sua própria solução ou utilizar as extensões existentes.
14 13 </para>
15 14 <para>
16   - Para utilizar o modelo de segurança proposto basta utilizar o Demoiselle, pois no núcleo do Framework estão as
  15 + Para utilizar o modelo de segurança proposto basta utilizar o Framework Demoiselle, pois no núcleo do framework estão as
17 16 interfaces e anotações que definem o comportamento básico da implementação.
18 17 </para>
19 18  
20 19 <section>
21 20 <title>Configurando</title>
  21 +
22 22 <para>
23   - Para um correto funcionamento do Demoiselle é necessário inserir os interceptadores de segurança no arquivo <filename>src/main/WEB-INF/beans.xml</filename>.
  23 + Para um correto funcionamento da segurança no Framework Demoiselle é necessário inserir os interceptadores de segurança no arquivo <filename>beans.xml</filename>, localizado
  24 + na pasta WEB-INF em projetos WEB ou na pasta META-INF em projetos SE ou EJB.
24 25 </para>
  26 +
25 27 <programlisting role="XML"><![CDATA[<beans xmlns="http://java.sun.com/xml/ns/javaee"
26 28 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
27 29 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
... ... @@ -31,208 +33,584 @@ xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee
31 33 <class>br.gov.frameworkdemoiselle.security.RequiredRoleInterceptor</class>
32 34 </interceptors>
33 35 </beans>]]></programlisting>
  36 +
  37 + <para>
  38 + Opcionalmente é possível configurar o comportamento do módulo de segurança definindo propriedades no arquivo <emphasis>demoiselle.properties</emphasis>
  39 + da sua aplicação.
  40 + </para>
  41 +
  42 + <table>
  43 + <title>Propriedades de segurança do Framework Demoiselle</title>
  44 + <tgroup cols="3">
  45 + <colspec align="left"/>
  46 + <colspec align="left"/>
  47 + <colspec align="right"/>
  48 +
  49 + <thead>
  50 + <row valign="top">
  51 + <entry><emphasis role="bold">Propriedade</emphasis></entry>
  52 + <entry><emphasis role="bold">Descrição</emphasis></entry>
  53 + <entry><emphasis role="bold">Valor padrão</emphasis></entry>
  54 + </row>
  55 + </thead>
  56 + <tbody>
  57 + <row valign="top">
  58 + <entry>frameworkdemoiselle.security.enabled</entry>
  59 + <entry>
  60 + <para>
  61 + Habilita ou desabilita o mecanismo de segurança
  62 + </para>
  63 + </entry>
  64 + <entry>true</entry>
  65 + </row>
  66 +
  67 + <row valign="top">
  68 + <entry>frameworkdemoiselle.security.authenticator.class</entry>
  69 + <entry>
  70 + <para>
  71 + Define a classe que implementa o mecanismo de autenticação.
  72 + (Detalhes na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>)
  73 + </para>
  74 + </entry>
  75 + <entry>
  76 + -
  77 + </entry>
  78 + </row>
  79 +
  80 + <row valign="top">
  81 + <entry>frameworkdemoiselle.security.authorizer.class</entry>
  82 + <entry>
  83 + <para>
  84 + Define a classe que implementa o mecanismo de autorização.
  85 + (Detalhes na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>)
  86 + </para>
  87 + </entry>
  88 + <entry>
  89 + -
  90 + </entry>
  91 + </row>
  92 + </tbody>
  93 + </tgroup>
  94 + </table>
  95 +
34 96 </section>
35 97  
36 98 <section>
37 99 <title>Autenticação</title>
38 100 <para>
39   - O mecanismo de autenticação busca verificar a identidade do usuário de um sistema. A forma mais conhecida, e comum,
40   - para executar essa verificação se dá por meio de um formulário de login, geralmente solicitando um nome de usuário e
  101 + O mecanismo de autenticação busca verificar a identidade do usuário de um sistema. A forma mais conhecida - e comum - para
  102 + executar essa verificação se dá por meio de um formulário de login, geralmente solicitando um nome de usuário e
41 103 sua respectiva senha. No entanto, outras formas como reconhecimento biométrico e autenticação por token, para citar
42   - apenas duas, têm ganhado um grande número de adeptos.
  104 + apenas duas, tem ganhado um grande número de adeptos.
43 105 </para>
44 106 <para>
45   - O Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua conveniência e necessidade.
46   - A peça chave para tornar isso possível é o contexto de segurança, representado pela interface SecurityContext. Nessa
  107 + O Framework Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua conveniência e necessidade.
  108 + A peça chave para tornar isso possível é o contexto de segurança, representado pela interface <code>SecurityContext</code>. Nessa
47 109 estão definidos os métodos responsáveis por gerenciar os mecanismos de autenticação como, por exemplo, executar
48 110 login/logout de usuários e verificar se os mesmos estão ou não autenticados.
49 111 </para>
50 112 <para>
51   - O contexto de segurança irá direcionar as requisições para a implementação definida pela aplicação. A autenticação será
52   - efetuada por uma classe que implemente a interface Authenticator, cujo método authenticate() é responsável por
53   - executar os passos necessários para validar a identidade de um usuário. Nesta mesma interface serão encontrados,
54   - ainda, os métodos unAuthenticate() e getUser(), responsáveis por, respectivamente, desautenticar e retornar o usuário
55   - autenticado.
56   - </para>
57   - <para>
58   - Para exemplificar, consideremos a autenticação baseada em nome de usuário e senha. O primeiro passo é criar um bean para
59   - armazenar essas informações:
  113 + Para utilizar o <code>SecurityContext</code>, basta injetá-lo em seu código. O método <code>login</code> ativa o mecanismo de autenticação
  114 + e o método <code>logout</code> remove as credenciais atualmente autenticadas do sistema. A classe <code>SecurityContext</code> possui
  115 + outros métodos que permitem verificar se há um usuário autenticado e acessar o objeto <emphasis>gerente</emphasis> (representado pela
  116 + classe <code>javax.security.Principal</code>), um objeto que contém dados adicionais sobre o usuário atualmente autenticado. Consulte
  117 + a documentação da classe <code>SecurityContext</code> para consultar as funcionalidades que ela oferece.
60 118 </para>
61   - <programlisting role="JAVA"><![CDATA[@SessionScoped
62   -public class Credential {
63   -
64   - private String login;
65   - private String senha;
66   - // ...
67   -}]]></programlisting>
68 119 <para>
69   - Feito isso, podemos implementar a classe na qual se deseja adicionar o mecanismo de segurança:
  120 + Um exemplo do uso do <code>SecurityContext</code> para autenticação segue abaixo:
70 121 </para>
71   - <programlisting role="JAVA"><![CDATA[public class ClasseExemplo {
72   -
73   - @Inject
74   - private Credential credential;
  122 + <programlisting role="JAVA"><![CDATA[public class ExemploAutenticacao {
75 123  
76 124 @Inject
77   - private SecurityContext context;
78   -
79   - public void metodo1() {
80   - credential.setLogin(“usuario1”);
81   - credential.setSenha(“123”);
82   - context.login();
83   - // codigo do metodo
84   - context.logout();
  125 + private SecurityContext securityContext;
  126 +
  127 + public void efetuarAutenticacao() {
  128 + /*
  129 + Obtém as credenciais do usuário, pode ser um login e senha ou um certificado digital. O mais
  130 + comum é exibir uma tela HTML contendo um formulário que solicita as informações.
  131 + */
  132 +
  133 + securityContext.login();
  134 +
  135 + //Executa código que requer autenticação
  136 +
  137 + securityContext.logout();
  138 +
85 139 }
86 140 }]]></programlisting>
87   - <para>
88   - Neste caso, a interface SecurityContext e o bean Credential estão sendo injetados na classe utilizando o CDI.
89   - Dentro do método, ao definir o usuário e a senha e invocar “context.login()”, a implementação de segurança definida irá
90   - tratar essa requisição de acordo com os critérios estabelecidos.
91   - </para>
92 141 </section>
93 142  
94 143 <section>
95 144 <title>Autorização</title>
96 145 <para>
97   - O mecanismo de autorização é responsável por garantir que apenas usuários autorizados tenham o acesso concedido a
98   - determinados recursos de um sistema. No modelo de segurança do Demoiselle 2, a autorização pode acontecer de duas
  146 + Em certos sistemas é necessário não apenas autenticar um usuário, mas também proteger funcionalidades individuais e separar
  147 + usuários em grupos que possuem diferentes autorizações de acesso. O mecanismo de autorização é responsável por garantir que apenas
  148 + usuários autorizados tenham o acesso concedido a determinados recursos de um sistema.
  149 + </para>
  150 +
  151 + <para>
  152 + No modelo de segurança do Framework Demoiselle, a autorização pode acontecer de duas
99 153 formas:
100 154 <itemizedlist>
101   - <listitem><para>Permissão por usuário, através da anotação @RequiredPermission</para></listitem>
  155 + <listitem><para>Permissão por funcionalidade, através da anotação @RequiredPermission</para></listitem>
102 156 <listitem><para>Permissão por papel, através da anotação @RequiredRole</para></listitem>
103 157 </itemizedlist>
104 158 </para>
105   - <para>
106   - Novamente a interface SecurityContext é a responsável pela interação entre as funcionalidades da aplicação e a implementação de
107   - 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
108   - usuário está associado a um papel.
109   - </para>
110   - <para>
111   - A anotação @RequiredPermission pode ser utilizada tanto em classes como em métodos e possui dois parâmetros opcionais:
112   - “operation” e “resource”. O primeiro define a operação para a qual se deseja permissão e o segundo define em qual
113   - recurso essa operação será realizada. Abaixo serão exemplificadas algumas formas de utilização:
114   - </para>
115   - <programlisting role="JAVA"><![CDATA[class ClasseExemplo {
  159 +
  160 +
  161 + <section>
  162 + <title>Protegendo o sistema com <emphasis>@RequiredPermission</emphasis></title>
  163 +
  164 + <para>
  165 + A anotação <code>@RequiredPermission</code> permite marcar uma classe ou método e informar que acesso a esse recurso requer
  166 + a permissão de executar uma <emphasis>operação</emphasis>. Operação nesse contexto é um nome definido pelo desenvolvedor
  167 + que representa uma funcionalidade do sistema. Por exemplo, determinada classe pode ter métodos responsávels por criar, editar,
  168 + listar e remover bookmarks, o desenvolvedor pode decidir agrupar esses métodos sobre a operação <emphasis>gerenciar bookmark</emphasis>.
  169 + </para>
  170 +
  171 + <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark {
116 172  
117   - @RequiredPermission
118   - public void requiredPermissionWithoutDeclaredResourceAndOperation() {
  173 + @RequiredPermission(resource = "bookmark" , operation = "gerenciar")
  174 + public void incluirBookmark(Bookmark bookmark) {
  175 + //Código do método
119 176 }
120 177  
121   - @RequiredPermission(resource = "contact", operation = "insert")
122   - public void requiredPermissionWithDeclaredResourceAndOperation() {
123   - }
  178 + @RequiredPermission(resource = "bookmark", operation = "gerenciar")
  179 + public List<Bookmark> listarBookmarks() {
  180 + //Código do método
  181 + }
  182 +
  183 + @RequiredPermission
  184 + public List<Bookmark> apagarBookmark(Long idBookmark) {
  185 + public List<Bookmark> listarBookmarks() {
  186 + }
124 187 }]]></programlisting>
  188 +
  189 + <tip>
  190 + Perceba que a anotação <code>@RequiredPermission</code> sobre o método <code>apagarBookmark</code> não contém parâmetros. Quando não
  191 + são passados parâmetros o valor padrão para o parâmetro <code>resource</code> é o nome da classe e o valor padrão para <code>operation</code>
  192 + é o nome do método.
  193 + </tip>
  194 +
  195 + <tip>
  196 + É possível anotar a classe inteira com <code>@RequiredPermission</code>, isso protegerá o acesso a todos os métodos dessa classe.
  197 +
  198 + <programlisting role="JAVA"><![CDATA[@RequiredPermission(resource="bookmark" , operation="gerenciar")
  199 +class GerenciadorBookmark {
  200 +
  201 + public void incluirBookmark(Bookmark bookmark) {
  202 + //Código do método
  203 + }
  204 +
  205 + public List<Bookmark> listarBookmarks() {
  206 + //Código do método
  207 + }
  208 +
  209 + public List<Bookmark> apagarBookmark(Long idBookmark) {
  210 + public List<Bookmark> listarBookmarks() {
  211 + }
  212 +}]]></programlisting>
  213 + </tip>
  214 + </section>
  215 +
  216 + <section>
  217 + <title>Protegendo o sistema com <emphasis>@RequiredRole</emphasis></title>
  218 +
  219 + <para>
  220 + Diferente de <code>@RequiredPermission</code>, a anotação <code>@RequiredRole</code> utiliza o conceito
  221 + de papéis - ou perfís - para proteger recursos. Uma classe ou método anotado com <code>@RequiredRole</code>
  222 + exigirá que o usuário autenticado possua o papel indicado para acessar o recurso.
  223 + </para>
  224 +
  225 + <para>
  226 + Voltando ao exemplo de nosso aplicativo de bookmarks, vamos supor que a função de listar os bookmarks existentes
  227 + pode ser acessada por qualquer usuário autenticado, mas apenas administradores podem criar um novo bookmark. A classe
  228 + responsável por tais funcionalidades pode ser criada da seguinte forma:
  229 + </para>
  230 +
  231 + <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark {
  232 +
  233 + @RequiredRole("administrador")
  234 + public void inserirBookmark(Bookmark bookmark) {
  235 + }
  236 +
  237 + @RequiredRole({"convidado" , "administrador"})
  238 + public List<Bookmark> listarBookmarks() {
  239 + }
  240 +
  241 +}]]></programlisting>
  242 +
  243 + <tip>
  244 + É possível informar mais de um papel para a anotação <code>@RequiredRole</code>, neste caso basta que o usuário
  245 + autenticado possua um dos papéis listados para ter acesso ao recurso.
  246 + </tip>
  247 +
  248 + <para>
  249 + Da mesma forma que a anotação <code>@RequiredPermission</code>, a anotação <code>@RequiredRole</code> pode ser usada
  250 + a nível de classe para proteger todos os métodos contidos nessa classe.
  251 + </para>
  252 + </section>
  253 +
  254 + <section>
  255 + <title>Protegendo porções do código</title>
  256 +
  257 + <para>
  258 + É 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
  259 + expressões condicionais, onde um trecho só deve ser executado caso o usuário possua a autorização necessária.
  260 + Para isso voltamos a usar a interface <code>SecurityContext</code>, pois ela contém métodos que são funcionalmente equivalentes
  261 + às anotações <code>@RequiredPermission</code> e <code>@RequiredRole</code>.
  262 + </para>
  263 +
  264 + <para>
  265 + Como um exemplo, vamos supor que ao remover um bookmark um email seja enviado ao administrador, mas se o próprio
  266 + administrador executou a operação não é necessário enviar o email.
  267 + </para>
  268 +
  269 + <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark {
  270 +
  271 + @Inject
  272 + private SecurityContext securityContext;
  273 +
  274 + public void removerBookmark(Long idBookmark) {
  275 +
  276 + //Código que remove o bookmark
  277 +
  278 + if ( ! securityContext.hasRole("administrador") ){
  279 + //Envia um email ao administrador
  280 + }
  281 +
  282 + }
  283 +
  284 +}]]></programlisting>
  285 +
  286 + </section>
  287 +
  288 + <section>
  289 + <title>Protegendo porções de páginas <code>Java Server Faces</code></title>
  290 +
  291 + <para>
  292 + As restrições de segurança podem ser utilizadas ainda em páginas web, com o auxílio de Expression Language. A interface
  293 + <code>SecurityContext</code> está automaticamente disponível para páginas <code>Java Server Faces</code> como um <emphasis>bean</emphasis>
  294 + de nome <code>securityContext</code>, bastando então acessar seus métodos a partir deste bean.
  295 + </para>
  296 +
  297 + <programlisting role="XHTML"><![CDATA[<p:commandButton value="#{messages['button.save']}" action="#{contactEditMB.insert}"
  298 + ajax="false" disabled="#{!securityContext.hasPermission('contact', 'insert')}" />]]></programlisting>
  299 +
  300 + <para>
  301 + Nesse caso, a habilitação de um botão está condicionada à existência de permissão para o usuário autenticado no momento
  302 + executar a operação “insert” no recurso “contact”.
  303 + </para>
  304 + </section>
  305 + </section>
  306 +
  307 + <section>
  308 + <title>Redirecionando automaticamente para um formulário de acesso</title>
  309 +
  310 + <para>
  311 + Se sua aplicação usa a extensão <emphasis>demoiselle-jsf</emphasis> ou se você utilizou o arquétipo <emphasis>demoiselle-jsf-jpa</emphasis>
  312 + 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
  313 + para essa página caso haja a tentativa de acessar um recurso protejido e nenhum usuário esteja autenticado no sistema.
  314 + </para>
  315 +
  316 + <tip>
  317 + <para>Para acrescentar a extensão <emphasis>demoiselle-jsf</emphasis> em um projeto Maven, adicione a dependência abaixo
  318 + no arquivo <emphasis>pom.xml</emphasis>.</para>
  319 +
  320 + <programlisting role="XML"><![CDATA[
  321 +<dependency>
  322 + <groupId>br.gov.frameworkdemoiselle</groupId>
  323 + <artifactId>demoiselle-jsf</artifactId>
  324 + <scope>compile</scope>
  325 +</dependency>]]></programlisting>
  326 +
  327 + <para>
  328 + O arquétipo <emphasis>demoiselle-jsf-jpa</emphasis> já contém essa extensão, se você criou seu projeto
  329 + baseado nesse arquétipo nada precisa ser feito.
  330 + </para>
  331 + </tip>
  332 +
125 333 <para>
126   - 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
127   - do método, respectivamente. Uma outra possibilidade seria utilizar a anotação @Name, tanto na classe como no método, de
128   - forma a possibilitar uma descrição mais amigável para o usuário.
  334 + Por padrão a página contendo o formulário de login deve se chamar <emphasis>login.jsp</emphasis> ou <emphasis>login.xhtml</emphasis>
  335 + (a depender de como sua aplicação esteja configurada para mapear páginas JSF). Para mudar esse padrão, é possível
  336 + editar o arquivo <emphasis>demoiselle.properties</emphasis> para configurar qual página deve ser utilizada.
129 337 </para>
  338 +
  339 + <table>
  340 + <title>Propriedades de segurança da extensão <emphasis>demoiselle-jsf</emphasis></title>
  341 + <tgroup cols="3">
  342 + <colspec align="left"/>
  343 + <colspec align="left"/>
  344 + <colspec align="right"/>
  345 +
  346 + <thead>
  347 + <row valign="top">
  348 + <entry><emphasis role="bold">Propriedade</emphasis></entry>
  349 + <entry><emphasis role="bold">Descrição</emphasis></entry>
  350 + <entry><emphasis role="bold">Valor padrão</emphasis></entry>
  351 + </row>
  352 + </thead>
  353 + <tbody>
  354 + <row valign="top">
  355 + <entry>frameworkdemoiselle.security.login.page</entry>
  356 + <entry>
  357 + <para>
  358 + Define a página de login da aplicação.
  359 + </para>
  360 + </entry>
  361 + <entry>"/login"</entry>
  362 + </row>
  363 + <row valign="top">
  364 + <entry>frameworkdemoiselle.security.redirect.after.login</entry>
  365 + <entry>
  366 + <para>
  367 + Define a tela para qual o usuário será redirecionado após o processo de <emphasis>login</emphasis> bem sucedido.
  368 + </para>
  369 + </entry>
  370 + <entry>"/index"</entry>
  371 + </row>
  372 + <row valign="top">
  373 + <entry>frameworkdemoiselle.security.redirect.after.logout</entry>
  374 + <entry>
  375 + <para>
  376 + Define a tela para qual o usuário será redirecionado após o processo de <emphasis>logout</emphasis> bem sucedido.
  377 + </para>
  378 + </entry>
  379 + <entry>"/login"</entry>
  380 + </row>
  381 + <row valign="top">
  382 + <entry>frameworkdemoiselle.security.redirect.enabled</entry>
  383 + <entry>
  384 + <para>
  385 + Habilita ou desabilita o redirecionamento automático para a página de login após uma tentativa
  386 + de acessar recurso protegido.
  387 + </para>
  388 + </entry>
  389 + <entry>true</entry>
  390 + </row>
  391 + </tbody>
  392 + </tgroup>
  393 + </table>
  394 +
  395 + </section>
  396 +
  397 + <section>
  398 + <title>Integrando o Framework Demoiselle com a especificação JAAS</title>
  399 +
130 400 <para>
131   - Assim como na autenticação, o contexto de segurança possui métodos destinados a delegar as requisições de autorização para
132   - a implementação de segurança. No caso da anotação @RequiredPermission, o método hasPermission(String resource, String
133   - operation) executa esta tarefa. Para tanto, deve existir uma classe que implemente a interface Authorizer, cujo
134   - método hasPermission(Object resource, String operation) verifica se o usuário logado possui permissão para executar
135   - uma determinada operação em um recurso específico.
  401 + Até agora vimos como criar código protegido em uma aplicação Demoiselle, mas nada foi dito sobre a tecnologia que implementa essa
  402 + proteção. A verdade é que o Framework Demoiselle dá ao desenvolvedor a liberdade de implementar a solução que mais se adequa ao sistema
  403 + desenvolvido, mas o framework também conta com suporte nativo à especificação JAAS (<emphasis>Java Authentication and
  404 + Authorization Service</emphasis>).
136 405 </para>
  406 +
137 407 <para>
138   - Ainda na interface Authorizer, pode-se notar a existência do método hasRole(String role), responsável por verificar se o
139   - usuário logado possui um papel específico. Este método é chamado pelo contexto de segurança, por meio do seu método
140   - hasRole(String role), para tratar as requisições que possuam a anotação @RequiredRole. Essa anotação possui um
141   - parâmetro obrigatório, no qual podem ser definidos uma simples role ou um array delas.
  408 + O suporte a JAAS é fornecido para aplicações WEB e está implementado na extensão
  409 + <emphasis>demoiselle-servlet</emphasis>, então é necessário declarar a dependência a essa extensão em sua aplicação.
142 410 </para>
143   - <programlisting role="JAVA"><![CDATA[class ClasseExemplo {
  411 +
  412 + <tip>
  413 + <para>Para acrescentar a extensão <emphasis>demoiselle-servlet</emphasis> em um projeto Maven, adicione a dependência abaixo
  414 + no arquivo <emphasis>pom.xml</emphasis>.</para>
  415 +
  416 + <programlisting role="XML"><![CDATA[
  417 +<dependency>
  418 + <groupId>br.gov.frameworkdemoiselle</groupId>
  419 + <artifactId>demoiselle-servlet</artifactId>
  420 + <scope>compile</scope>
  421 +</dependency>]]></programlisting>
  422 + </tip>
  423 +
  424 + <tip>
  425 + <para>
  426 + O arquétipo <emphasis>demoiselle-jsf-jpa</emphasis> já conta com a dependência à extensão <emphasis>demoiselle-jsf</emphasis>, que
  427 + por sua vez depende da extensão <emphasis>demoiselle-servlet</emphasis>. Se sua aplicação é baseada no arquétipo
  428 + <emphasis>demoiselle-jsf-jpa</emphasis> você já possui a extensão <emphasis>demoiselle-servlet</emphasis>.
  429 + </para>
  430 + </tip>
  431 +
  432 + <para>
  433 + Uma vez que sua aplicação contenha a extensão <emphasis>demoiselle-servlet</emphasis>, tudo que você precisa fazer é configurar
  434 + 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
  435 + aplicação utilizado e foge ao escopo deste documento.
  436 + </para>
  437 +
  438 + <para>
  439 + Para autenticar um usuário presente no servidor de aplicação através do JAAS, a extensão <emphasis>demoiselle-servlet</emphasis>
  440 + oferece a classe <code>Credentials</code>, que deve ser injetada em seu código. O código abaixo mostra como realizar a autenticação a partir de um servlet.
  441 + </para>
  442 +
  443 + <programlisting role="JAVA"><![CDATA[class LoginServlet extends HttpServlet {
  444 +
  445 + @Inject
  446 + private SecurityContext securityContext;
  447 +
  448 + @Inject
  449 + private Credentials credentials;
144 450  
145   - @RequiredRole("simpleRoleName")
146   - public void requiredRoleWithSingleRole() {
  451 + public void doPost(HttpServletRequest req, HttpServletResponse resp) {
  452 +
  453 + credentials.setUsername( req.getParameter("username") );
  454 + credentials.setPassword( req.getParameter("password") );
  455 +
  456 + securityContext.login();
  457 +
147 458 }
148 459  
149   - @RequiredRole({ "firstRole", "secondRole", "thirdRole", "fourthRole", "fifthRole" })
150   - public void requiredRoleWithArrayOfRoles() {
151   - }
152 460 }]]></programlisting>
  461 +
153 462 <para>
154   - As restrições de segurança pode ser utilizadas, ainda, em páginas web, com o auxílio de Expression Language, como no
155   - exemplo abaixo:
156   - </para>
157   - <programlisting role="XHTML"><![CDATA[<p:commandButton value="#{messages['button.save']}" action="#{contactEditMB.insert}"
158   - rendered="#{!contactEditMB.updateMode}" ajax="false"
159   - disabled="#{!securityContext.hasPermission('contact', 'insert')}" />]]></programlisting>
160   - <para>
161   - Nesse caso, a habilitação de um botão está condicionada à existência de permissão para o usuário autenticado no momento
162   - executar a operação “insert” no recurso “contact”.
  463 + Uma vez autenticado o usuário, a anotação <code>@RequiredRole</code> passará a verificar se o usuário presente no JAAS possui o papel informado.
163 464 </para>
  465 +
  466 + <caution>
  467 + <para>
  468 + 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
  469 + da especificação JAAS o uso da anotação <code>@RequiredPermission</code> fica vetado. Utilizar essa anotação em um sistema que utilize
  470 + JAAS para autorização causará uma exceção quando o recurso for acessado.
  471 + </para>
  472 + </caution>
  473 +
  474 + <tip>
  475 + <para>
  476 + É possível utilizar o JAAS para autenticar e autorizar papéis de usuários mas criar sua própria implementação para
  477 + implementar a autorização de permissões. Para isso crie uma classe que herde a classe
  478 + <code>br.gov.frameworkdemoiselle.security.ServletAuthorizer</code> e sobrescreva o método <code>hasPermission(String resource, String operation)</code>
  479 + para implementar seu próprio mecanismo. Feito isso, basta definir sua classe no arquivo <emphasis>demoiselle.properties</emphasis> usando
  480 + a propriedade <code>frameworkdemoiselle.security.authorizer.class</code>.
  481 + </para>
  482 +
  483 + <para>
  484 + Mais detalhes sobre como criar sua própria implementação ou extender uma implementação existente podem
  485 + ser vistos na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>.
  486 + </para>
  487 + </tip>
  488 +
164 489 </section>
165 490  
166   - <section>
  491 + <section id="criando_implementacao_seguranca">
167 492 <title>Criando sua implementação</title>
  493 +
168 494 <para>
169   - Após toda essa explicação, fica a dúvida: como implementar um esquema de segurança sem utilizar a extensão existente?
  495 + Para os mecanismos de autenticação não cobertos pelo Framework Demoiselle, é possível criar sua própria implementação e integra-la
  496 + ao framework. Também é possível extender uma implementação existente e acrescentar funcionalidades inexistentes.
170 497 </para>
  498 +
171 499 <para>
172   - O primeiro passo é criar classes para implementar as interfaces Authenticator e Authorizer. O <literal>Demoiselle</literal> detecta automaticamente
173   - a implementação, e torna essa classe a implementação padrão dessas interfaces:<!-- Essas classes devem ser
174   - anotadas com @Alternative para que o CDI saiba que se trata de uma estratégia: -->
  500 + O ponto de extensão para o módulo de segurança são as interfaces <code>Authenticator</code> e <code>Authorizer</code>. Para criar
  501 + um novo mecanismo de autenticação e autorização, é necessário apenas implementar essas duas interfaces em sua aplicação. Segue
  502 + abaixo um exemplo de implementação.
175 503 </para>
  504 +
176 505 <programlisting role="JAVA"><![CDATA[public class MeuAuthenticator implements Authenticator {
177 506  
178 507 @Override
179 508 public boolean authenticate() {
180   - // Escreva aqui seu codigo de autenticacao
  509 + // Escreva aqui seu codigo de autenticacao e retorne true caso o processo seja um sucesso
181 510 return true;
182 511 }
183 512  
184 513 @Override
185   - public User getUser() {
186   - // Escreva aqui seu codigo para retornar o usuario logado
187   - return null;
  514 + public Principal getUser() {
  515 + // Obtenha dados sobre o usuário autenticado e retorne na forma da interface javax.security.Principal
  516 + return new Principal(){
  517 + public String getName(){
  518 + return "usuario";
  519 + }
  520 + };
188 521 }
189 522  
190 523 @Override
191 524 public void unAuthenticate() {
192   - // Escreva aqui seu codigo de desautenticacao
  525 + // Remova qualquer informação de autenticação do usuário, após o retorno deste método o usuário
  526 + // deve ser considerado não autenticado.
193 527 }
194 528 }]]></programlisting>
195 529 <programlisting role="JAVA"><![CDATA[public class MeuAuthorizer implements Authorizer {
196 530  
197 531 @Override
198 532 public boolean hasRole(String role) {
199   - // Escreva aqui seu codigo de verificacao do papel
  533 + // Verifique se o usuário autenticado tem o papel informado, retorne true em caso positivo
200 534 return false;
201 535 }
202 536  
203 537 @Override
204 538 public boolean hasPermission(Object resource, String operation) {
205   - // Escreva aqui seu codigo de verificacao de permissao
  539 + // Verifique se o usuário autenticado tem a permissão adequada, retorne true em caso positivo
206 540 return false;
207 541 }
208 542 }]]></programlisting>
209   - <!-- <para>
210   - Feito isso deve-se definir no arquivo <filename>demoiselle.properties</filename>, as classes criadas:
211   - </para>
212   - <programlisting>
213   - frameworkdemoiselle.security.authenticator.class=projeto.MeuAuthenticator
214   - frameworkdemoiselle.security.authorizer.class=projeto.MeuAuthorizer
215   - </programlisting> -->
  543 +
216 544 <para>
217 545 Pronto! Sua aplicação já possui uma implementação de segurança definida.
218 546 </para>
219   -
  547 +
  548 + <tip>
  549 + <para>
  550 + Você nunca deve chamar diretamente em sua aplicação as implementações das interfaces <code>Authenticator</code>
  551 + e <code>Authorizer</code>, o Framework Demoiselle vai automaticamente chamar os métodos implementados
  552 + quando for necessário.
  553 + </para>
  554 + </tip>
  555 +
220 556 <para>
221   - Caso sua aplicação detecte o uso das anotações @RequiredRole e @RequiredPermission mas nenhuma classe
222   - implemente essas interfaces, no momento em que os recursos anotados forem acessados, o framework lançará uma exceção informando que a
223   - aplicação precisa implementá-las.
  557 + Em um sistema que use as anotações <code>@RequiredRole</code> ou <code>@RequiredPermission</code>, deve haver pelo menos uma implementação
  558 + dessas duas interfaces. Ao processar essas anotações, o Framework Demoiselle vai buscar uma implementação para essas interfaces
  559 + e disparar uma exceção caso não encontre uma implementação adequada.
224 560 </para>
  561 +
225 562 <para>
226   - Se você tem mais de uma implementação de <literal>Authenticator</literal> e/ou <literal>Authorizer</literal> (o que pode acontecer, por exemplo, quando
227   - se necessite de uma implementação na aplicação principal, e outra para os testes), deverá definir no arquivo <filename>demoiselle.properties</filename>
228   - qual classe será a padrão:
229   - <programlisting>frameworkdemoiselle.security.authenticator.class=projeto.MeuAuthenticatorPadrao
230   -frameworkdemoiselle.security.authorizer.class=projeto.MeuAuthorizerPadrao</programlisting>
  563 + Se existe mais de uma implementação de <code>Authenticator</code> e/ou <code>Authorizer</code> (o que pode acontecer, por exemplo, quando
  564 + seja necessário uma implementação na aplicação principal e outra para os testes), é possível definir no arquivo <filename>demoiselle.properties</filename>
  565 + a classe que deve ser usada por padrão:
231 566 </para>
  567 +
  568 + <informaltable>
  569 + <tgroup cols="3">
  570 + <colspec align="left"/>
  571 + <colspec align="left"/>
  572 + <colspec align="right"/>
  573 +
  574 + <thead>
  575 + <row valign="top">
  576 + <entry><emphasis role="bold">Propriedade</emphasis></entry>
  577 + <entry><emphasis role="bold">Descrição</emphasis></entry>
  578 + <entry><emphasis role="bold">Valor padrão</emphasis></entry>
  579 + </row>
  580 + </thead>
  581 + <tbody>
  582 + <row valign="top">
  583 + <entry>frameworkdemoiselle.security.authenticator.class</entry>
  584 + <entry>
  585 + <para>
  586 + Define a classe concreta utilizada como implementação da interface Authenticator
  587 + </para>
  588 + </entry>
  589 + <entry>
  590 + <emphasis>
  591 + nenhum, se houver apenas uma implementação o framework a detectará
  592 + automaticamente sem necessidade de definir essa propriedade
  593 + </emphasis>
  594 + </entry>
  595 + </row>
  596 +
  597 + <row valign="top">
  598 + <entry>frameworkdemoiselle.security.authorizer.class</entry>
  599 + <entry>
  600 + <para>
  601 + Define a classe concreta utilizada como implementação da interface Authorizer
  602 + </para>
  603 + </entry>
  604 + <entry>
  605 + <emphasis>
  606 + nenhum, se houver apenas uma implementação o framework a detectará
  607 + automaticamente sem necessidade de definir essa propriedade
  608 + </emphasis>
  609 + </entry>
  610 + </row>
  611 + </tbody>
  612 + </tgroup>
  613 + </informaltable>
232 614 </section>
233   - <caution> <para>O Demoiselle também oferece o componente
234   - <ulink url="http://demoiselle.sourceforge.net/docs/demoiselle-guide-components/1.2.0/html/authorization-master.html">demoiselle-authorization</ulink>
235   - 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
236   - como dependência, por isso sempre confira o arquivo pom.xml e se for o caso retire essa dependência.</para> </caution>
237   -
  615 +
238 616 </chapter>
239 617 \ No newline at end of file
... ...