Commit b1a280739c057b2aa569350d380f7d01f1bf8eb8
1 parent
fcb6b857
Segurança
Showing
6 changed files
with
246 additions
and
0 deletions
Show diff stats
jwt/pom.xml
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | <maven.compiler.target>1.8</maven.compiler.target> |
12 | 12 | </properties> |
13 | 13 | <dependencies> |
14 | + | |
14 | 15 | <dependency> |
15 | 16 | <groupId>${project.groupId}</groupId> |
16 | 17 | <artifactId>demoiselle-core</artifactId> |
... | ... | @@ -29,5 +30,18 @@ |
29 | 30 | <version>${project.version}</version> |
30 | 31 | </dependency> |
31 | 32 | |
33 | + <dependency> | |
34 | + <groupId>org.bitbucket.b_c</groupId> | |
35 | + <artifactId>jose4j</artifactId> | |
36 | + <version>0.4.1</version> | |
37 | + </dependency> | |
38 | + | |
39 | + <dependency> | |
40 | + <groupId>com.google.code.gson</groupId> | |
41 | + <artifactId>gson</artifactId> | |
42 | + <version>2.2.2</version> | |
43 | + <scope>compile</scope> | |
44 | + </dependency> | |
45 | + | |
32 | 46 | </dependencies> |
33 | 47 | </project> | ... | ... |
jwt/src/main/java/org/demoiselle/jee/security/jwt/impl/SecurityContextImpl.java
0 → 100644
... | ... | @@ -0,0 +1,123 @@ |
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
0 → 100644
... | ... | @@ -0,0 +1,106 @@ |
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 void 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 | +} | ... | ... |