1 |
|
package org.europa.together.application; |
2 |
|
|
3 |
|
import com.nimbusds.jose.JWSAlgorithm; |
4 |
|
import com.nimbusds.jose.JWSHeader; |
5 |
|
import com.nimbusds.jose.JWSObject; |
6 |
|
import com.nimbusds.jose.JWSSigner; |
7 |
|
import com.nimbusds.jose.JWSVerifier; |
8 |
|
import com.nimbusds.jose.Payload; |
9 |
|
import com.nimbusds.jose.crypto.MACSigner; |
10 |
|
import com.nimbusds.jose.crypto.MACVerifier; |
11 |
|
import com.nimbusds.jwt.JWTClaimsSet; |
12 |
|
import com.nimbusds.jwt.SignedJWT; |
13 |
|
import java.util.Date; |
14 |
|
import java.util.List; |
15 |
|
import org.europa.together.business.ConfigurationDAO; |
16 |
|
import org.europa.together.business.JsonWebToken; |
17 |
|
import org.europa.together.business.Logger; |
18 |
|
import org.europa.together.domain.ConfigurationDO; |
19 |
|
import org.europa.together.domain.LogLevel; |
20 |
|
import org.europa.together.exceptions.DAOException; |
21 |
|
import org.europa.together.exceptions.JsonProcessingException; |
22 |
|
import org.europa.together.utils.Constraints; |
23 |
|
import org.europa.together.utils.StringUtils; |
24 |
|
import org.springframework.beans.factory.annotation.Autowired; |
25 |
|
import org.springframework.stereotype.Repository; |
26 |
|
import org.springframework.transaction.annotation.Transactional; |
27 |
|
|
28 |
|
|
29 |
|
|
30 |
|
@author |
31 |
|
|
32 |
|
@Repository |
33 |
|
@Transactional |
|
|
| 78.2% |
Uncovered Elements: 17 (78) |
Complexity: 16 |
Complexity Density: 0.26 |
|
34 |
|
public class NimbusJwt implements JsonWebToken { |
35 |
|
|
36 |
|
private static final long serialVersionUID = 16L; |
37 |
|
private static final Logger LOGGER = new LogbackLogger(NimbusJwt.class); |
38 |
|
|
39 |
|
private String sharedSecret = ""; |
40 |
|
|
41 |
|
@Autowired |
42 |
|
private ConfigurationDAO configurationDAO; |
43 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
44 |
1 |
public NimbusJwt() throws DAOException {... |
45 |
1 |
LOGGER.log("instance class", LogLevel.INFO); |
46 |
|
} |
47 |
|
|
|
|
| 75% |
Uncovered Elements: 4 (16) |
Complexity: 3 |
Complexity Density: 0.21 |
|
48 |
1 |
@Override... |
49 |
|
public String buildHMAC512SignedJws(final String jsonPayload) |
50 |
|
throws JsonProcessingException { |
51 |
1 |
String jws = ""; |
52 |
1 |
try { |
53 |
1 |
fetchSharedSecret(); |
54 |
1 |
if (!validateLengthOfSharedSecret(sharedSecret)) { |
55 |
0 |
String msg = "The length of the secret is less than 128 characters."; |
56 |
0 |
throw new JsonProcessingException(msg); |
57 |
|
} |
58 |
|
|
59 |
1 |
JWSSigner signer = new MACSigner(sharedSecret); |
60 |
1 |
JWSHeader jswHeader = new JWSHeader(JWSAlgorithm.HS512); |
61 |
|
|
62 |
1 |
Payload payload = new Payload(jsonPayload); |
63 |
|
|
64 |
1 |
JWSObject jwsObject = new JWSObject(jswHeader, payload); |
65 |
1 |
jwsObject.sign(signer); |
66 |
|
|
67 |
1 |
jws = jwsObject.serialize(); |
68 |
|
} catch (Exception ex) { |
69 |
0 |
throw new JsonProcessingException(ex.getClass().getTypeName() |
70 |
|
+ " " + ex.getMessage()); |
71 |
|
} |
72 |
1 |
return jws; |
73 |
|
} |
74 |
|
|
|
|
| 76.5% |
Uncovered Elements: 4 (17) |
Complexity: 3 |
Complexity Density: 0.2 |
|
75 |
3 |
@Override... |
76 |
|
public String buildHMAC512SignedJwt(final String issuer, final String subject, |
77 |
|
final List<String> audience) |
78 |
|
throws JsonProcessingException { |
79 |
3 |
String jwt = ""; |
80 |
3 |
try { |
81 |
3 |
fetchSharedSecret(); |
82 |
3 |
if (!validateLengthOfSharedSecret(sharedSecret)) { |
83 |
0 |
String msg = "The length of the secret is less than 128 characters."; |
84 |
0 |
throw new JsonProcessingException(msg); |
85 |
|
} |
86 |
|
|
87 |
3 |
JWSSigner signer = new MACSigner(sharedSecret); |
88 |
3 |
JWSHeader jswHeader = new JWSHeader(JWSAlgorithm.HS512); |
89 |
|
|
90 |
3 |
Date currentTime = new Date(); |
91 |
|
|
92 |
3 |
JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder() |
93 |
|
.issuer(issuer) |
94 |
|
.subject(subject) |
95 |
|
.audience(audience) |
96 |
|
.expirationTime(new Date(new Date().getTime() + 600000)) |
97 |
|
.notBeforeTime(currentTime) |
98 |
|
.issueTime(currentTime) |
99 |
|
.jwtID(StringUtils.generateUUID()) |
100 |
|
.build(); |
101 |
|
|
102 |
3 |
SignedJWT signedJWT = new SignedJWT(jswHeader, jwtClaims); |
103 |
3 |
signedJWT.sign(signer); |
104 |
3 |
jwt = signedJWT.serialize(); |
105 |
|
} catch (Exception ex) { |
106 |
0 |
throw new JsonProcessingException(ex.getClass().getTypeName() |
107 |
|
+ " " + ex.getMessage()); |
108 |
|
} |
109 |
3 |
return jwt; |
110 |
|
} |
111 |
|
|
|
|
| 71.4% |
Uncovered Elements: 4 (14) |
Complexity: 3 |
Complexity Density: 0.25 |
|
112 |
2 |
@Override... |
113 |
|
public String parseHMAC512SingedJws(final String jws) |
114 |
|
throws JsonProcessingException { |
115 |
2 |
String payload = ""; |
116 |
2 |
try { |
117 |
2 |
fetchSharedSecret(); |
118 |
|
|
119 |
2 |
JWSObject jwsObject = JWSObject.parse(jws); |
120 |
1 |
JWSVerifier verifier = new MACVerifier(sharedSecret); |
121 |
1 |
payload = jwsObject.getPayload().toString(); |
122 |
|
|
123 |
1 |
if (!jwsObject.verify(verifier)) { |
124 |
0 |
LOGGER.log("JWS is not valid.", LogLevel.ERROR); |
125 |
0 |
LOGGER.log("\t payload: " + payload, LogLevel.ERROR); |
126 |
0 |
throw new Exception("JWS is not valid. - for security reasons rejected!"); |
127 |
|
} |
128 |
|
|
129 |
|
} catch (Exception ex) { |
130 |
1 |
throw new JsonProcessingException(ex.getClass().getTypeName() |
131 |
|
+ " " + ex.getMessage()); |
132 |
|
} |
133 |
1 |
return payload; |
134 |
|
} |
135 |
|
|
|
|
| 71.4% |
Uncovered Elements: 4 (14) |
Complexity: 3 |
Complexity Density: 0.25 |
|
136 |
2 |
@Override... |
137 |
|
public String parseHMAC512SingedJwt(final String jwt) |
138 |
|
throws JsonProcessingException { |
139 |
2 |
String payload = ""; |
140 |
2 |
try { |
141 |
2 |
fetchSharedSecret(); |
142 |
|
|
143 |
2 |
SignedJWT signedJWT = SignedJWT.parse(jwt); |
144 |
1 |
JWSVerifier verifier = new MACVerifier(sharedSecret); |
145 |
1 |
payload = signedJWT.getPayload().toString(); |
146 |
|
|
147 |
1 |
if (!signedJWT.verify(verifier)) { |
148 |
0 |
LOGGER.log("JWT is not valid.", LogLevel.ERROR); |
149 |
0 |
LOGGER.log("\t payload: " + payload, LogLevel.ERROR); |
150 |
0 |
throw new Exception("JWT is not valid. - for security reasons rejected!"); |
151 |
|
} |
152 |
|
|
153 |
|
} catch (Exception ex) { |
154 |
1 |
throw new JsonProcessingException(ex.getClass().getTypeName() |
155 |
|
+ " " + ex.getMessage()); |
156 |
|
} |
157 |
1 |
return payload; |
158 |
|
} |
159 |
|
|
160 |
|
|
|
|
| 83.3% |
Uncovered Elements: 1 (6) |
Complexity: 2 |
Complexity Density: 0.5 |
|
161 |
4 |
private boolean validateLengthOfSharedSecret(final String secret) {... |
162 |
4 |
boolean success = false; |
163 |
|
|
164 |
4 |
if (secret.length() >= Constraints.INT_128) { |
165 |
4 |
success = true; |
166 |
|
} |
167 |
4 |
return success; |
168 |
|
} |
169 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
|
170 |
8 |
private void fetchSharedSecret() throws DAOException {... |
171 |
8 |
List<ConfigurationDO> configuration = configurationDAO |
172 |
|
.getAllConfigurationSetEntries("core", VERSION, "json"); |
173 |
8 |
this.sharedSecret = configuration.get(0).getValue(); |
174 |
|
|
175 |
8 |
LOGGER.log("SEC: " + configuration.toString().substring(0, 30), LogLevel.DEBUG); |
176 |
|
} |
177 |
|
|
178 |
|
} |