Commit 3de0d99cd35a589fa6c19034db340856b3b20ffa
1 parent
95260573
Segurança
Showing
11 changed files
with
474 additions
and
418 deletions
Show diff stats
basic/src/main/java/org/demoiselle/jee/security/basic/impl/SecurityContextImpl.java
| ... | ... | @@ -1,123 +0,0 @@ |
| 1 | -package org.demoiselle.jee.security.basic.impl; | |
| 2 | - | |
| 3 | -import org.demoiselle.jee.security.Token; | |
| 4 | -import javax.enterprise.context.Dependent; | |
| 5 | -import java.security.Principal; | |
| 6 | -import java.util.Map; | |
| 7 | -import java.util.Set; | |
| 8 | -import javax.inject.Inject; | |
| 9 | -import org.demoiselle.jee.core.util.ResourceBundle; | |
| 10 | -import org.demoiselle.jee.security.interfaces.SecurityContext; | |
| 11 | -import org.demoiselle.jee.security.exception.NotLoggedInException; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * <p> | |
| 15 | - * This is the default implementation of {@link SecurityContext} interface. | |
| 16 | - * </p> | |
| 17 | - * | |
| 18 | - * @author SERPRO | |
| 19 | - */ | |
| 20 | -@Dependent | |
| 21 | -public class SecurityContextImpl implements SecurityContext { | |
| 22 | - | |
| 23 | - private static final long serialVersionUID = 1L; | |
| 24 | - | |
| 25 | - @Inject | |
| 26 | - private TokensManager tm; | |
| 27 | - | |
| 28 | - @Inject | |
| 29 | - private Token token; | |
| 30 | - | |
| 31 | - @Inject | |
| 32 | - private ResourceBundle bundle; | |
| 33 | - | |
| 34 | - /** | |
| 35 | - * @see org.demoiselle.security.SecurityContext#hasPermission(String, | |
| 36 | - * String) | |
| 37 | - */ | |
| 38 | - @Override | |
| 39 | - public boolean hasPermission(String resource, String operation) { | |
| 40 | - boolean result = true; | |
| 41 | - | |
| 42 | - return result; | |
| 43 | - } | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * @see org.demoiselle.security.SecurityContext#hasRole(String) | |
| 47 | - */ | |
| 48 | - @Override | |
| 49 | - public boolean hasRole(String role) { | |
| 50 | - boolean result = true; | |
| 51 | - | |
| 52 | - return result; | |
| 53 | - } | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * @see org.demoiselle.security.SecurityContext#isLoggedIn() | |
| 57 | - */ | |
| 58 | - @Override | |
| 59 | - public boolean isLoggedIn() { | |
| 60 | - return getUser() != null; | |
| 61 | - } | |
| 62 | - | |
| 63 | - /** | |
| 64 | - * @see org.demoiselle.security.SecurityContext#getUser() | |
| 65 | - */ | |
| 66 | - @Override | |
| 67 | - public Principal getUser() { | |
| 68 | - if (token.getKey() != null && !token.getKey().isEmpty()) { | |
| 69 | - return tm.getUser(token.getKey()); | |
| 70 | - } | |
| 71 | - return token.getPrincipal(); | |
| 72 | - } | |
| 73 | - | |
| 74 | - public void checkLoggedIn() throws NotLoggedInException { | |
| 75 | - if (!isLoggedIn()) { | |
| 76 | - throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 77 | - } | |
| 78 | - } | |
| 79 | - | |
| 80 | - @Override | |
| 81 | - public void setRoles(Set<String> roles) { | |
| 82 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 83 | - } | |
| 84 | - | |
| 85 | - @Override | |
| 86 | - public void setPermission(Map<String, String> permissions) { | |
| 87 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 88 | - } | |
| 89 | - | |
| 90 | - @Override | |
| 91 | - public Set<String> getResources(String operation) { | |
| 92 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 93 | - } | |
| 94 | - | |
| 95 | - @Override | |
| 96 | - public Set<String> getOperations(String resources) { | |
| 97 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 98 | - } | |
| 99 | - | |
| 100 | - @Override | |
| 101 | - public void setUser(Principal principal) { | |
| 102 | - token.setKey(tm.getToken(principal)); | |
| 103 | - token.setPrincipal(principal); | |
| 104 | - } | |
| 105 | - | |
| 106 | - @Override | |
| 107 | - public String getToken() { | |
| 108 | - if (token.getKey() != null && token.getKey().isEmpty()) { | |
| 109 | - token.setKey(tm.getToken(token.getPrincipal())); | |
| 110 | - } | |
| 111 | - return token.getKey(); | |
| 112 | - } | |
| 113 | - | |
| 114 | - @Override | |
| 115 | - public void setToken(String chave) { | |
| 116 | - token.setPrincipal(tm.getUser(chave)); | |
| 117 | - if (token.getPrincipal() == null) { | |
| 118 | - throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 119 | - } | |
| 120 | - token.setKey(chave); | |
| 121 | - } | |
| 122 | - | |
| 123 | -} |
basic/src/main/java/org/demoiselle/jee/security/basic/impl/TokensManager.java
| ... | ... | @@ -1,56 +0,0 @@ |
| 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.basic.impl; | |
| 7 | - | |
| 8 | -import java.security.Principal; | |
| 9 | -import java.util.Map; | |
| 10 | -import java.util.UUID; | |
| 11 | -import java.util.concurrent.ConcurrentHashMap; | |
| 12 | -import java.util.logging.Logger; | |
| 13 | -import javax.enterprise.context.ApplicationScoped; | |
| 14 | -import javax.enterprise.context.RequestScoped; | |
| 15 | -import javax.inject.Inject; | |
| 16 | - | |
| 17 | -/** | |
| 18 | - * | |
| 19 | - * @author 70744416353 | |
| 20 | - */ | |
| 21 | -@ApplicationScoped | |
| 22 | -public class TokensManager { | |
| 23 | - | |
| 24 | - private static ConcurrentHashMap<String, Principal> repo = new ConcurrentHashMap<>(); | |
| 25 | - | |
| 26 | - @Inject | |
| 27 | - private Logger logger; | |
| 28 | - | |
| 29 | - public Principal getUser(String token) { | |
| 30 | - return repo.get(token); | |
| 31 | - } | |
| 32 | - | |
| 33 | - public String getToken(Principal user) { | |
| 34 | - String value = null; | |
| 35 | - if (!repo.containsValue(user)) { | |
| 36 | - value = UUID.randomUUID().toString(); | |
| 37 | - repo.put(value, user); | |
| 38 | - } else { | |
| 39 | - for (Map.Entry<String, Principal> entry : repo.entrySet()) { | |
| 40 | - if (entry.getValue().equals(user)) { | |
| 41 | - return entry.getKey(); | |
| 42 | - } | |
| 43 | - } | |
| 44 | - } | |
| 45 | - return value; | |
| 46 | - } | |
| 47 | - | |
| 48 | - public void remove(String token) { | |
| 49 | - repo.remove(token); | |
| 50 | - } | |
| 51 | - | |
| 52 | - public boolean validate(String token) { | |
| 53 | - return repo.containsKey(token); | |
| 54 | - } | |
| 55 | - | |
| 56 | -} |
basic/src/main/java/org/demoiselle/jee/security/basic/impl/TokensManagerImpl.java
0 → 100644
| ... | ... | @@ -0,0 +1,51 @@ |
| 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.basic.impl; | |
| 7 | + | |
| 8 | +import java.security.Principal; | |
| 9 | +import java.util.Map; | |
| 10 | +import java.util.UUID; | |
| 11 | +import java.util.concurrent.ConcurrentHashMap; | |
| 12 | +import java.util.logging.Logger; | |
| 13 | +import javax.enterprise.context.Dependent; | |
| 14 | +import javax.inject.Inject; | |
| 15 | +import org.demoiselle.jee.security.Token; | |
| 16 | +import org.demoiselle.jee.security.interfaces.TokensManager; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * | |
| 20 | + * @author 70744416353 | |
| 21 | + */ | |
| 22 | +@Dependent | |
| 23 | +public class TokensManagerImpl implements TokensManager { | |
| 24 | + | |
| 25 | + private static ConcurrentHashMap<String, Principal> repo = new ConcurrentHashMap<>(); | |
| 26 | + | |
| 27 | + @Inject | |
| 28 | + private Logger logger; | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + public Principal getUser(Token token) { | |
| 32 | + return repo.get(token.getKey()); | |
| 33 | + } | |
| 34 | + | |
| 35 | + @Override | |
| 36 | + public Token getToken(Principal user) { | |
| 37 | + String value = null; | |
| 38 | + if (!repo.containsValue(user)) { | |
| 39 | + value = UUID.randomUUID().toString(); | |
| 40 | + repo.put(value, user); | |
| 41 | + } else { | |
| 42 | + for (Map.Entry<String, Principal> entry : repo.entrySet()) { | |
| 43 | + if (entry.getValue().equals(user)) { | |
| 44 | + return entry.getKey(); | |
| 45 | + } | |
| 46 | + } | |
| 47 | + } | |
| 48 | + return value; | |
| 49 | + } | |
| 50 | + | |
| 51 | +} | ... | ... |
jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/SecurityContextImpl.java
| ... | ... | @@ -1,123 +0,0 @@ |
| 1 | -package org.demoiselle.jee.security.jwt.impl; | |
| 2 | - | |
| 3 | -import org.demoiselle.jee.security.Token; | |
| 4 | -import javax.enterprise.context.Dependent; | |
| 5 | -import java.security.Principal; | |
| 6 | -import java.util.Map; | |
| 7 | -import java.util.Set; | |
| 8 | -import javax.inject.Inject; | |
| 9 | -import org.demoiselle.jee.core.util.ResourceBundle; | |
| 10 | -import org.demoiselle.jee.security.interfaces.SecurityContext; | |
| 11 | -import org.demoiselle.jee.security.exception.NotLoggedInException; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * <p> | |
| 15 | - * This is the default implementation of {@link SecurityContext} interface. | |
| 16 | - * </p> | |
| 17 | - * | |
| 18 | - * @author SERPRO | |
| 19 | - */ | |
| 20 | -@Dependent | |
| 21 | -public class SecurityContextImpl implements SecurityContext { | |
| 22 | - | |
| 23 | - private static final long serialVersionUID = 1L; | |
| 24 | - | |
| 25 | - @Inject | |
| 26 | - private TokensManager tm; | |
| 27 | - | |
| 28 | - @Inject | |
| 29 | - private Token token; | |
| 30 | - | |
| 31 | - @Inject | |
| 32 | - private ResourceBundle bundle; | |
| 33 | - | |
| 34 | - /** | |
| 35 | - * @see org.demoiselle.security.SecurityContext#hasPermission(String, | |
| 36 | - * String) | |
| 37 | - */ | |
| 38 | - @Override | |
| 39 | - public boolean hasPermission(String resource, String operation) { | |
| 40 | - boolean result = true; | |
| 41 | - | |
| 42 | - return result; | |
| 43 | - } | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * @see org.demoiselle.security.SecurityContext#hasRole(String) | |
| 47 | - */ | |
| 48 | - @Override | |
| 49 | - public boolean hasRole(String role) { | |
| 50 | - boolean result = true; | |
| 51 | - | |
| 52 | - return result; | |
| 53 | - } | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * @see org.demoiselle.security.SecurityContext#isLoggedIn() | |
| 57 | - */ | |
| 58 | - @Override | |
| 59 | - public boolean isLoggedIn() { | |
| 60 | - return getUser() != null; | |
| 61 | - } | |
| 62 | - | |
| 63 | - /** | |
| 64 | - * @see org.demoiselle.security.SecurityContext#getUser() | |
| 65 | - */ | |
| 66 | - @Override | |
| 67 | - public Principal getUser() { | |
| 68 | - if (token.getKey() != null && !token.getKey().isEmpty()) { | |
| 69 | - return tm.getUser(token.getKey()); | |
| 70 | - } | |
| 71 | - return token.getPrincipal(); | |
| 72 | - } | |
| 73 | - | |
| 74 | - public void checkLoggedIn() throws NotLoggedInException { | |
| 75 | - if (!isLoggedIn()) { | |
| 76 | - throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 77 | - } | |
| 78 | - } | |
| 79 | - | |
| 80 | - @Override | |
| 81 | - public void setRoles(Set<String> roles) { | |
| 82 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 83 | - } | |
| 84 | - | |
| 85 | - @Override | |
| 86 | - public void setPermission(Map<String, String> permissions) { | |
| 87 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 88 | - } | |
| 89 | - | |
| 90 | - @Override | |
| 91 | - public Set<String> getResources(String operation) { | |
| 92 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 93 | - } | |
| 94 | - | |
| 95 | - @Override | |
| 96 | - public Set<String> getOperations(String resources) { | |
| 97 | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 98 | - } | |
| 99 | - | |
| 100 | - @Override | |
| 101 | - public void setUser(Principal principal) { | |
| 102 | - token.setKey(tm.getToken(principal)); | |
| 103 | - token.setPrincipal(principal); | |
| 104 | - } | |
| 105 | - | |
| 106 | - @Override | |
| 107 | - public String getToken() { | |
| 108 | - if (token.getKey() != null && token.getKey().isEmpty()) { | |
| 109 | - token.setKey(tm.getToken(token.getPrincipal())); | |
| 110 | - } | |
| 111 | - return token.getKey(); | |
| 112 | - } | |
| 113 | - | |
| 114 | - @Override | |
| 115 | - public void setToken(String chave) { | |
| 116 | - token.setPrincipal(tm.getUser(chave)); | |
| 117 | - if (token.getPrincipal() == null) { | |
| 118 | - throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 119 | - } | |
| 120 | - token.setKey(chave); | |
| 121 | - } | |
| 122 | - | |
| 123 | -} |
jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManager.java
| ... | ... | @@ -1,106 +0,0 @@ |
| 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 com.google.gson.Gson; | |
| 9 | -import java.security.Key; | |
| 10 | -import java.security.Principal; | |
| 11 | -import java.util.Map; | |
| 12 | -import java.util.UUID; | |
| 13 | -import java.util.logging.Level; | |
| 14 | -import java.util.logging.Logger; | |
| 15 | -import javax.annotation.PostConstruct; | |
| 16 | -import javax.enterprise.context.RequestScoped; | |
| 17 | -import javax.inject.Inject; | |
| 18 | -import javax.servlet.http.HttpServletRequest; | |
| 19 | -import javax.ws.rs.container.PreMatching; | |
| 20 | -import org.jose4j.jwk.RsaJsonWebKey; | |
| 21 | -import org.jose4j.jwk.RsaJwkGenerator; | |
| 22 | -import org.jose4j.jws.AlgorithmIdentifiers; | |
| 23 | -import org.jose4j.jws.JsonWebSignature; | |
| 24 | -import org.jose4j.jwt.JwtClaims; | |
| 25 | -import org.jose4j.jwt.consumer.InvalidJwtException; | |
| 26 | -import org.jose4j.jwt.consumer.JwtConsumer; | |
| 27 | -import org.jose4j.jwt.consumer.JwtConsumerBuilder; | |
| 28 | -import org.jose4j.lang.JoseException; | |
| 29 | - | |
| 30 | -/** | |
| 31 | - * | |
| 32 | - * @author 70744416353 | |
| 33 | - */ | |
| 34 | -@RequestScoped | |
| 35 | -public class TokensManager { | |
| 36 | - | |
| 37 | - @Inject | |
| 38 | - private HttpServletRequest httpRequest; | |
| 39 | - | |
| 40 | - private RsaJsonWebKey rsaJsonWebKey; | |
| 41 | - | |
| 42 | - @Inject | |
| 43 | - private Logger logger; | |
| 44 | - | |
| 45 | - public TokensManager() throws JoseException { | |
| 46 | - RsaJsonWebKey chave = RsaJwkGenerator.generateJwk(2048); | |
| 47 | - logger.info("Se você quiser usar sua app em cluster, coloque o parametro jwt.key no app.properties e reinicie a aplicacao"); | |
| 48 | - logger.log(Level.INFO, "jwt.key={0}", chave); | |
| 49 | - 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 "); | |
| 50 | - rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk((Key) chave); | |
| 51 | - rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | |
| 52 | - } | |
| 53 | - | |
| 54 | - public Principal getUser(String jwt) { | |
| 55 | - Principal usuario = null; | |
| 56 | - if (jwt != null && !jwt.isEmpty()) { | |
| 57 | - JwtConsumer jwtConsumer = new JwtConsumerBuilder() | |
| 58 | - .setRequireExpirationTime() // the JWT must have an expiration time | |
| 59 | - .setAllowedClockSkewInSeconds(60) // allow some leeway in validating time based claims to account for clock skew | |
| 60 | - .setExpectedIssuer("demoiselle") // whom the JWT needs to have been issued by | |
| 61 | - .setExpectedAudience("demoiselle") // to whom the JWT is intended for | |
| 62 | - .setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key | |
| 63 | - .build(); // create the JwtConsumer instance | |
| 64 | - | |
| 65 | - try { | |
| 66 | - JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt); | |
| 67 | - usuario = new Gson().fromJson((String) jwtClaims.getClaimValue("user"), Principal.class); | |
| 68 | - | |
| 69 | - String ip = httpRequest.getRemoteAddr(); | |
| 70 | - if (!ip.equalsIgnoreCase((String) jwtClaims.getClaimValue("ip"))) { | |
| 71 | - usuario = null; | |
| 72 | - } | |
| 73 | - } catch (InvalidJwtException e) { | |
| 74 | - //Logger.getLogger(TokenRepository.class.getName()).log(Level.SEVERE, null, e); | |
| 75 | - } | |
| 76 | - } | |
| 77 | - return usuario; | |
| 78 | - } | |
| 79 | - | |
| 80 | - public String getToken(Principal user) { | |
| 81 | - try { | |
| 82 | - JwtClaims claims = new JwtClaims(); | |
| 83 | - claims.setIssuer("demoiselle"); | |
| 84 | - claims.setAudience("demoiselle"); | |
| 85 | - claims.setExpirationTimeMinutesInTheFuture(720); | |
| 86 | - claims.setGeneratedJwtId(); | |
| 87 | - claims.setIssuedAtToNow(); | |
| 88 | - claims.setNotBeforeMinutesInThePast(1); | |
| 89 | - | |
| 90 | - claims.setClaim("ip", httpRequest.getRemoteAddr()); | |
| 91 | - claims.setClaim("user", new Gson().toJson(user)); | |
| 92 | - | |
| 93 | - JsonWebSignature jws = new JsonWebSignature(); | |
| 94 | - jws.setPayload(claims.toJson()); | |
| 95 | - jws.setKey(rsaJsonWebKey.getPrivateKey()); | |
| 96 | - jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId()); | |
| 97 | - jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); | |
| 98 | - return jws.getCompactSerialization(); | |
| 99 | - } catch (JoseException ex) { | |
| 100 | - logger.severe(ex.getMessage()); | |
| 101 | - } | |
| 102 | - return null; | |
| 103 | - | |
| 104 | - } | |
| 105 | - | |
| 106 | -} |
jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/TokensManagerImpl.java
0 → 100644
| ... | ... | @@ -0,0 +1,105 @@ |
| 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 com.google.gson.Gson; | |
| 9 | +import java.security.Key; | |
| 10 | +import java.security.Principal; | |
| 11 | +import java.util.logging.Level; | |
| 12 | +import java.util.logging.Logger; | |
| 13 | +import javax.enterprise.context.Dependent; | |
| 14 | +import javax.inject.Inject; | |
| 15 | +import javax.servlet.http.HttpServletRequest; | |
| 16 | +import org.demoiselle.jee.security.interfaces.TokensManager; | |
| 17 | +import org.jose4j.jwk.RsaJsonWebKey; | |
| 18 | +import org.jose4j.jwk.RsaJwkGenerator; | |
| 19 | +import org.jose4j.jws.AlgorithmIdentifiers; | |
| 20 | +import org.jose4j.jws.JsonWebSignature; | |
| 21 | +import org.jose4j.jwt.JwtClaims; | |
| 22 | +import org.jose4j.jwt.consumer.InvalidJwtException; | |
| 23 | +import org.jose4j.jwt.consumer.JwtConsumer; | |
| 24 | +import org.jose4j.jwt.consumer.JwtConsumerBuilder; | |
| 25 | +import org.jose4j.lang.JoseException; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * | |
| 29 | + * @author 70744416353 | |
| 30 | + */ | |
| 31 | +@Dependent | |
| 32 | +public class TokensManagerImpl implements TokensManager { | |
| 33 | + | |
| 34 | + @Inject | |
| 35 | + private HttpServletRequest httpRequest; | |
| 36 | + | |
| 37 | + private RsaJsonWebKey rsaJsonWebKey; | |
| 38 | + | |
| 39 | + @Inject | |
| 40 | + private Logger logger; | |
| 41 | + | |
| 42 | + public TokensManagerImpl() throws JoseException { | |
| 43 | + RsaJsonWebKey chave = RsaJwkGenerator.generateJwk(2048); | |
| 44 | + logger.info("Se você quiser usar sua app em cluster, coloque o parametro jwt.key no app.properties e reinicie a aplicacao"); | |
| 45 | + logger.log(Level.INFO, "jwt.key={0}", chave); | |
| 46 | + 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 "); | |
| 47 | + rsaJsonWebKey = (RsaJsonWebKey) RsaJsonWebKey.Factory.newPublicJwk((Key) chave); | |
| 48 | + rsaJsonWebKey.setKeyId("demoiselle-security-jwt"); | |
| 49 | + } | |
| 50 | + | |
| 51 | + @Override | |
| 52 | + public Principal getUser(String jwt) { | |
| 53 | + Principal usuario = null; | |
| 54 | + if (jwt != null && !jwt.isEmpty()) { | |
| 55 | + JwtConsumer jwtConsumer = new JwtConsumerBuilder() | |
| 56 | + .setRequireExpirationTime() // the JWT must have an expiration time | |
| 57 | + .setAllowedClockSkewInSeconds(60) // allow some leeway in validating time based claims to account for clock skew | |
| 58 | + .setExpectedIssuer("demoiselle") // whom the JWT needs to have been issued by | |
| 59 | + .setExpectedAudience("demoiselle") // to whom the JWT is intended for | |
| 60 | + .setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key | |
| 61 | + .build(); // create the JwtConsumer instance | |
| 62 | + | |
| 63 | + try { | |
| 64 | + JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt); | |
| 65 | + usuario = new Gson().fromJson((String) jwtClaims.getClaimValue("user"), Principal.class); | |
| 66 | + | |
| 67 | + String ip = httpRequest.getRemoteAddr(); | |
| 68 | + if (!ip.equalsIgnoreCase((String) jwtClaims.getClaimValue("ip"))) { | |
| 69 | + usuario = null; | |
| 70 | + } | |
| 71 | + } catch (InvalidJwtException e) { | |
| 72 | + //Logger.getLogger(TokenRepository.class.getName()).log(Level.SEVERE, null, e); | |
| 73 | + } | |
| 74 | + } | |
| 75 | + return usuario; | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 79 | + public String getToken(Principal user) { | |
| 80 | + try { | |
| 81 | + JwtClaims claims = new JwtClaims(); | |
| 82 | + claims.setIssuer("demoiselle"); | |
| 83 | + claims.setAudience("demoiselle"); | |
| 84 | + claims.setExpirationTimeMinutesInTheFuture(720); | |
| 85 | + claims.setGeneratedJwtId(); | |
| 86 | + claims.setIssuedAtToNow(); | |
| 87 | + claims.setNotBeforeMinutesInThePast(1); | |
| 88 | + | |
| 89 | + claims.setClaim("ip", httpRequest.getRemoteAddr()); | |
| 90 | + claims.setClaim("user", new Gson().toJson(user)); | |
| 91 | + | |
| 92 | + JsonWebSignature jws = new JsonWebSignature(); | |
| 93 | + jws.setPayload(claims.toJson()); | |
| 94 | + jws.setKey(rsaJsonWebKey.getPrivateKey()); | |
| 95 | + jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId()); | |
| 96 | + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); | |
| 97 | + return jws.getCompactSerialization(); | |
| 98 | + } catch (JoseException ex) { | |
| 99 | + logger.severe(ex.getMessage()); | |
| 100 | + } | |
| 101 | + return null; | |
| 102 | + | |
| 103 | + } | |
| 104 | + | |
| 105 | +} | ... | ... |
security/src/main/java/org/demoiselle/jee/security/LoggedUser.java
0 → 100644
| ... | ... | @@ -0,0 +1,67 @@ |
| 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; | |
| 7 | + | |
| 8 | +import java.io.Serializable; | |
| 9 | +import java.security.Principal; | |
| 10 | +import java.util.List; | |
| 11 | +import java.util.Map; | |
| 12 | +import javax.enterprise.context.RequestScoped; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * | |
| 16 | + * @author 70744416353 | |
| 17 | + */ | |
| 18 | +@RequestScoped | |
| 19 | +public class LoggedUser { | |
| 20 | + | |
| 21 | + private String id; | |
| 22 | + private String username; | |
| 23 | + private String email; | |
| 24 | + private Map<String, String> premissions; | |
| 25 | + private List<String> roles; | |
| 26 | + | |
| 27 | + public String getId() { | |
| 28 | + return id; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public void setId(String id) { | |
| 32 | + this.id = id; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public String getUsername() { | |
| 36 | + return username; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public void setUsername(String username) { | |
| 40 | + this.username = username; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public String getEmail() { | |
| 44 | + return email; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public void setEmail(String email) { | |
| 48 | + this.email = email; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public Map<String, String> getPremissions() { | |
| 52 | + return premissions; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public void setPremissions(Map<String, String> premissions) { | |
| 56 | + this.premissions = premissions; | |
| 57 | + } | |
| 58 | + | |
| 59 | + public List<String> getRoles() { | |
| 60 | + return roles; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public void setRoles(List<String> roles) { | |
| 64 | + this.roles = roles; | |
| 65 | + } | |
| 66 | + | |
| 67 | +} | ... | ... |
security/src/main/java/org/demoiselle/jee/security/Token.java
| ... | ... | @@ -5,7 +5,6 @@ |
| 5 | 5 | */ |
| 6 | 6 | package org.demoiselle.jee.security; |
| 7 | 7 | |
| 8 | -import java.security.Principal; | |
| 9 | 8 | import javax.enterprise.context.RequestScoped; |
| 10 | 9 | |
| 11 | 10 | /** |
| ... | ... | @@ -15,17 +14,8 @@ import javax.enterprise.context.RequestScoped; |
| 15 | 14 | @RequestScoped |
| 16 | 15 | public class Token { |
| 17 | 16 | |
| 18 | - private Principal principal; | |
| 19 | 17 | private String key; |
| 20 | 18 | |
| 21 | - public Principal getPrincipal() { | |
| 22 | - return principal; | |
| 23 | - } | |
| 24 | - | |
| 25 | - public void setPrincipal(Principal principal) { | |
| 26 | - this.principal = principal; | |
| 27 | - } | |
| 28 | - | |
| 29 | 19 | public String getKey() { |
| 30 | 20 | return key; |
| 31 | 21 | } | ... | ... |
security/src/main/java/org/demoiselle/jee/security/impl/SecurityContextImpl.java
0 → 100644
| ... | ... | @@ -0,0 +1,128 @@ |
| 1 | +package org.demoiselle.jee.security.impl; | |
| 2 | + | |
| 3 | +import org.demoiselle.jee.security.Token; | |
| 4 | +import javax.enterprise.context.Dependent; | |
| 5 | +import java.security.Principal; | |
| 6 | +import java.util.Map; | |
| 7 | +import java.util.Set; | |
| 8 | +import javax.inject.Inject; | |
| 9 | +import org.demoiselle.jee.core.util.ResourceBundle; | |
| 10 | +import org.demoiselle.jee.security.LoggedUser; | |
| 11 | +import org.demoiselle.jee.security.interfaces.SecurityContext; | |
| 12 | +import org.demoiselle.jee.security.exception.NotLoggedInException; | |
| 13 | +import org.demoiselle.jee.security.interfaces.TokensManager; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * <p> | |
| 17 | + * This is the default implementation of {@link SecurityContext} interface. | |
| 18 | + * </p> | |
| 19 | + * | |
| 20 | + * @author SERPRO | |
| 21 | + */ | |
| 22 | +@Dependent | |
| 23 | +public class SecurityContextImpl implements SecurityContext { | |
| 24 | + | |
| 25 | + private static final long serialVersionUID = 1L; | |
| 26 | + | |
| 27 | + @Inject | |
| 28 | + private TokensManager tm; | |
| 29 | + | |
| 30 | + @Inject | |
| 31 | + private Token token; | |
| 32 | + | |
| 33 | + @Inject | |
| 34 | + private LoggedUser loggedUser; | |
| 35 | + | |
| 36 | + @Inject | |
| 37 | + private ResourceBundle bundle; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * @see org.demoiselle.security.SecurityContext#hasPermission(String, | |
| 41 | + * String) | |
| 42 | + */ | |
| 43 | + @Override | |
| 44 | + public boolean hasPermission(String resource, String operation) { | |
| 45 | + boolean result = true; | |
| 46 | + | |
| 47 | + return result; | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * @see org.demoiselle.security.SecurityContext#hasRole(String) | |
| 52 | + */ | |
| 53 | + @Override | |
| 54 | + public boolean hasRole(String role) { | |
| 55 | + boolean result = true; | |
| 56 | + | |
| 57 | + return result; | |
| 58 | + } | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * @see org.demoiselle.security.SecurityContext#isLoggedIn() | |
| 62 | + */ | |
| 63 | + @Override | |
| 64 | + public boolean isLoggedIn() { | |
| 65 | + return getUser() != null; | |
| 66 | + } | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * @see org.demoiselle.security.SecurityContext#getUser() | |
| 70 | + */ | |
| 71 | + @Override | |
| 72 | + public Principal getUser() { | |
| 73 | +// if (token.getKey() != null && !token.getKey().isEmpty()) { | |
| 74 | +// return tm.getUser(token.getKey()); | |
| 75 | +// } | |
| 76 | + return null;//token.getPrincipal(); | |
| 77 | + } | |
| 78 | + | |
| 79 | + public void checkLoggedIn() throws NotLoggedInException { | |
| 80 | + if (!isLoggedIn()) { | |
| 81 | + throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 82 | + } | |
| 83 | + } | |
| 84 | + | |
| 85 | + @Override | |
| 86 | + public void setRoles(Set<String> roles) { | |
| 87 | + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 88 | + } | |
| 89 | + | |
| 90 | + @Override | |
| 91 | + public void setPermission(Map<String, String> permissions) { | |
| 92 | + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 93 | + } | |
| 94 | + | |
| 95 | + @Override | |
| 96 | + public Set<String> getResources(String operation) { | |
| 97 | + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 98 | + } | |
| 99 | + | |
| 100 | + @Override | |
| 101 | + public Set<String> getOperations(String resources) { | |
| 102 | + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. | |
| 103 | + } | |
| 104 | + | |
| 105 | + @Override | |
| 106 | + public void setUser(Principal principal) { | |
| 107 | +// token.setKey(tm.getToken(principal)); | |
| 108 | +// token.setPrincipal(principal); | |
| 109 | + } | |
| 110 | + | |
| 111 | + @Override | |
| 112 | + public String getToken() { | |
| 113 | +// if (token.getKey() != null && token.getKey().isEmpty()) { | |
| 114 | +// token.setKey(tm.getToken(token.getPrincipal())); | |
| 115 | +// } | |
| 116 | + return token.getKey(); | |
| 117 | + } | |
| 118 | + | |
| 119 | + @Override | |
| 120 | + public void setToken(String chave) { | |
| 121 | +// token.setPrincipal(tm.getUser(chave)); | |
| 122 | +// if (token.getPrincipal() == null) { | |
| 123 | +// throw new NotLoggedInException(bundle.getString("user-not-authenticated")); | |
| 124 | +// } | |
| 125 | + token.setKey(chave); | |
| 126 | + } | |
| 127 | + | |
| 128 | +} | ... | ... |
security/src/main/java/org/demoiselle/jee/security/interfaces/LoggedUser.java
0 → 100644
| ... | ... | @@ -0,0 +1,66 @@ |
| 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 org.demoiselle.jee.security.interfaces; | |
| 38 | + | |
| 39 | +import java.io.Serializable; | |
| 40 | +import java.util.List; | |
| 41 | +import java.util.Map; | |
| 42 | +import javax.enterprise.context.RequestScoped; | |
| 43 | + | |
| 44 | +/** | |
| 45 | + * <p> | |
| 46 | + * Structure used to handle both authentication and authorizations mechanisms. | |
| 47 | + * </p> | |
| 48 | + * | |
| 49 | + * @author SERPRO | |
| 50 | + */ | |
| 51 | +@RequestScoped | |
| 52 | +public interface LoggedUser extends Serializable { | |
| 53 | + | |
| 54 | + public String getId(); | |
| 55 | + | |
| 56 | + public void setId(String id); | |
| 57 | + | |
| 58 | + public Map<String, String> getPermissions(); | |
| 59 | + | |
| 60 | + public void setPermissions(Map<String, String> premissions); | |
| 61 | + | |
| 62 | + public List<String> getRoles(); | |
| 63 | + | |
| 64 | + public void setRoles(List<String> roles); | |
| 65 | + | |
| 66 | +} | ... | ... |
security/src/main/java/org/demoiselle/jee/security/interfaces/TokensManager.java
0 → 100644
| ... | ... | @@ -0,0 +1,57 @@ |
| 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 org.demoiselle.jee.security.interfaces; | |
| 38 | + | |
| 39 | +import java.io.Serializable; | |
| 40 | +import java.security.Principal; | |
| 41 | +import org.demoiselle.jee.security.LoggedUser; | |
| 42 | +import org.demoiselle.jee.security.Token; | |
| 43 | + | |
| 44 | +/** | |
| 45 | + * <p> | |
| 46 | + * Structure used to handle both authentication and authorizations mechanisms. | |
| 47 | + * </p> | |
| 48 | + * | |
| 49 | + * @author SERPRO | |
| 50 | + */ | |
| 51 | +public interface TokensManager extends Serializable { | |
| 52 | + | |
| 53 | + public LoggedUser getUser(Token token); | |
| 54 | + | |
| 55 | + public String create(LoggedUser user); | |
| 56 | + | |
| 57 | +} | ... | ... |