diff --git a/demoiselle-core/src/main/java/org/demoiselle/jee/core/interfaces/security/TokensManager.java b/demoiselle-core/src/main/java/org/demoiselle/jee/core/interfaces/security/TokensManager.java index 2f6adb1..21548dc 100644 --- a/demoiselle-core/src/main/java/org/demoiselle/jee/core/interfaces/security/TokensManager.java +++ b/demoiselle-core/src/main/java/org/demoiselle/jee/core/interfaces/security/TokensManager.java @@ -7,6 +7,7 @@ package org.demoiselle.jee.core.interfaces.security; import java.io.Serializable; +import java.security.PublicKey; /** *

@@ -23,4 +24,6 @@ public interface TokensManager extends Serializable { public boolean validate(); + public PublicKey getPublicKey(); + } diff --git a/demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java b/demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java index 9884fd0..4965791 100644 --- a/demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java +++ b/demoiselle-rest/src/main/java/org/demoiselle/jee/ws/jaxrs/exception/mapper/GenericExceptionMapper.java @@ -31,22 +31,23 @@ public class GenericExceptionMapper implements ExceptionMapper { StringWriter errorStackTrace = new StringWriter(); ex.printStackTrace(new PrintWriter(errorStackTrace)); + HashMap entity = new HashMap<>(); // Verifica se a exception é de validação de PAYLOAD do REST if (ex instanceof DemoiselleRESTException) { DemoiselleRESTException exDemoiselleREST = (DemoiselleRESTException) ex; if (!exDemoiselleREST.getMessages().isEmpty()) { - return status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessages()) + entity.put("error", exDemoiselleREST.getMessages().toString()); + return status(exDemoiselleREST.getStatusCode()).entity(entity) .type(APPLICATION_JSON).build(); - } else if (exDemoiselleREST.getStatusCode() > 0){ - return status(exDemoiselleREST.getStatusCode()).entity(exDemoiselleREST.getMessage()) + } else if (exDemoiselleREST.getStatusCode() > 0) { + entity.put("error", exDemoiselleREST.getMessage()); + return status(exDemoiselleREST.getStatusCode()).entity(entity) .type(APPLICATION_JSON).build(); } } - HashMap entity = new HashMap<>(); - // No caso de existir message ele mostra a MESSAGE da Exception if (ex.getMessage() != null) { entity.put("error", ex.getMessage()); @@ -55,7 +56,7 @@ public class GenericExceptionMapper implements ExceptionMapper { int level = 1; while (ex.getCause() != null) { ex = (Exception) ex.getCause(); - if (!ex.getMessage().isEmpty()) { + if (ex != null && ex.getMessage() != null && !ex.getMessage().isEmpty()) { entity.put("inner_cause_" + level, ex.getMessage()); } level += 1; diff --git a/demoiselle-security-jwt/pom.xml b/demoiselle-security-jwt/pom.xml index 0d8bdea..c0ccecb 100644 --- a/demoiselle-security-jwt/pom.xml +++ b/demoiselle-security-jwt/pom.xml @@ -24,6 +24,11 @@ + org.demoiselle.jee + demoiselle-configuration + + + org.bitbucket.b_c jose4j 0.5.2 diff --git a/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/Config.java b/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/Config.java new file mode 100644 index 0000000..03b797a --- /dev/null +++ b/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/Config.java @@ -0,0 +1,87 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.demoiselle.jee.security.jwt.impl; + +import java.io.Serializable; +import org.demoiselle.jee.configuration.annotation.Configuration; +import org.demoiselle.jee.core.annotation.Name; + +/** + * + * @author 70744416353 + */ +@Configuration(resource = "demoiselle-security-jwt") +public class Config implements Serializable { + + private static final long serialVersionUID = 638435989235076782L; + + @Name("jwt.type") + private String type; + + @Name("jwt.privateKey") + private String privateKey; + + @Name("jwt.publicKey") + private String publicKey; + + @Name("jwt.timetolive") + private Float tempo; + + @Name("jwt.issuer") + private String remetente; + + @Name("jwt.audience") + private String destinatario; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public Float getTempo() { + return tempo; + } + + public void setTempo(Float tempo) { + this.tempo = tempo; + } + + public String getRemetente() { + return remetente; + } + + public void setRemetente(String remetente) { + this.remetente = remetente; + } + + public String getDestinatario() { + return destinatario; + } + + public void setDestinatario(String destinatario) { + this.destinatario = destinatario; + } + +} diff --git a/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java b/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java index 6a3b03c..cb1e19b 100644 --- a/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java +++ b/demoiselle-security-jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java @@ -5,15 +5,20 @@ */ package org.demoiselle.jee.security.jwt.impl; +import java.security.PublicKey; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import org.demoiselle.jee.core.interfaces.security.DemoisellePrincipal; import org.demoiselle.jee.core.interfaces.security.Token; import org.demoiselle.jee.core.interfaces.security.TokensManager; +import org.demoiselle.jee.security.exception.DemoiselleSecurityException; import org.jose4j.jwk.JsonWebKey; import org.jose4j.jwk.RsaJsonWebKey; import org.jose4j.jwk.RsaJwkGenerator; @@ -43,14 +48,37 @@ public class TokensManagerImpl implements TokensManager { @Inject private Token token; +// @Inject +// private Config config; @Inject private DemoisellePrincipal loggedUser; - public TokensManagerImpl() throws JoseException { + //@PostConstruct + public TokensManagerImpl() { if (rsaJsonWebKey == null) { - String chave = RsaJwkGenerator.generateJwk(2048).toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE); - rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(chave); - rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); +// logger.info("Demoiselle Module - Security - JWT"); + try { + +// if (config.getType() == null) { +// throw new DemoiselleSecurityException("Escolha o tipo de autenticação, ver documentação", 500); +// } +// +// if (config.getType().equalsIgnoreCase("slave") && (config.getPublicKey() == null || config.getPublicKey().isEmpty())) { +// throw new DemoiselleSecurityException("Informe a chave pública no arquivo de configuração do projeto, ver documentação", 500); +// } else { +// rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(config.getPrivateKey()); +// } +// +// if (config.getType().equalsIgnoreCase("master") && (config.getPrivateKey() == null || config.getPrivateKey().isEmpty())) { +// throw new DemoiselleSecurityException("Informe a chave privada no arquivo de configuração do projeto, ver documentação", 500); +// } else { +// rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(config.getPublicKey()); +// } + rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk(RsaJwkGenerator.generateJwk(2048).toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE)); + rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); + } catch (JoseException ex) { + // logger.severe(ex.getMessage()); + } } } @@ -63,7 +91,6 @@ public class TokensManagerImpl implements TokensManager { .setAllowedClockSkewInSeconds(60) // allow some leeway in validating time based claims to account for clock skew .setExpectedIssuer("demoiselle") // whom the JWT needs to have been issued by .setExpectedAudience("demoiselle") // to whom the JWT is intended for - .setDecryptionKey(rsaJsonWebKey.getPrivateKey()) // decrypt with the receiver's private key .setVerificationKey(rsaJsonWebKey.getPublicKey()) .build(); // create the JwtConsumer instance JwtClaims jwtClaims = jwtConsumer.processToClaims(token.getKey()); @@ -111,7 +138,6 @@ public class TokensManagerImpl implements TokensManager { token.setKey(jws.getCompactSerialization()); token.setType("JWT"); } catch (JoseException ex) { - //ex.printStackTrace(); logger.severe(ex.getMessage()); } @@ -122,4 +148,8 @@ public class TokensManagerImpl implements TokensManager { return getUser() != null; } + @Override + public PublicKey getPublicKey() { + return rsaJsonWebKey.getPublicKey(); + } } diff --git a/demoiselle-security-jwt/src/main/resources/demoiselle.properties b/demoiselle-security-jwt/src/main/resources/demoiselle.properties deleted file mode 100644 index 4f777af..0000000 --- a/demoiselle-security-jwt/src/main/resources/demoiselle.properties +++ /dev/null @@ -1 +0,0 @@ -user-not-authenticated \ No newline at end of file diff --git a/demoiselle-security-jwt/src/main/resources/messages.properties b/demoiselle-security-jwt/src/main/resources/messages.properties deleted file mode 100644 index 65893da..0000000 --- a/demoiselle-security-jwt/src/main/resources/messages.properties +++ /dev/null @@ -1 +0,0 @@ -tipo-seguranca=basic \ No newline at end of file diff --git a/demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java b/demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java index 306c96d..d2f309e 100644 --- a/demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java +++ b/demoiselle-security-token/src/main/java/org/demoiselle/jee/security/token/impl/TokensManagerImpl.java @@ -5,6 +5,7 @@ */ package org.demoiselle.jee.security.token.impl; +import java.security.PublicKey; import static java.util.UUID.randomUUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; @@ -59,4 +60,8 @@ public class TokensManagerImpl implements TokensManager { return getUser() != null; } + @Override + public PublicKey getPublicKey() { + return null; + } } diff --git a/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredPermissionInterceptor.java b/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredPermissionInterceptor.java index 0fbfc11..f33432a 100644 --- a/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredPermissionInterceptor.java +++ b/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredPermissionInterceptor.java @@ -71,8 +71,8 @@ public class RequiredPermissionInterceptor implements Serializable { String resource = getResource(ic); String operation = getOperation(ic); - if (securityContext.isLoggedIn()) { - logger.finest(bundle.accessCheckingPermission(operation, resource)); + if (!securityContext.isLoggedIn()) { + throw new DemoiselleSecurityException(bundle.userNotAuthenticated(), UNAUTHORIZED.getStatusCode()); } if (!securityContext.hasPermission(resource, operation)) { diff --git a/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredRoleInterceptor.java b/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredRoleInterceptor.java index e0ba6ba..1758b21 100644 --- a/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredRoleInterceptor.java +++ b/demoiselle-security/src/main/java/org/demoiselle/jee/security/interceptor/RequiredRoleInterceptor.java @@ -75,6 +75,10 @@ public class RequiredRoleInterceptor implements Serializable { List roles = getRoles(ic); List userRoles = new ArrayList<>(); + + if (!securityContext.isLoggedIn()) { + throw new DemoiselleSecurityException(bundle.userNotAuthenticated(), UNAUTHORIZED.getStatusCode()); + } for (String role : roles) { if (securityContext.hasRole(role)) { -- libgit2 0.21.2