Commit 986dccd716b77e3ab1e6dccec4c1b24ac670a8da
1 parent
6e126b79
Segurança e ajustes nos pacotes
Showing
16 changed files
with
301 additions
and
129 deletions
Show diff stats
demoiselle-parent/pom.xml
... | ... | @@ -179,6 +179,18 @@ |
179 | 179 | <artifactId>demoiselle-security</artifactId> |
180 | 180 | <version>${project.version}</version> |
181 | 181 | </dependency> |
182 | + | |
183 | + <dependency> | |
184 | + <groupId>org.demoiselle.jee</groupId> | |
185 | + <artifactId>demoiselle-rest</artifactId> | |
186 | + <version>${project.version}</version> | |
187 | + </dependency> | |
188 | + | |
189 | + <dependency> | |
190 | + <groupId>org.demoiselle.jee</groupId> | |
191 | + <artifactId>demoiselle-persistence-jpa</artifactId> | |
192 | + <version>${project.version}</version> | |
193 | + </dependency> | |
182 | 194 | |
183 | 195 | </dependencies> |
184 | 196 | ... | ... |
demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/DemoiselleRESTException.java
... | ... | @@ -12,30 +12,30 @@ import org.demoiselle.jee.core.exception.DemoiselleException; |
12 | 12 | |
13 | 13 | public class DemoiselleRESTException extends DemoiselleException { |
14 | 14 | |
15 | - private static final long serialVersionUID = 519965615171844237L; | |
15 | + private static final long serialVersionUID = 519965615171844237L; | |
16 | 16 | |
17 | - private HashMap<String, String> messages = new HashMap<String, String>(); | |
17 | + private HashMap<String, String> messages = new HashMap<String, String>(); | |
18 | 18 | |
19 | - private int statusCode; | |
19 | + private int statusCode; | |
20 | 20 | |
21 | - public DemoiselleRESTException() { | |
21 | + public DemoiselleRESTException() { | |
22 | 22 | |
23 | - } | |
24 | - | |
25 | - public DemoiselleRESTException(String string) { | |
26 | - super(string); | |
27 | - } | |
23 | + } | |
28 | 24 | |
29 | - public int getStatusCode() { | |
30 | - return statusCode; | |
31 | - } | |
25 | + public DemoiselleRESTException(String string) { | |
26 | + super(string); | |
27 | + } | |
32 | 28 | |
33 | - public void addMessage(String field, String msg) { | |
34 | - this.statusCode = 422; | |
35 | - messages.put(field, msg); | |
36 | - } | |
29 | + public int getStatusCode() { | |
30 | + return statusCode; | |
31 | + } | |
37 | 32 | |
38 | - public HashMap<String, String> getMessages() { | |
39 | - return messages; | |
40 | - } | |
33 | + public void addMessage(String field, String msg) { | |
34 | + this.statusCode = 422; | |
35 | + messages.put(field, msg); | |
36 | + } | |
37 | + | |
38 | + public HashMap<String, String> getMessages() { | |
39 | + return messages; | |
40 | + } | |
41 | 41 | } | ... | ... |
demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java
... | ... | @@ -21,48 +21,52 @@ import org.demoiselle.jee.ws.jaxrs.exception.DemoiselleRESTException; |
21 | 21 | @Provider |
22 | 22 | public class GenericExceptionMapper implements ExceptionMapper<Exception> { |
23 | 23 | |
24 | - public Response toResponse(Exception ex) { | |
24 | + public Response toResponse(Exception ex) { | |
25 | 25 | |
26 | - StringWriter errorStackTrace = new StringWriter(); | |
27 | - ex.printStackTrace(new PrintWriter(errorStackTrace)); | |
26 | + StringWriter errorStackTrace = new StringWriter(); | |
27 | + ex.printStackTrace(new PrintWriter(errorStackTrace)); | |
28 | 28 | |
29 | - // Verifica se a exception é de validação de PAYLOAD do REST | |
30 | - if (ex.getCause() instanceof DemoiselleRESTException) { | |
31 | - DemoiselleRESTException exDemoiselleREST = (DemoiselleRESTException) ex.getCause(); | |
32 | - if (!exDemoiselleREST.getMessages().isEmpty()) { | |
33 | - return Response.status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessages()) | |
34 | - .type(MediaType.APPLICATION_JSON).build(); | |
35 | - } | |
36 | - } | |
29 | + // Verifica se a exception é de validação de PAYLOAD do REST | |
30 | + if (ex instanceof DemoiselleRESTException) { | |
31 | + DemoiselleRESTException exDemoiselleREST = (DemoiselleRESTException) ex; | |
32 | + if (!exDemoiselleREST.getMessages().isEmpty()) { | |
33 | + return Response.status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessages()) | |
34 | + .type(MediaType.APPLICATION_JSON).build(); | |
35 | + } else if (exDemoiselleREST.getStatusCode() > 0){ | |
36 | + return Response.status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessage()) | |
37 | + .type(MediaType.APPLICATION_JSON).build(); | |
38 | + } | |
37 | 39 | |
38 | - HashMap<String, String> entity = new HashMap<String, String>(); | |
40 | + } | |
39 | 41 | |
40 | - // No caso de existir message ele mostra a MESSAGE da Exception | |
41 | - if (ex.getMessage() != null) { | |
42 | - entity.put("error", ex.getMessage()); | |
42 | + HashMap<String, String> entity = new HashMap<String, String>(); | |
43 | 43 | |
44 | - // Pega toda as mensagens da stacktrace | |
45 | - int level = 1; | |
46 | - while (ex.getCause() != null) { | |
47 | - ex = (Exception) ex.getCause(); | |
48 | - if (!ex.getMessage().isEmpty()) { | |
49 | - entity.put("inner_cause_" + level, ex.getMessage()); | |
50 | - } | |
51 | - level += 1; | |
52 | - } | |
53 | - | |
54 | - // Por padrão retorna SERVER ERROR, mas tenta encontrar o status do RESPONSE se for WebApplicationException | |
55 | - // http://docs.oracle.com/javaee/7/api/javax/ws/rs/WebApplicationException.html | |
56 | - int responseCode = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); | |
57 | - if (ex instanceof WebApplicationException) { | |
58 | - responseCode = ((WebApplicationException)ex).getResponse().getStatus(); | |
59 | - } | |
44 | + // No caso de existir message ele mostra a MESSAGE da Exception | |
45 | + if (ex.getMessage() != null) { | |
46 | + entity.put("error", ex.getMessage()); | |
60 | 47 | |
61 | - return Response.status(responseCode).entity(entity).type(MediaType.APPLICATION_JSON).build(); | |
62 | - } | |
48 | + // Pega toda as mensagens da stacktrace | |
49 | + int level = 1; | |
50 | + while (ex.getCause() != null) { | |
51 | + ex = (Exception) ex.getCause(); | |
52 | + if (!ex.getMessage().isEmpty()) { | |
53 | + entity.put("inner_cause_" + level, ex.getMessage()); | |
54 | + } | |
55 | + level += 1; | |
56 | + } | |
63 | 57 | |
64 | - entity.put("error", "Erro interno desconhecido no servidor."); | |
65 | - return Response.status(500).entity(entity).type(MediaType.APPLICATION_JSON).build(); | |
66 | - } | |
58 | + // Por padrão retorna SERVER ERROR, mas tenta encontrar o status do RESPONSE se for WebApplicationException | |
59 | + // http://docs.oracle.com/javaee/7/api/javax/ws/rs/WebApplicationException.html | |
60 | + int responseCode = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); | |
61 | + if (ex instanceof WebApplicationException) { | |
62 | + responseCode = ((WebApplicationException) ex).getResponse().getStatus(); | |
63 | + } | |
64 | + | |
65 | + return Response.status(responseCode).entity(entity).type(MediaType.APPLICATION_JSON).build(); | |
66 | + } | |
67 | + | |
68 | + entity.put("error", "Erro interno desconhecido no servidor."); | |
69 | + return Response.status(500).entity(entity).type(MediaType.APPLICATION_JSON).build(); | |
70 | + } | |
67 | 71 | |
68 | 72 | } | ... | ... |
demoiselle-security-basic/pom.xml
... | ... | @@ -22,6 +22,11 @@ |
22 | 22 | <groupId>org.demoiselle.jee</groupId> |
23 | 23 | <artifactId>demoiselle-security</artifactId> |
24 | 24 | </dependency> |
25 | + | |
26 | + <dependency> | |
27 | + <groupId>org.demoiselle.jee</groupId> | |
28 | + <artifactId>demoiselle-persistence-jpa</artifactId> | |
29 | + </dependency> | |
25 | 30 | |
26 | 31 | </dependencies> |
27 | 32 | </project> | ... | ... |
demoiselle-security-basic/src/main/java/org/demoiselle/jee/security/basic/impl/TokensManagerImpl.java
... | ... | @@ -5,9 +5,12 @@ |
5 | 5 | */ |
6 | 6 | package org.demoiselle.jee.security.basic.impl; |
7 | 7 | |
8 | +import java.io.UnsupportedEncodingException; | |
9 | +import java.util.Base64; | |
8 | 10 | import java.util.logging.Logger; |
9 | 11 | import javax.enterprise.context.Dependent; |
10 | 12 | import javax.inject.Inject; |
13 | +import javax.persistence.EntityManager; | |
11 | 14 | import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; |
12 | 15 | import org.demoiselle.jee.core.interfaces.security.Token; |
13 | 16 | import org.demoiselle.jee.core.interfaces.security.TokensManager; |
... | ... | @@ -20,34 +23,40 @@ import org.demoiselle.jee.core.interfaces.security.TokensManager; |
20 | 23 | public class TokensManagerImpl implements TokensManager { |
21 | 24 | |
22 | 25 | @Inject |
23 | - private Logger logger; | |
26 | + private DemoisellePrincipal loggedUser; | |
24 | 27 | |
25 | 28 | @Inject |
26 | 29 | private Token token; |
27 | 30 | |
28 | 31 | @Inject |
29 | - private DemoisellePrincipal loggedUser; | |
32 | + private Logger logger; | |
33 | + | |
34 | + @Inject | |
35 | + private EntityManager entityManager; | |
30 | 36 | |
31 | 37 | @Override |
32 | 38 | public DemoisellePrincipal getUser() { |
33 | - if (loggedUser == null) { | |
34 | - if (token.getKey() != null && !token.getKey().isEmpty()) { | |
35 | - // desfaz o basic | |
36 | - return loggedUser; | |
37 | - } | |
39 | + try { | |
40 | + | |
41 | + byte[] asBytes = Base64.getDecoder().decode(token.getKey()); | |
42 | + String login = new String(asBytes, "utf-8"); | |
43 | + loggedUser = (DemoisellePrincipal) entityManager.createNativeQuery("select * from usuario where usuario = " + login.split(":")[0] + " senha = " + login.split(":")[1]).getResultList().get(0); | |
44 | + | |
45 | + } catch (UnsupportedEncodingException ex) { | |
46 | + logger.severe(ex.getMessage()); | |
38 | 47 | } |
48 | + | |
39 | 49 | return loggedUser; |
40 | 50 | } |
41 | 51 | |
42 | 52 | @Override |
43 | 53 | public void setUser(DemoisellePrincipal user) { |
44 | - String value = null; | |
45 | - | |
54 | + loggedUser = user; | |
46 | 55 | } |
47 | 56 | |
48 | 57 | @Override |
49 | 58 | public boolean validate() { |
50 | - return true;//(getUser() != null && repo.get(token.getKey()).); | |
59 | + return getUser() != null; | |
51 | 60 | } |
52 | 61 | |
53 | 62 | } | ... | ... |
demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java
... | ... | @@ -5,12 +5,11 @@ |
5 | 5 | */ |
6 | 6 | package org.demoiselle.jee.security.jwt.impl; |
7 | 7 | |
8 | -import com.google.gson.Gson; | |
9 | -import java.security.Key; | |
10 | -import java.security.Principal; | |
11 | -import java.util.logging.Level; | |
8 | +import java.util.List; | |
9 | +import java.util.Map; | |
12 | 10 | import java.util.logging.Logger; |
13 | 11 | import javax.enterprise.context.Dependent; |
12 | +import javax.enterprise.context.RequestScoped; | |
14 | 13 | import javax.inject.Inject; |
15 | 14 | import javax.servlet.http.HttpServletRequest; |
16 | 15 | import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; |
... | ... | @@ -36,7 +35,7 @@ public class TokensManagerImpl implements TokensManager { |
36 | 35 | @Inject |
37 | 36 | private HttpServletRequest httpRequest; |
38 | 37 | |
39 | - private RsaJsonWebKey rsaJsonWebKey; | |
38 | + private static RsaJsonWebKey rsaJsonWebKey; | |
40 | 39 | |
41 | 40 | @Inject |
42 | 41 | private Logger logger; |
... | ... | @@ -48,12 +47,14 @@ public class TokensManagerImpl implements TokensManager { |
48 | 47 | private DemoisellePrincipal loggedUser; |
49 | 48 | |
50 | 49 | public TokensManagerImpl() throws JoseException { |
51 | - RsaJsonWebKey chave = RsaJwkGenerator.generateJwk(2048); | |
52 | - logger.info("Se você quiser usar sua app em cluster, coloque o parametro jwt.key no app.properties e reinicie a aplicacao"); | |
53 | - logger.log(Level.INFO, "jwt.key={0}", chave); | |
54 | - logger.info("Se você não usar esse parametro, a cada reinicialização será gerada uma nova chave privada, isso inviabiliza o uso em cluster "); | |
55 | - rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk((Key) chave); | |
56 | - rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | |
50 | + if (rsaJsonWebKey == null) { | |
51 | +// RsaJsonWebKey chave = RsaJwkGenerator.generateJwk(2048); | |
52 | +// logger.info("Se você quiser usar sua app em cluster, coloque o parametro jwt.key no app.properties e reinicie a aplicacao"); | |
53 | +// logger.log(Level.INFO, "jwt.key={0}", chave); | |
54 | +// logger.info("Se você não usar esse parametro, a cada reinicialização será gerada uma nova chave privada, isso inviabiliza o uso em cluster "); | |
55 | + rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(RsaJwkGenerator.generateJwk(2048).getKey()); | |
56 | + rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | |
57 | + } | |
57 | 58 | } |
58 | 59 | |
59 | 60 | @Override |
... | ... | @@ -68,12 +69,18 @@ public class TokensManagerImpl implements TokensManager { |
68 | 69 | .setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key |
69 | 70 | .build(); // create the JwtConsumer instance |
70 | 71 | JwtClaims jwtClaims = jwtConsumer.processToClaims(token.getKey()); |
71 | - loggedUser = new Gson().fromJson((String) jwtClaims.getClaimValue("user"), DemoisellePrincipal.class); | |
72 | + loggedUser.setId((String) jwtClaims.getClaimValue("id")); | |
73 | + loggedUser.setName((String) jwtClaims.getClaimValue("name")); | |
74 | + loggedUser.setRoles((List) jwtClaims.getClaimValue("roles")); | |
75 | + loggedUser.setPermissions((Map) jwtClaims.getClaimValue("permissions")); | |
76 | + //loggedUser = new Gson().fromJson((String) jwtClaims.getClaimValue("user"), DemoisellePrincipal.class); | |
72 | 77 | String ip = httpRequest.getRemoteAddr(); |
73 | 78 | if (!ip.equalsIgnoreCase((String) jwtClaims.getClaimValue("ip"))) { |
74 | 79 | return null; |
75 | 80 | } |
76 | 81 | } catch (InvalidJwtException ex) { |
82 | + loggedUser = null; | |
83 | + token.setKey(null); | |
77 | 84 | logger.severe(ex.getMessage()); |
78 | 85 | } |
79 | 86 | } |
... | ... | @@ -92,23 +99,27 @@ public class TokensManagerImpl implements TokensManager { |
92 | 99 | claims.setNotBeforeMinutesInThePast(1); |
93 | 100 | |
94 | 101 | claims.setClaim("ip", httpRequest.getRemoteAddr()); |
95 | - claims.setClaim("user", new Gson().toJson(user)); | |
102 | + claims.setClaim("id", (user.getId())); | |
103 | + claims.setClaim("name", (user.getName())); | |
104 | + claims.setClaim("roles", (user.getRoles())); | |
105 | + claims.setClaim("permissions", (user.getPermissions())); | |
96 | 106 | |
97 | 107 | JsonWebSignature jws = new JsonWebSignature(); |
98 | 108 | jws.setPayload(claims.toJson()); |
99 | - jws.setKey(rsaJsonWebKey.getPrivateKey()); | |
109 | + jws.setKey(rsaJsonWebKey.getKey()); | |
100 | 110 | jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId()); |
101 | - jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); | |
111 | + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA512); | |
102 | 112 | token.setKey(jws.getCompactSerialization()); |
103 | 113 | } catch (JoseException ex) { |
104 | - logger.severe(ex.getMessage()); | |
114 | + ex.printStackTrace(); | |
115 | + // logger.severe(ex.getMessage()); | |
105 | 116 | } |
106 | 117 | |
107 | 118 | } |
108 | 119 | |
109 | 120 | @Override |
110 | 121 | public boolean validate() { |
111 | - return true; | |
122 | + return getUser() != null; | |
112 | 123 | } |
113 | 124 | |
114 | 125 | } | ... | ... |
demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java
... | ... | @@ -5,7 +5,8 @@ |
5 | 5 | */ |
6 | 6 | package org.demoiselle.jee.security.token.impl; |
7 | 7 | |
8 | -import java.security.Principal; | |
8 | +import java.util.Iterator; | |
9 | +import java.util.Map; | |
9 | 10 | import java.util.UUID; |
10 | 11 | import java.util.concurrent.ConcurrentHashMap; |
11 | 12 | import java.util.logging.Logger; |
... | ... | @@ -20,7 +21,7 @@ import org.demoiselle.jee.core.interfaces.security.TokensManager; |
20 | 21 | * |
21 | 22 | * @author 70744416353 |
22 | 23 | */ |
23 | -@RequestScoped | |
24 | +@Dependent | |
24 | 25 | public class TokensManagerImpl implements TokensManager { |
25 | 26 | |
26 | 27 | private final static ConcurrentHashMap<String, DemoisellePrincipal> repo = new ConcurrentHashMap<>(); |
... | ... | @@ -45,13 +46,17 @@ public class TokensManagerImpl implements TokensManager { |
45 | 46 | String value = UUID.randomUUID().toString(); |
46 | 47 | repo.put(value, user); |
47 | 48 | token.setKey(value); |
48 | - token.setType("Token"); | |
49 | + } else { | |
50 | + repo.entrySet().parallelStream().filter((e) -> (user.equals(e.getValue()))).forEach((e) -> { | |
51 | + token.setKey((String) e.getKey()); | |
52 | + }); | |
49 | 53 | } |
54 | + token.setType("Token"); | |
50 | 55 | } |
51 | 56 | |
52 | 57 | @Override |
53 | 58 | public boolean validate() { |
54 | - return true;//(getUser() != null && repo.get(token.getKey()).); | |
59 | + return getUser() != null; | |
55 | 60 | } |
56 | 61 | |
57 | 62 | } | ... | ... |
demoiselle-security/pom.xml
... | ... | @@ -23,6 +23,10 @@ |
23 | 23 | <groupId>org.demoiselle.jee</groupId> |
24 | 24 | <artifactId>demoiselle-core</artifactId> |
25 | 25 | </dependency> |
26 | - | |
26 | + | |
27 | + <dependency> | |
28 | + <groupId>org.demoiselle.jee</groupId> | |
29 | + <artifactId>demoiselle-rest</artifactId> | |
30 | + </dependency> | |
27 | 31 | </dependencies> |
28 | 32 | </project> | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/exception/DemoiselleSecurityException.java
... | ... | @@ -8,30 +8,31 @@ package org.demoiselle.jee.security.exception; |
8 | 8 | |
9 | 9 | import java.util.HashMap; |
10 | 10 | |
11 | -import org.demoiselle.jee.core.exception.DemoiselleException; | |
11 | +import org.demoiselle.jee.ws.jaxrs.exception.DemoiselleRESTException; | |
12 | 12 | |
13 | -public class DemoiselleSecurityException extends DemoiselleException { | |
13 | +public class DemoiselleSecurityException extends DemoiselleRESTException { | |
14 | 14 | |
15 | - private static final long serialVersionUID = 519965615171844237L; | |
15 | + private static final long serialVersionUID = 519965615171844237L; | |
16 | 16 | |
17 | - private HashMap<String, String> messages = new HashMap<String, String>(); | |
17 | + private HashMap<String, String> messages = new HashMap<String, String>(); | |
18 | 18 | |
19 | - private int statusCode; | |
19 | + private int statusCode; | |
20 | 20 | |
21 | - public DemoiselleSecurityException(String string) { | |
22 | - super(string); | |
23 | - } | |
21 | + public DemoiselleSecurityException(String string) { | |
22 | + super(string); | |
23 | + this.statusCode = 401; | |
24 | + } | |
24 | 25 | |
25 | - public int getStatusCode() { | |
26 | - return statusCode; | |
27 | - } | |
26 | + public int getStatusCode() { | |
27 | + return statusCode; | |
28 | + } | |
28 | 29 | |
29 | - public void addMessage(String field, String msg) { | |
30 | - this.statusCode = 422; | |
31 | - messages.put(field, msg); | |
32 | - } | |
30 | + public void addMessage(String field, String msg) { | |
33 | 31 | |
34 | - public HashMap<String, String> getMessages() { | |
35 | - return messages; | |
36 | - } | |
32 | + messages.put(field, msg); | |
33 | + } | |
34 | + | |
35 | + public HashMap<String, String> getMessages() { | |
36 | + return messages; | |
37 | + } | |
37 | 38 | } | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/exception/NotLoggedInException.java
... | ... | @@ -13,7 +13,7 @@ package org.demoiselle.jee.security.exception; |
13 | 13 | * |
14 | 14 | * @author SERPRO |
15 | 15 | */ |
16 | -public class NotLoggedInException extends AuthenticationException { | |
16 | +public class NotLoggedInException extends DemoiselleSecurityException { | |
17 | 17 | |
18 | 18 | private static final long serialVersionUID = 1L; |
19 | 19 | |
... | ... | @@ -27,4 +27,6 @@ public class NotLoggedInException extends AuthenticationException { |
27 | 27 | public NotLoggedInException(String message) { |
28 | 28 | super(message); |
29 | 29 | } |
30 | + | |
31 | + | |
30 | 32 | } | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/impl/DemoisellePrincipalImpl.java
0 → 100644
... | ... | @@ -0,0 +1,97 @@ |
1 | +/* | |
2 | + * Demoiselle Framework | |
3 | + * | |
4 | + * License: GNU Lesser General Public License (LGPL), version 3 or later. | |
5 | + * See the lgpl.txt file in the root directory or <https://www.gnu.org/licenses/lgpl.html>. | |
6 | + */ | |
7 | +package org.demoiselle.jee.security.impl; | |
8 | + | |
9 | +import java.util.List; | |
10 | +import java.util.Map; | |
11 | +import java.util.Objects; | |
12 | +import javax.enterprise.context.RequestScoped; | |
13 | +import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; | |
14 | + | |
15 | +/** | |
16 | + * | |
17 | + * @author 70744416353 | |
18 | + */ | |
19 | +@RequestScoped | |
20 | +public class DemoisellePrincipalImpl implements DemoisellePrincipal { | |
21 | + | |
22 | + private String id; | |
23 | + private String name; | |
24 | + private List<String> roles; | |
25 | + private Map<String, String> permissions; | |
26 | + | |
27 | + @Override | |
28 | + public String getId() { | |
29 | + return id; | |
30 | + } | |
31 | + | |
32 | + @Override | |
33 | + public void setId(String id) { | |
34 | + this.id = id; | |
35 | + } | |
36 | + | |
37 | + @Override | |
38 | + public String getName() { | |
39 | + return name; | |
40 | + } | |
41 | + | |
42 | + @Override | |
43 | + public void setName(String name) { | |
44 | + this.name = name; | |
45 | + } | |
46 | + | |
47 | + @Override | |
48 | + public List<String> getRoles() { | |
49 | + return roles; | |
50 | + } | |
51 | + | |
52 | + @Override | |
53 | + public void setRoles(List<String> roles) { | |
54 | + this.roles = roles; | |
55 | + } | |
56 | + | |
57 | + @Override | |
58 | + public Map<String, String> getPermissions() { | |
59 | + return permissions; | |
60 | + } | |
61 | + | |
62 | + @Override | |
63 | + public void setPermissions(Map<String, String> permissions) { | |
64 | + this.permissions = permissions; | |
65 | + } | |
66 | + | |
67 | + @Override | |
68 | + public int hashCode() { | |
69 | + int hash = 7; | |
70 | + hash = 37 * hash + Objects.hashCode(this.id); | |
71 | + return hash; | |
72 | + } | |
73 | + | |
74 | + @Override | |
75 | + public boolean equals(Object obj) { | |
76 | + if (this == obj) { | |
77 | + return true; | |
78 | + } | |
79 | + if (obj == null) { | |
80 | + return false; | |
81 | + } | |
82 | + if (getClass() != obj.getClass()) { | |
83 | + return false; | |
84 | + } | |
85 | + final DemoisellePrincipalImpl other = (DemoisellePrincipalImpl) obj; | |
86 | + if (!Objects.equals(this.id, other.id)) { | |
87 | + return false; | |
88 | + } | |
89 | + return true; | |
90 | + } | |
91 | + | |
92 | + @Override | |
93 | + public String toString() { | |
94 | + return "DemoisellePrincipalImpl{" + "id=" + id + ", name=" + name + ", roles=" + roles + ", permissions=" + permissions + '}'; | |
95 | + } | |
96 | + | |
97 | +} | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/impl/SecurityContextImpl.java
... | ... | @@ -6,15 +6,17 @@ |
6 | 6 | */ |
7 | 7 | package org.demoiselle.jee.security.impl; |
8 | 8 | |
9 | +import java.util.Iterator; | |
10 | +import java.util.Map; | |
11 | +import java.util.stream.Collectors; | |
9 | 12 | import javax.enterprise.context.Dependent; |
10 | 13 | import javax.inject.Inject; |
11 | 14 | import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; |
12 | 15 | |
13 | -import org.demoiselle.jee.core.util.ResourceBundle; | |
14 | - | |
15 | 16 | import org.demoiselle.jee.security.exception.NotLoggedInException; |
16 | 17 | import org.demoiselle.jee.core.interfaces.security.SecurityContext; |
17 | 18 | import org.demoiselle.jee.core.interfaces.security.TokensManager; |
19 | +import org.demoiselle.jee.security.message.DemoiselleSecurityMessages; | |
18 | 20 | |
19 | 21 | /** |
20 | 22 | * <p> |
... | ... | @@ -32,7 +34,7 @@ public class SecurityContextImpl implements SecurityContext { |
32 | 34 | private TokensManager tm; |
33 | 35 | |
34 | 36 | @Inject |
35 | - private ResourceBundle bundle; | |
37 | + private DemoiselleSecurityMessages bundle; | |
36 | 38 | |
37 | 39 | /** |
38 | 40 | * @see org.demoiselle.security.SecurityContext#hasPermission(String, |
... | ... | @@ -40,9 +42,11 @@ public class SecurityContextImpl implements SecurityContext { |
40 | 42 | */ |
41 | 43 | @Override |
42 | 44 | public boolean hasPermission(String resource, String operation) { |
43 | - boolean result = true; | |
44 | - | |
45 | - return result; | |
45 | + return (tm.getUser().getPermissions().entrySet() | |
46 | + .stream() | |
47 | + .filter(p -> p.getKey().equalsIgnoreCase(resource)) | |
48 | + .filter(p -> p.getValue().equalsIgnoreCase(operation)) | |
49 | + .count() > 0); | |
46 | 50 | } |
47 | 51 | |
48 | 52 | /** |
... | ... | @@ -50,9 +54,7 @@ public class SecurityContextImpl implements SecurityContext { |
50 | 54 | */ |
51 | 55 | @Override |
52 | 56 | public boolean hasRole(String role) { |
53 | - boolean result = true; | |
54 | - | |
55 | - return result; | |
57 | + return (tm.getUser().getRoles().parallelStream().filter(p -> p.equals(role)).count() > 0); | |
56 | 58 | } |
57 | 59 | |
58 | 60 | /** |
... | ... | @@ -66,7 +68,7 @@ public class SecurityContextImpl implements SecurityContext { |
66 | 68 | @Override |
67 | 69 | public void checkLoggedIn() throws NotLoggedInException { |
68 | 70 | if (!isLoggedIn()) { |
69 | - throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
71 | + throw new NotLoggedInException(bundle.userNotAuthenticated()); | |
70 | 72 | } |
71 | 73 | } |
72 | 74 | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/impl/TokenImpl.java
... | ... | @@ -6,13 +6,14 @@ |
6 | 6 | package org.demoiselle.jee.security.impl; |
7 | 7 | |
8 | 8 | import javax.enterprise.context.Dependent; |
9 | +import javax.enterprise.context.RequestScoped; | |
9 | 10 | import org.demoiselle.jee.core.interfaces.security.Token; |
10 | 11 | |
11 | 12 | /** |
12 | 13 | * |
13 | 14 | * @author 70744416353 |
14 | 15 | */ |
15 | -@Dependent | |
16 | +@RequestScoped | |
16 | 17 | public class TokenImpl implements Token { |
17 | 18 | |
18 | 19 | private String key; | ... | ... |
demoiselle-security/src/main/java/org/demoiselle/jee/security/message/DemoiselleSecurityMessages.java
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +/* | |
2 | + * Demoiselle Framework | |
3 | + * | |
4 | + * License: GNU Lesser General Public License (LGPL), version 3 or later. | |
5 | + * See the lgpl.txt file in the root directory or <https://www.gnu.org/licenses/lgpl.html>. | |
6 | + */ | |
7 | +package org.demoiselle.jee.security.message; | |
8 | + | |
9 | +import org.apache.deltaspike.core.api.message.MessageBundle; | |
10 | +import org.apache.deltaspike.core.api.message.MessageTemplate; | |
11 | + | |
12 | +@MessageBundle | |
13 | +public interface DemoiselleSecurityMessages { | |
14 | + | |
15 | + @MessageTemplate("{user-not-authenticated}") | |
16 | + String userNotAuthenticated(); | |
17 | + | |
18 | + | |
19 | +} | |
0 | 20 | \ No newline at end of file | ... | ... |
demoiselle-security/src/main/resources/messages.properties
... | ... | @@ -1,12 +0,0 @@ |
1 | -adding-message-to-context=Adicionando uma mensagem no contexto: [{0}] | |
2 | -access-checking=Verificando permiss\u00e3o do usu\u00e1rio {0} para executar a a\u00e7\u00e3o {1} no recurso {2} | |
3 | -access-allowed=O usu\u00e1rio {0} acessou o recurso {2} com a a\u00e7\u00e3o {1} | |
4 | -access-denied=O usu\u00e1rio {0} n\u00e3o possui permiss\u00e3o para executar a a\u00e7\u00e3o {1} no recurso {2} | |
5 | -access-denied-ui=Voc\u00ea n\u00e3o est\u00e1 autorizado a executar a a\u00e7\u00e3o {1} no recurso {0} | |
6 | -authorizer-not-defined=Nenhuma regra de resolu\u00e7\u00e3o de permiss\u00f5es foi definida. Para utilizar @{0} \u00e9 preciso definir a propriedade frameworkdemoiselle.security.authorizer.class como regra de resolu\u00e7\u00e3o de permiss\u00f5es desejada no arquivo demoiselle.properties. | |
7 | -user-not-authenticated=Usu\u00e1rio n\u00e3o autenticado | |
8 | -invalid-credentials=Usu\u00e1rio ou senha inv\u00e1lidos | |
9 | -has-role-verification=Verificando se o usu\u00e1rio {0} possui a(s) role(s)\: {1} | |
10 | -does-not-have-role=Usu\u00e1rio {0} n\u00e3o possui a(s) role(s)\: {1} | |
11 | -does-not-have-role-ui=Para acessar este recurso \u00e9 necess\u00e1rio ser {0} | |
12 | -user-has-role=Usu\u00e1rio {0} possui a(s) role(s)\: {1} | |
13 | 0 | \ No newline at end of file |
demoiselle-security/src/main/resources/org/demoiselle/jee/security/message/DemoiselleSecurityMessages.properties
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +adding-message-to-context=Adicionando uma mensagem no contexto: [{0}] | |
2 | +access-checking=Verificando permiss\u00e3o do usu\u00e1rio {0} para executar a a\u00e7\u00e3o {1} no recurso {2} | |
3 | +access-allowed=O usu\u00e1rio {0} acessou o recurso {2} com a a\u00e7\u00e3o {1} | |
4 | +access-denied=O usu\u00e1rio {0} n\u00e3o possui permiss\u00e3o para executar a a\u00e7\u00e3o {1} no recurso {2} | |
5 | +access-denied-ui=Voc\u00ea n\u00e3o est\u00e1 autorizado a executar a a\u00e7\u00e3o {1} no recurso {0} | |
6 | +authorizer-not-defined=Nenhuma regra de resolu\u00e7\u00e3o de permiss\u00f5es foi definida. Para utilizar @{0} \u00e9 preciso definir a propriedade frameworkdemoiselle.security.authorizer.class como regra de resolu\u00e7\u00e3o de permiss\u00f5es desejada no arquivo demoiselle.properties. | |
7 | +user-not-authenticated=Usu\u00e1rio n\u00e3o autenticado | |
8 | +invalid-credentials=Usu\u00e1rio ou senha inv\u00e1lidos | |
9 | +has-role-verification=Verificando se o usu\u00e1rio {0} possui a(s) role(s)\: {1} | |
10 | +does-not-have-role=Usu\u00e1rio {0} n\u00e3o possui a(s) role(s)\: {1} | |
11 | +does-not-have-role-ui=Para acessar este recurso \u00e9 necess\u00e1rio ser {0} | |
12 | +user-has-role=Usu\u00e1rio {0} possui a(s) role(s)\: {1} | |
0 | 13 | \ No newline at end of file | ... | ... |