Commit aa9eeb45fad212e64f4d64caa9c6d5366988a8ed
1 parent
6f0de507
Exists in
master
FWK-208: Tratamento de uso de sessão com REST
Task-Url: https://demoiselle.atlassian.net/browse/FWK-208
Showing
10 changed files
with
224 additions
and
131 deletions
Show diff stats
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/RESTConfig.java
0 → 100644
... | ... | @@ -0,0 +1,55 @@ |
1 | +/* | |
2 | + * Demoiselle Framework | |
3 | + * Copyright (C) 2010 SERPRO | |
4 | + * ---------------------------------------------------------------------------- | |
5 | + * This file is part of Demoiselle Framework. | |
6 | + * | |
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | |
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | |
9 | + * as published by the Free Software Foundation. | |
10 | + * | |
11 | + * This program is distributed in the hope that it will be useful, | |
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | + * GNU General Public License for more details. | |
15 | + * | |
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | |
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | |
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | |
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | + * ---------------------------------------------------------------------------- | |
21 | + * Este arquivo é parte do Framework Demoiselle. | |
22 | + * | |
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | |
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | |
25 | + * do Software Livre (FSF). | |
26 | + * | |
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | |
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | |
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | |
30 | + * para maiores detalhes. | |
31 | + * | |
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | |
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | |
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | |
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | |
36 | + */ | |
37 | +package br.gov.frameworkdemoiselle.internal.configuration; | |
38 | + | |
39 | +import java.io.Serializable; | |
40 | + | |
41 | +import br.gov.frameworkdemoiselle.annotation.Name; | |
42 | +import br.gov.frameworkdemoiselle.configuration.Configuration; | |
43 | + | |
44 | +@Configuration(prefix = "frameworkdemoiselle") | |
45 | +public class RESTConfig implements Serializable { | |
46 | + | |
47 | + private static final long serialVersionUID = 1L; | |
48 | + | |
49 | + @Name("session.allowed") | |
50 | + private boolean sessionAllowed = false; | |
51 | + | |
52 | + public boolean isSessionAllowed() { | |
53 | + return sessionAllowed; | |
54 | + } | |
55 | +} | ... | ... |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/RESTSecurityConfig.java
0 → 100644
... | ... | @@ -0,0 +1,62 @@ |
1 | +/* | |
2 | + * Demoiselle Framework | |
3 | + * Copyright (C) 2010 SERPRO | |
4 | + * ---------------------------------------------------------------------------- | |
5 | + * This file is part of Demoiselle Framework. | |
6 | + * | |
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | |
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | |
9 | + * as published by the Free Software Foundation. | |
10 | + * | |
11 | + * This program is distributed in the hope that it will be useful, | |
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | + * GNU General Public License for more details. | |
15 | + * | |
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | |
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | |
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | |
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | + * ---------------------------------------------------------------------------- | |
21 | + * Este arquivo é parte do Framework Demoiselle. | |
22 | + * | |
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | |
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | |
25 | + * do Software Livre (FSF). | |
26 | + * | |
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | |
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | |
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | |
30 | + * para maiores detalhes. | |
31 | + * | |
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | |
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | |
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | |
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | |
36 | + */ | |
37 | +package br.gov.frameworkdemoiselle.internal.configuration; | |
38 | + | |
39 | +import java.io.Serializable; | |
40 | + | |
41 | +import br.gov.frameworkdemoiselle.annotation.Name; | |
42 | +import br.gov.frameworkdemoiselle.configuration.Configuration; | |
43 | + | |
44 | +@Configuration(prefix = "frameworkdemoiselle.security") | |
45 | +public class RESTSecurityConfig implements Serializable { | |
46 | + | |
47 | + private static final long serialVersionUID = 1L; | |
48 | + | |
49 | + @Name("basic.filter.active") | |
50 | + private boolean basicFilterActive = true; | |
51 | + | |
52 | + @Name("token.filter.active") | |
53 | + private boolean tokenFilterActive = true; | |
54 | + | |
55 | + public boolean isBasicFilterActive() { | |
56 | + return basicFilterActive; | |
57 | + } | |
58 | + | |
59 | + public boolean isTokenFilterActive() { | |
60 | + return tokenFilterActive; | |
61 | + } | |
62 | +} | ... | ... |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/SessionNotAllowedListener.java
0 → 100644
... | ... | @@ -0,0 +1,98 @@ |
1 | +package br.gov.frameworkdemoiselle.internal.implementation; | |
2 | + | |
3 | +import static javax.servlet.SessionTrackingMode.URL; | |
4 | + | |
5 | +import java.util.HashSet; | |
6 | +import java.util.Set; | |
7 | +import java.util.logging.Logger; | |
8 | + | |
9 | +import javax.enterprise.event.Observes; | |
10 | +import javax.servlet.ServletContextEvent; | |
11 | +import javax.servlet.ServletContextListener; | |
12 | +import javax.servlet.SessionTrackingMode; | |
13 | +import javax.servlet.annotation.WebListener; | |
14 | +import javax.servlet.http.HttpServletRequest; | |
15 | +import javax.servlet.http.HttpSession; | |
16 | +import javax.servlet.http.HttpSessionEvent; | |
17 | +import javax.servlet.http.HttpSessionListener; | |
18 | + | |
19 | +import br.gov.frameworkdemoiselle.internal.configuration.RESTConfig; | |
20 | +import br.gov.frameworkdemoiselle.transaction.BeforeTransactionComplete; | |
21 | +import br.gov.frameworkdemoiselle.util.Beans; | |
22 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | |
23 | +import br.gov.frameworkdemoiselle.util.ResourceBundle; | |
24 | + | |
25 | +@WebListener | |
26 | +public class SessionNotAllowedListener implements ServletContextListener, HttpSessionListener { | |
27 | + | |
28 | + private static final String ATTR_NAME = "br.gov.frameworkdemoiselle.SESSION_NOT_ALLOWED"; | |
29 | + | |
30 | + private static final String ATTR_VALUE = "created"; | |
31 | + | |
32 | + private transient RESTConfig config; | |
33 | + | |
34 | + private transient ResourceBundle bundle; | |
35 | + | |
36 | + private transient Logger logger; | |
37 | + | |
38 | + public void contextInitialized(ServletContextEvent event) { | |
39 | + if (!getConfig().isSessionAllowed()) { | |
40 | + Set<SessionTrackingMode> modes = new HashSet<SessionTrackingMode>(); | |
41 | + modes.add(URL); | |
42 | + event.getServletContext().setSessionTrackingModes(modes); | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + public void contextDestroyed(ServletContextEvent event) { | |
47 | + } | |
48 | + | |
49 | + @Override | |
50 | + public void sessionCreated(HttpSessionEvent event) { | |
51 | + if (!getConfig().isSessionAllowed()) { | |
52 | + Beans.getReference(HttpServletRequest.class).setAttribute(ATTR_NAME, ATTR_VALUE); | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public void sessionDestroyed(HttpSessionEvent event) { | |
58 | + } | |
59 | + | |
60 | + public void beforeTransactionComplete(@Observes BeforeTransactionComplete event, HttpServletRequest request) { | |
61 | + if (!getConfig().isSessionAllowed() && ATTR_VALUE.equals(request.getAttribute(ATTR_NAME))) { | |
62 | + invalidateSesstion(request); | |
63 | + throw new IllegalStateException(getBundle().getString("session-not-allowed")); | |
64 | + } | |
65 | + } | |
66 | + | |
67 | + private void invalidateSesstion(HttpServletRequest request) { | |
68 | + HttpSession session = request.getSession(false); | |
69 | + | |
70 | + if (session != null) { | |
71 | + session.invalidate(); | |
72 | + } | |
73 | + } | |
74 | + | |
75 | + private RESTConfig getConfig() { | |
76 | + if (config == null) { | |
77 | + config = Beans.getReference(RESTConfig.class); | |
78 | + } | |
79 | + | |
80 | + return config; | |
81 | + } | |
82 | + | |
83 | + private ResourceBundle getBundle() { | |
84 | + if (bundle == null) { | |
85 | + bundle = Beans.getReference(ResourceBundle.class, new NameQualifier("demoiselle-rest-bundle")); | |
86 | + } | |
87 | + | |
88 | + return bundle; | |
89 | + } | |
90 | + | |
91 | + private Logger getLogger() { | |
92 | + if (logger == null) { | |
93 | + logger = Beans.getReference(Logger.class, new NameQualifier("br.gov.frameworkdemoiselle.util")); | |
94 | + } | |
95 | + | |
96 | + return logger; | |
97 | + } | |
98 | +} | ... | ... |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/SessionNotPermittedListener.java
... | ... | @@ -1,60 +0,0 @@ |
1 | -package br.gov.frameworkdemoiselle.internal.implementation; | |
2 | - | |
3 | -import static javax.servlet.SessionTrackingMode.URL; | |
4 | - | |
5 | -import java.util.HashSet; | |
6 | -import java.util.Set; | |
7 | - | |
8 | -import javax.enterprise.event.Observes; | |
9 | -import javax.servlet.ServletContextEvent; | |
10 | -import javax.servlet.ServletContextListener; | |
11 | -import javax.servlet.SessionTrackingMode; | |
12 | -import javax.servlet.annotation.WebListener; | |
13 | -import javax.servlet.http.HttpServletRequest; | |
14 | -import javax.servlet.http.HttpSession; | |
15 | -import javax.servlet.http.HttpSessionEvent; | |
16 | -import javax.servlet.http.HttpSessionListener; | |
17 | - | |
18 | -import br.gov.frameworkdemoiselle.transaction.BeforeTransactionComplete; | |
19 | -import br.gov.frameworkdemoiselle.util.Beans; | |
20 | - | |
21 | -@WebListener | |
22 | -public class SessionNotPermittedListener implements ServletContextListener, HttpSessionListener { | |
23 | - | |
24 | - private static final String ATTR_NAME = "br.gov.frameworkdemoiselle.SESSION_NOT_PERMITTED"; | |
25 | - | |
26 | - private static final String ATTR_VALUE = "created"; | |
27 | - | |
28 | - public void contextInitialized(ServletContextEvent event) { | |
29 | - Set<SessionTrackingMode> modes = new HashSet<SessionTrackingMode>(); | |
30 | - modes.add(URL); | |
31 | - event.getServletContext().setSessionTrackingModes(modes); | |
32 | - } | |
33 | - | |
34 | - public void contextDestroyed(ServletContextEvent event) { | |
35 | - } | |
36 | - | |
37 | - @Override | |
38 | - public void sessionCreated(HttpSessionEvent event) { | |
39 | - Beans.getReference(HttpServletRequest.class).setAttribute(ATTR_NAME, ATTR_VALUE); | |
40 | - } | |
41 | - | |
42 | - @Override | |
43 | - public void sessionDestroyed(HttpSessionEvent event) { | |
44 | - } | |
45 | - | |
46 | - public void beforeTransactionComplete(@Observes BeforeTransactionComplete event, HttpServletRequest request) { | |
47 | - if (ATTR_VALUE.equals(request.getAttribute(ATTR_NAME))) { | |
48 | - invalidateSesstion(request); | |
49 | - throw new IllegalStateException("Session use is not permitted."); | |
50 | - } | |
51 | - } | |
52 | - | |
53 | - private void invalidateSesstion(HttpServletRequest request) { | |
54 | - HttpSession session = request.getSession(false); | |
55 | - | |
56 | - if (session != null) { | |
57 | - session.invalidate(); | |
58 | - } | |
59 | - } | |
60 | -} |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/security/BasicAuthFilter.java
... | ... | @@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletResponse; |
41 | 41 | |
42 | 42 | import org.apache.commons.codec.binary.Base64; |
43 | 43 | |
44 | +import br.gov.frameworkdemoiselle.internal.configuration.RESTSecurityConfig; | |
44 | 45 | import br.gov.frameworkdemoiselle.util.Beans; |
45 | 46 | |
46 | 47 | public class BasicAuthFilter extends AbstractHTTPAuthorizationFilter { | ... | ... |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/security/RESTSecurityConfig.java
... | ... | @@ -1,62 +0,0 @@ |
1 | -/* | |
2 | - * Demoiselle Framework | |
3 | - * Copyright (C) 2010 SERPRO | |
4 | - * ---------------------------------------------------------------------------- | |
5 | - * This file is part of Demoiselle Framework. | |
6 | - * | |
7 | - * Demoiselle Framework is free software; you can redistribute it and/or | |
8 | - * modify it under the terms of the GNU Lesser General Public License version 3 | |
9 | - * as published by the Free Software Foundation. | |
10 | - * | |
11 | - * This program is distributed in the hope that it will be useful, | |
12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | - * GNU General Public License for more details. | |
15 | - * | |
16 | - * You should have received a copy of the GNU Lesser General Public License version 3 | |
17 | - * along with this program; if not, see <http://www.gnu.org/licenses/> | |
18 | - * or write to the Free Software Foundation, Inc., 51 Franklin Street, | |
19 | - * Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | - * ---------------------------------------------------------------------------- | |
21 | - * Este arquivo é parte do Framework Demoiselle. | |
22 | - * | |
23 | - * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | |
24 | - * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | |
25 | - * do Software Livre (FSF). | |
26 | - * | |
27 | - * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | |
28 | - * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | |
29 | - * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | |
30 | - * para maiores detalhes. | |
31 | - * | |
32 | - * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | |
33 | - * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | |
34 | - * ou escreva para a Fundação do Software Livre (FSF) Inc., | |
35 | - * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | |
36 | - */ | |
37 | -package br.gov.frameworkdemoiselle.security; | |
38 | - | |
39 | -import java.io.Serializable; | |
40 | - | |
41 | -import br.gov.frameworkdemoiselle.annotation.Name; | |
42 | -import br.gov.frameworkdemoiselle.configuration.Configuration; | |
43 | - | |
44 | -@Configuration(prefix = "frameworkdemoiselle.security") | |
45 | -public class RESTSecurityConfig implements Serializable { | |
46 | - | |
47 | - private static final long serialVersionUID = 1L; | |
48 | - | |
49 | - @Name("basic.filter.active") | |
50 | - private boolean basicFilterActive = true; | |
51 | - | |
52 | - @Name("token.filter.active") | |
53 | - private boolean tokenFilterActive = true; | |
54 | - | |
55 | - public boolean isBasicFilterActive() { | |
56 | - return basicFilterActive; | |
57 | - } | |
58 | - | |
59 | - public boolean isTokenFilterActive() { | |
60 | - return tokenFilterActive; | |
61 | - } | |
62 | -} |
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/security/TokenAuthFilter.java
... | ... | @@ -43,6 +43,7 @@ import javax.servlet.ServletException; |
43 | 43 | import javax.servlet.http.HttpServletRequest; |
44 | 44 | import javax.servlet.http.HttpServletResponse; |
45 | 45 | |
46 | +import br.gov.frameworkdemoiselle.internal.configuration.RESTSecurityConfig; | |
46 | 47 | import br.gov.frameworkdemoiselle.util.Beans; |
47 | 48 | |
48 | 49 | public class TokenAuthFilter extends AbstractHTTPAuthorizationFilter { | ... | ... |
impl/extension/rest/src/main/resources/demoiselle-rest-bundle.properties
... | ... | @@ -34,5 +34,6 @@ |
34 | 34 | # 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. |
35 | 35 | |
36 | 36 | internal-server-error=Erro interno do servidor |
37 | +session-not-allowed=O uso de sess\u00F5es n\u00E3o \u00E9 aconselh\u00E1vel em aplia\u00E7\u00F5es REST, mas se mesmo assim voc\u00EA desejar usar defina "frameworkdemoiselle.session.allowed\=true" no demoiselle.properties da aplica\u00E7\u00E3o | |
37 | 38 | mapping-violations=Mapeando viola\u00E7\u00F5es com o status HTTP {0} |
38 | 39 | authentication-failed=Falha na autentica\u00E7\u00E3o | ... | ... |
impl/extension/rest/src/test/java/security/authentication/basic/BasicAuthenticationFilterTest.java
... | ... | @@ -5,12 +5,10 @@ import static org.apache.http.HttpStatus.SC_OK; |
5 | 5 | import static org.apache.http.HttpStatus.SC_UNAUTHORIZED; |
6 | 6 | import static org.junit.Assert.assertEquals; |
7 | 7 | |
8 | -import java.io.IOException; | |
9 | 8 | import java.net.URL; |
10 | 9 | |
11 | 10 | import org.apache.commons.codec.binary.Base64; |
12 | 11 | import org.apache.http.HttpResponse; |
13 | -import org.apache.http.client.ClientProtocolException; | |
14 | 12 | import org.apache.http.client.methods.HttpGet; |
15 | 13 | import org.apache.http.client.methods.HttpPost; |
16 | 14 | import org.apache.http.impl.client.CloseableHttpClient; |
... | ... | @@ -39,7 +37,7 @@ public class BasicAuthenticationFilterTest { |
39 | 37 | } |
40 | 38 | |
41 | 39 | @Test |
42 | - public void loginSucessfull() throws ClientProtocolException, IOException { | |
40 | + public void loginSucessfull() throws Exception { | |
43 | 41 | CloseableHttpClient client = HttpClientBuilder.create().build(); |
44 | 42 | HttpGet get; |
45 | 43 | HttpResponse response; |
... | ... | @@ -61,15 +59,14 @@ public class BasicAuthenticationFilterTest { |
61 | 59 | } |
62 | 60 | |
63 | 61 | @Test |
64 | - public void loginFailed() throws ClientProtocolException, IOException { | |
62 | + public void loginFailed() throws Exception { | |
65 | 63 | String username = "invalid"; |
66 | 64 | String password = "invalid"; |
67 | - | |
68 | - | |
65 | + | |
69 | 66 | HttpPost x = new HttpPost(); |
70 | 67 | x.setEntity(null); |
71 | - | |
72 | - //HttpEntity entity | |
68 | + | |
69 | + // HttpEntity entity | |
73 | 70 | |
74 | 71 | HttpGet get = new HttpGet(deploymentUrl + "/helper"); |
75 | 72 | byte[] encoded = Base64.encodeBase64((username + ":" + password).getBytes()); | ... | ... |
impl/extension/rest/src/test/java/test/Tests.java
... | ... | @@ -51,6 +51,7 @@ import br.gov.frameworkdemoiselle.InternalServerErrorException; |
51 | 51 | import br.gov.frameworkdemoiselle.NotFoundException; |
52 | 52 | import br.gov.frameworkdemoiselle.ServiceUnavailableException; |
53 | 53 | import br.gov.frameworkdemoiselle.UnprocessableEntityException; |
54 | +import br.gov.frameworkdemoiselle.internal.configuration.RESTSecurityConfig; | |
54 | 55 | import br.gov.frameworkdemoiselle.internal.implementation.AuthenticationExceptionMapper; |
55 | 56 | import br.gov.frameworkdemoiselle.internal.implementation.AuthorizationExceptionMapper; |
56 | 57 | import br.gov.frameworkdemoiselle.internal.implementation.ConstraintViolationExceptionMapper; |
... | ... | @@ -59,7 +60,6 @@ import br.gov.frameworkdemoiselle.internal.implementation.HttpViolationException |
59 | 60 | import br.gov.frameworkdemoiselle.internal.implementation.IllegalArgumentExceptionMapper; |
60 | 61 | import br.gov.frameworkdemoiselle.security.AbstractHTTPAuthorizationFilter; |
61 | 62 | import br.gov.frameworkdemoiselle.security.BasicAuthFilter; |
62 | -import br.gov.frameworkdemoiselle.security.RESTSecurityConfig; | |
63 | 63 | import br.gov.frameworkdemoiselle.security.Token; |
64 | 64 | //import br.gov.frameworkdemoiselle.util.BasicAuthFilter; |
65 | 65 | import br.gov.frameworkdemoiselle.security.TokenAuthFilter; | ... | ... |