Commit 021d223bacede45579b1fc641a54998c41c624ad

Authored by PauloGladson
1 parent 50340724

Ajustes segurança

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&lt;Exception&gt; { @@ -31,22 +31,23 @@ public class GenericExceptionMapper implements ExceptionMapper&lt;Exception&gt; {
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&lt;Exception&gt; { @@ -55,7 +56,7 @@ public class GenericExceptionMapper implements ExceptionMapper&lt;Exception&gt; {
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
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -user-not-authenticated  
2 \ No newline at end of file 0 \ No newline at end of file
demoiselle-security-jwt/src/main/resources/messages.properties
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -tipo-seguranca=basic  
2 \ No newline at end of file 0 \ No newline at end of file
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)) {