Commit 021d223bacede45579b1fc641a54998c41c624ad
1 parent
50340724
Ajustes segurança
Showing
10 changed files
with
149 additions
and
16 deletions
Show diff stats
demoiselle-core/src/main/java/org/demoiselle/jee/core/interfaces/security/TokensManager.java
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
7 | package org.demoiselle.jee.core.interfaces.security; | 7 | package org.demoiselle.jee.core.interfaces.security; |
8 | 8 | ||
9 | import java.io.Serializable; | 9 | import java.io.Serializable; |
10 | +import java.security.PublicKey; | ||
10 | 11 | ||
11 | /** | 12 | /** |
12 | * <p> | 13 | * <p> |
@@ -23,4 +24,6 @@ public interface TokensManager extends Serializable { | @@ -23,4 +24,6 @@ public interface TokensManager extends Serializable { | ||
23 | 24 | ||
24 | public boolean validate(); | 25 | public boolean validate(); |
25 | 26 | ||
27 | + public PublicKey getPublicKey(); | ||
28 | + | ||
26 | } | 29 | } |
demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java
@@ -31,22 +31,23 @@ public class GenericExceptionMapper implements ExceptionMapper<Exception> { | @@ -31,22 +31,23 @@ public class GenericExceptionMapper implements ExceptionMapper<Exception> { | ||
31 | 31 | ||
32 | StringWriter errorStackTrace = new StringWriter(); | 32 | StringWriter errorStackTrace = new StringWriter(); |
33 | ex.printStackTrace(new PrintWriter(errorStackTrace)); | 33 | ex.printStackTrace(new PrintWriter(errorStackTrace)); |
34 | + HashMap<String, String> entity = new HashMap<>(); | ||
34 | 35 | ||
35 | // Verifica se a exception é de validação de PAYLOAD do REST | 36 | // Verifica se a exception é de validação de PAYLOAD do REST |
36 | if (ex instanceof DemoiselleRESTException) { | 37 | if (ex instanceof DemoiselleRESTException) { |
37 | DemoiselleRESTException exDemoiselleREST = (DemoiselleRESTException) ex; | 38 | DemoiselleRESTException exDemoiselleREST = (DemoiselleRESTException) ex; |
38 | if (!exDemoiselleREST.getMessages().isEmpty()) { | 39 | if (!exDemoiselleREST.getMessages().isEmpty()) { |
39 | - return status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessages()) | 40 | + entity.put("error", exDemoiselleREST.getMessages().toString()); |
41 | + return status(exDemoiselleREST.getStatusCode()).entity(entity) | ||
40 | .type(APPLICATION_JSON).build(); | 42 | .type(APPLICATION_JSON).build(); |
41 | - } else if (exDemoiselleREST.getStatusCode() > 0){ | ||
42 | - return status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessage()) | 43 | + } else if (exDemoiselleREST.getStatusCode() > 0) { |
44 | + entity.put("error", exDemoiselleREST.getMessage()); | ||
45 | + return status(exDemoiselleREST.getStatusCode()).entity(entity) | ||
43 | .type(APPLICATION_JSON).build(); | 46 | .type(APPLICATION_JSON).build(); |
44 | } | 47 | } |
45 | 48 | ||
46 | } | 49 | } |
47 | 50 | ||
48 | - HashMap<String, String> entity = new HashMap<>(); | ||
49 | - | ||
50 | // No caso de existir message ele mostra a MESSAGE da Exception | 51 | // No caso de existir message ele mostra a MESSAGE da Exception |
51 | if (ex.getMessage() != null) { | 52 | if (ex.getMessage() != null) { |
52 | entity.put("error", ex.getMessage()); | 53 | entity.put("error", ex.getMessage()); |
@@ -55,7 +56,7 @@ public class GenericExceptionMapper implements ExceptionMapper<Exception> { | @@ -55,7 +56,7 @@ public class GenericExceptionMapper implements ExceptionMapper<Exception> { | ||
55 | int level = 1; | 56 | int level = 1; |
56 | while (ex.getCause() != null) { | 57 | while (ex.getCause() != null) { |
57 | ex = (Exception) ex.getCause(); | 58 | ex = (Exception) ex.getCause(); |
58 | - if (!ex.getMessage().isEmpty()) { | 59 | + if (ex != null && ex.getMessage() != null && !ex.getMessage().isEmpty()) { |
59 | entity.put("inner_cause_" + level, ex.getMessage()); | 60 | entity.put("inner_cause_" + level, ex.getMessage()); |
60 | } | 61 | } |
61 | level += 1; | 62 | level += 1; |
demoiselle-security-jwt/pom.xml
@@ -24,6 +24,11 @@ | @@ -24,6 +24,11 @@ | ||
24 | </dependency> | 24 | </dependency> |
25 | 25 | ||
26 | <dependency> | 26 | <dependency> |
27 | + <groupId>org.demoiselle.jee</groupId> | ||
28 | + <artifactId>demoiselle-configuration</artifactId> | ||
29 | + </dependency> | ||
30 | + | ||
31 | + <dependency> | ||
27 | <groupId>org.bitbucket.b_c</groupId> | 32 | <groupId>org.bitbucket.b_c</groupId> |
28 | <artifactId>jose4j</artifactId> | 33 | <artifactId>jose4j</artifactId> |
29 | <version>0.5.2</version> | 34 | <version>0.5.2</version> |
demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/Config.java
0 → 100644
@@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
1 | +/* | ||
2 | + * To change this license header, choose License Headers in Project Properties. | ||
3 | + * To change this template file, choose Tools | Templates | ||
4 | + * and open the template in the editor. | ||
5 | + */ | ||
6 | +package org.demoiselle.jee.security.jwt.impl; | ||
7 | + | ||
8 | +import java.io.Serializable; | ||
9 | +import org.demoiselle.jee.configuration.annotation.Configuration; | ||
10 | +import org.demoiselle.jee.core.annotation.Name; | ||
11 | + | ||
12 | +/** | ||
13 | + * | ||
14 | + * @author 70744416353 | ||
15 | + */ | ||
16 | +@Configuration(resource = "demoiselle-security-jwt") | ||
17 | +public class Config implements Serializable { | ||
18 | + | ||
19 | + private static final long serialVersionUID = 638435989235076782L; | ||
20 | + | ||
21 | + @Name("jwt.type") | ||
22 | + private String type; | ||
23 | + | ||
24 | + @Name("jwt.privateKey") | ||
25 | + private String privateKey; | ||
26 | + | ||
27 | + @Name("jwt.publicKey") | ||
28 | + private String publicKey; | ||
29 | + | ||
30 | + @Name("jwt.timetolive") | ||
31 | + private Float tempo; | ||
32 | + | ||
33 | + @Name("jwt.issuer") | ||
34 | + private String remetente; | ||
35 | + | ||
36 | + @Name("jwt.audience") | ||
37 | + private String destinatario; | ||
38 | + | ||
39 | + public String getType() { | ||
40 | + return type; | ||
41 | + } | ||
42 | + | ||
43 | + public void setType(String type) { | ||
44 | + this.type = type; | ||
45 | + } | ||
46 | + | ||
47 | + public String getPrivateKey() { | ||
48 | + return privateKey; | ||
49 | + } | ||
50 | + | ||
51 | + public void setPrivateKey(String privateKey) { | ||
52 | + this.privateKey = privateKey; | ||
53 | + } | ||
54 | + | ||
55 | + public String getPublicKey() { | ||
56 | + return publicKey; | ||
57 | + } | ||
58 | + | ||
59 | + public void setPublicKey(String publicKey) { | ||
60 | + this.publicKey = publicKey; | ||
61 | + } | ||
62 | + | ||
63 | + public Float getTempo() { | ||
64 | + return tempo; | ||
65 | + } | ||
66 | + | ||
67 | + public void setTempo(Float tempo) { | ||
68 | + this.tempo = tempo; | ||
69 | + } | ||
70 | + | ||
71 | + public String getRemetente() { | ||
72 | + return remetente; | ||
73 | + } | ||
74 | + | ||
75 | + public void setRemetente(String remetente) { | ||
76 | + this.remetente = remetente; | ||
77 | + } | ||
78 | + | ||
79 | + public String getDestinatario() { | ||
80 | + return destinatario; | ||
81 | + } | ||
82 | + | ||
83 | + public void setDestinatario(String destinatario) { | ||
84 | + this.destinatario = destinatario; | ||
85 | + } | ||
86 | + | ||
87 | +} |
demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java
@@ -5,15 +5,20 @@ | @@ -5,15 +5,20 @@ | ||
5 | */ | 5 | */ |
6 | package org.demoiselle.jee.security.jwt.impl; | 6 | package org.demoiselle.jee.security.jwt.impl; |
7 | 7 | ||
8 | +import java.security.PublicKey; | ||
8 | import java.util.List; | 9 | import java.util.List; |
9 | import java.util.Map; | 10 | import java.util.Map; |
11 | +import java.util.logging.Level; | ||
10 | import java.util.logging.Logger; | 12 | import java.util.logging.Logger; |
13 | +import javax.annotation.PostConstruct; | ||
14 | +import javax.enterprise.context.ApplicationScoped; | ||
11 | import javax.enterprise.context.RequestScoped; | 15 | import javax.enterprise.context.RequestScoped; |
12 | import javax.inject.Inject; | 16 | import javax.inject.Inject; |
13 | import javax.servlet.http.HttpServletRequest; | 17 | import javax.servlet.http.HttpServletRequest; |
14 | import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; | 18 | import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; |
15 | import org.demoiselle.jee.core.interfaces.security.Token; | 19 | import org.demoiselle.jee.core.interfaces.security.Token; |
16 | import org.demoiselle.jee.core.interfaces.security.TokensManager; | 20 | import org.demoiselle.jee.core.interfaces.security.TokensManager; |
21 | +import org.demoiselle.jee.security.exception.DemoiselleSecurityException; | ||
17 | import org.jose4j.jwk.JsonWebKey; | 22 | import org.jose4j.jwk.JsonWebKey; |
18 | import org.jose4j.jwk.RsaJsonWebKey; | 23 | import org.jose4j.jwk.RsaJsonWebKey; |
19 | import org.jose4j.jwk.RsaJwkGenerator; | 24 | import org.jose4j.jwk.RsaJwkGenerator; |
@@ -43,14 +48,37 @@ public class TokensManagerImpl implements TokensManager { | @@ -43,14 +48,37 @@ public class TokensManagerImpl implements TokensManager { | ||
43 | @Inject | 48 | @Inject |
44 | private Token token; | 49 | private Token token; |
45 | 50 | ||
51 | +// @Inject | ||
52 | +// private Config config; | ||
46 | @Inject | 53 | @Inject |
47 | private DemoisellePrincipal loggedUser; | 54 | private DemoisellePrincipal loggedUser; |
48 | 55 | ||
49 | - public TokensManagerImpl() throws JoseException { | 56 | + //@PostConstruct |
57 | + public TokensManagerImpl() { | ||
50 | if (rsaJsonWebKey == null) { | 58 | if (rsaJsonWebKey == null) { |
51 | - String chave = RsaJwkGenerator.generateJwk(2048).toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE); | ||
52 | - rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(chave); | ||
53 | - rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | 59 | +// logger.info("Demoiselle Module - Security - JWT"); |
60 | + try { | ||
61 | + | ||
62 | +// if (config.getType() == null) { | ||
63 | +// throw new DemoiselleSecurityException("Escolha o tipo de autenticação, ver documentação", 500); | ||
64 | +// } | ||
65 | +// | ||
66 | +// if (config.getType().equalsIgnoreCase("slave") && (config.getPublicKey() == null || config.getPublicKey().isEmpty())) { | ||
67 | +// throw new DemoiselleSecurityException("Informe a chave pública no arquivo de configuração do projeto, ver documentação", 500); | ||
68 | +// } else { | ||
69 | +// rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(config.getPrivateKey()); | ||
70 | +// } | ||
71 | +// | ||
72 | +// if (config.getType().equalsIgnoreCase("master") && (config.getPrivateKey() == null || config.getPrivateKey().isEmpty())) { | ||
73 | +// throw new DemoiselleSecurityException("Informe a chave privada no arquivo de configuração do projeto, ver documentação", 500); | ||
74 | +// } else { | ||
75 | +// rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(config.getPublicKey()); | ||
76 | +// } | ||
77 | + rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(RsaJwkGenerator.generateJwk(2048).toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE)); | ||
78 | + rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | ||
79 | + } catch (JoseException ex) { | ||
80 | + // logger.severe(ex.getMessage()); | ||
81 | + } | ||
54 | } | 82 | } |
55 | } | 83 | } |
56 | 84 | ||
@@ -63,7 +91,6 @@ public class TokensManagerImpl implements TokensManager { | @@ -63,7 +91,6 @@ public class TokensManagerImpl implements TokensManager { | ||
63 | .setAllowedClockSkewInSeconds(60) // allow some leeway in validating time based claims to account for clock skew | 91 | .setAllowedClockSkewInSeconds(60) // allow some leeway in validating time based claims to account for clock skew |
64 | .setExpectedIssuer("demoiselle") // whom the JWT needs to have been issued by | 92 | .setExpectedIssuer("demoiselle") // whom the JWT needs to have been issued by |
65 | .setExpectedAudience("demoiselle") // to whom the JWT is intended for | 93 | .setExpectedAudience("demoiselle") // to whom the JWT is intended for |
66 | - .setDecryptionKey(rsaJsonWebKey.getPrivateKey()) // decrypt with the receiver's private key | ||
67 | .setVerificationKey(rsaJsonWebKey.getPublicKey()) | 94 | .setVerificationKey(rsaJsonWebKey.getPublicKey()) |
68 | .build(); // create the JwtConsumer instance | 95 | .build(); // create the JwtConsumer instance |
69 | JwtClaims jwtClaims = jwtConsumer.processToClaims(token.getKey()); | 96 | JwtClaims jwtClaims = jwtConsumer.processToClaims(token.getKey()); |
@@ -111,7 +138,6 @@ public class TokensManagerImpl implements TokensManager { | @@ -111,7 +138,6 @@ public class TokensManagerImpl implements TokensManager { | ||
111 | token.setKey(jws.getCompactSerialization()); | 138 | token.setKey(jws.getCompactSerialization()); |
112 | token.setType("JWT"); | 139 | token.setType("JWT"); |
113 | } catch (JoseException ex) { | 140 | } catch (JoseException ex) { |
114 | - //ex.printStackTrace(); | ||
115 | logger.severe(ex.getMessage()); | 141 | logger.severe(ex.getMessage()); |
116 | } | 142 | } |
117 | 143 | ||
@@ -122,4 +148,8 @@ public class TokensManagerImpl implements TokensManager { | @@ -122,4 +148,8 @@ public class TokensManagerImpl implements TokensManager { | ||
122 | return getUser() != null; | 148 | return getUser() != null; |
123 | } | 149 | } |
124 | 150 | ||
151 | + @Override | ||
152 | + public PublicKey getPublicKey() { | ||
153 | + return rsaJsonWebKey.getPublicKey(); | ||
154 | + } | ||
125 | } | 155 | } |
demoiselle-security-jwt/src/main/resources/demoiselle.properties
demoiselle-security-jwt/src/main/resources/messages.properties
demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | */ | 5 | */ |
6 | package org.demoiselle.jee.security.token.impl; | 6 | package org.demoiselle.jee.security.token.impl; |
7 | 7 | ||
8 | +import java.security.PublicKey; | ||
8 | import static java.util.UUID.randomUUID; | 9 | import static java.util.UUID.randomUUID; |
9 | import java.util.concurrent.ConcurrentHashMap; | 10 | import java.util.concurrent.ConcurrentHashMap; |
10 | import java.util.logging.Logger; | 11 | import java.util.logging.Logger; |
@@ -59,4 +60,8 @@ public class TokensManagerImpl implements TokensManager { | @@ -59,4 +60,8 @@ public class TokensManagerImpl implements TokensManager { | ||
59 | return getUser() != null; | 60 | return getUser() != null; |
60 | } | 61 | } |
61 | 62 | ||
63 | + @Override | ||
64 | + public PublicKey getPublicKey() { | ||
65 | + return null; | ||
66 | + } | ||
62 | } | 67 | } |
demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredPermissionInterceptor.java
@@ -71,8 +71,8 @@ public class RequiredPermissionInterceptor implements Serializable { | @@ -71,8 +71,8 @@ public class RequiredPermissionInterceptor implements Serializable { | ||
71 | String resource = getResource(ic); | 71 | String resource = getResource(ic); |
72 | String operation = getOperation(ic); | 72 | String operation = getOperation(ic); |
73 | 73 | ||
74 | - if (securityContext.isLoggedIn()) { | ||
75 | - logger.finest(bundle.accessCheckingPermission(operation, resource)); | 74 | + if (!securityContext.isLoggedIn()) { |
75 | + throw new DemoiselleSecurityException(bundle.userNotAuthenticated(), UNAUTHORIZED.getStatusCode()); | ||
76 | } | 76 | } |
77 | 77 | ||
78 | if (!securityContext.hasPermission(resource, operation)) { | 78 | if (!securityContext.hasPermission(resource, operation)) { |
demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredRoleInterceptor.java
@@ -75,6 +75,10 @@ public class RequiredRoleInterceptor implements Serializable { | @@ -75,6 +75,10 @@ public class RequiredRoleInterceptor implements Serializable { | ||
75 | List<String> roles = getRoles(ic); | 75 | List<String> roles = getRoles(ic); |
76 | 76 | ||
77 | List<String> userRoles = new ArrayList<>(); | 77 | List<String> userRoles = new ArrayList<>(); |
78 | + | ||
79 | + if (!securityContext.isLoggedIn()) { | ||
80 | + throw new DemoiselleSecurityException(bundle.userNotAuthenticated(), UNAUTHORIZED.getStatusCode()); | ||
81 | + } | ||
78 | 82 | ||
79 | for (String role : roles) { | 83 | for (String role : roles) { |
80 | if (securityContext.hasRole(role)) { | 84 | if (securityContext.hasRole(role)) { |