Skip to content

Commit ef15bb4

Browse files
Remove jaxb dependencies from production code
These dependencies were introduced for Java11 compatibility. By switching to the Java8 Base64 implementation they can be eliminated. There is still a test-scoped dependency in the jersey module, that will not be removed.
1 parent 8758ff8 commit ef15bb4

File tree

4 files changed

+119
-130
lines changed

4 files changed

+119
-130
lines changed

cf-java-logging-support-servlet/pom.xml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,6 @@
1818
</properties>
1919

2020
<dependencies>
21-
<dependency>
22-
<groupId>javax.xml.bind</groupId>
23-
<artifactId>jaxb-api</artifactId>
24-
<version>2.3.0</version>
25-
</dependency>
26-
<dependency>
27-
<groupId>org.glassfish.jaxb</groupId>
28-
<artifactId>jaxb-runtime</artifactId>
29-
<version>2.3.0</version>
30-
<scope>runtime</scope>
31-
</dependency>
3221
<!-- servlet api -->
3322
<dependency>
3423
<groupId>javax.servlet</groupId>

cf-java-logging-support-servlet/src/main/java/com/sap/hcp/cf/logging/servlet/dynlog/DynLogEnvironment.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,11 @@ public DynLogEnvironment() {
3030
LOGGER.info("The header key used to retrieve the dynamic log level token has been set to the default value: {}",
3131
dynLogHeaderKey);
3232
}
33-
PublicKeyReader publicKeyReader = new PublicKeyReader();
3433

3534
RSAPublicKey tempKey = null;
3635
try {
37-
tempKey = publicKeyReader.readPublicKey(environment);
38-
} catch (NoSuchAlgorithmException e) {
39-
LOGGER.error("Could not read RSAPublicKey from environment", e);
40-
} catch (InvalidKeySpecException e) {
41-
LOGGER.error("Could not read RSAPublicKey from environment", e);
42-
} catch (IOException e) {
36+
tempKey = PublicKeyReader.readPublicKey(environment);
37+
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) {
4338
LOGGER.error("Could not read RSAPublicKey from environment", e);
4439
} finally {
4540
rsaPublicKey = tempKey;

cf-java-logging-support-servlet/src/main/java/com/sap/hcp/cf/logging/servlet/dynlog/PublicKeyReader.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
import java.security.interfaces.RSAPublicKey;
77
import java.security.spec.InvalidKeySpecException;
88
import java.security.spec.X509EncodedKeySpec;
9-
10-
import javax.xml.bind.DatatypeConverter;
9+
import java.util.Base64;
1110

1211
import org.slf4j.Logger;
1312
import org.slf4j.LoggerFactory;
@@ -18,8 +17,11 @@ public class PublicKeyReader {
1817

1918
private final static Logger LOGGER = LoggerFactory.getLogger(PublicKeyReader.class);
2019

21-
public RSAPublicKey readPublicKey(Environment environment) throws IOException, NoSuchAlgorithmException,
22-
InvalidKeySpecException {
20+
private PublicKeyReader() {
21+
}
22+
23+
public static RSAPublicKey readPublicKey(Environment environment) throws IOException, NoSuchAlgorithmException,
24+
InvalidKeySpecException {
2325

2426
String pemKey = environment.getVariable("DYN_LOG_LEVEL_KEY");
2527

@@ -32,14 +34,11 @@ public RSAPublicKey readPublicKey(Environment environment) throws IOException, N
3234
pemKey = pemKey.replace("\r", "");
3335
pemKey = pemKey.replace("-----END PUBLIC KEY-----", "");
3436

35-
byte[] pubKeyBytes = DatatypeConverter.parseBase64Binary(pemKey);
37+
byte[] pubKeyBytes = Base64.getDecoder().decode(pemKey);
3638

3739
X509EncodedKeySpec spec = new X509EncodedKeySpec(pubKeyBytes);
3840
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
3941
return (RSAPublicKey) keyFactory.generatePublic(spec);
40-
4142
}
42-
4343
}
44-
4544
}

cf-java-logging-support-servlet/src/main/java/com/sap/hcp/cf/logging/servlet/dynlog/TokenCreator.java

Lines changed: 110 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -11,120 +11,126 @@
1111
import java.security.spec.PKCS8EncodedKeySpec;
1212
import java.security.spec.X509EncodedKeySpec;
1313
import java.util.Arrays;
14+
import java.util.Base64;
1415
import java.util.Date;
1516
import java.util.List;
1617

17-
import javax.xml.bind.DatatypeConverter;
18-
1918
import org.apache.commons.lang3.StringUtils;
2019

2120
import com.auth0.jwt.JWT;
2221
import com.auth0.jwt.JWTCreator.Builder;
2322
import com.auth0.jwt.algorithms.Algorithm;
2423

24+
/**
25+
* This class provides a small example application to generate JWT tokens for
26+
* the dynamic log level feature. The input data is hard-coded in the
27+
* source-code. Please change the value for your use-case.
28+
*
29+
*/
2530
public class TokenCreator {
2631

27-
private static final List<String> ALLOWED_DYNAMIC_LOGLEVELS = Arrays.asList("TRACE", "DEBUG", "INFO", "WARN",
28-
"ERROR");
29-
30-
/**
31-
* Run this application locally in order to generate valid dynamic log level JWT
32-
* tokens which enable you to change the log level threshold on your
33-
* CF-Application for a single thread.
34-
*/
35-
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException,
36-
DynamicLogLevelException, InvalidKeySpecException {
37-
38-
/*
39-
* PLEASE PROVIDE THIS INFORMATION ***********************************
40-
*/
41-
// Replace with email address
42-
String issuer = "[email protected]";
43-
// Replace with the log level that should be transmitted via the token
44-
// Valid log level thresholds are:
45-
// "TRACE", "DEBUG", "INFO", "WARN", "ERROR"
46-
String level = "TRACE";
47-
// Replace with the packages that should be transmitted via the token
48-
// Multiple packages should be separated by a comma.
49-
String packages = "";
50-
// Set a validity period in days
51-
long validityPeriodInDays = 2;
52-
// If available provide Base64 encoded private key here:
53-
String privateKey = "";
54-
// If available provide Base64 encoded private key here:
55-
String publicKey = "";
56-
// (If no keys are provided, new keys will be generated)
57-
/*
58-
* ********************************************************************
59-
*/
60-
61-
KeyPair keyPair;
62-
63-
if (StringUtils.isNotBlank(privateKey)) {
64-
keyPair = new KeyPair(publicKeyConverter(publicKey), privateKeyConverter(privateKey));
65-
}
66-
67-
else {
68-
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
69-
keyGen.initialize(2048);
70-
keyPair = keyGen.generateKeyPair();
71-
// keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
72-
}
73-
privateKey = DatatypeConverter.printBase64Binary(keyPair.getPrivate().getEncoded());
74-
publicKey = DatatypeConverter.printBase64Binary(keyPair.getPublic().getEncoded());
75-
Date issuedAt = new Date();
76-
Date expiresAt = new Date(new Date().getTime() + validityPeriodInDays * 86400000);
77-
String token = TokenCreator.createToken(keyPair, issuer, issuedAt, expiresAt, level, packages);
78-
79-
System.out.println("You successfully created a dynamic log level token with log level " + level
80-
+ " and packages " + packages + "!");
81-
System.out.println();
82-
System.out.println("Your private key is:");
83-
System.out.println(privateKey);
84-
System.out.println("Your public key is:");
85-
System.out.println(publicKey);
86-
System.out.println("Your JWT token with log level " + level + " is:");
87-
System.out.println(token);
88-
System.out.println();
89-
System.out.println("Please copy and save token and keys for later usage. The JWT token can now be written");
90-
System.out.println("to an HTTP header in order to change the corresponding request's log level to " + level);
91-
System.out.println("For token validation, the public key must be added to the environment of the application.");
92-
System.out
93-
.println("In order to generate a new token with specific keys, the variables privateKey and publicKey");
94-
System.out.println("can be instantiated with these keys");
95-
96-
}
97-
98-
public static String createToken(KeyPair keyPair, String issuer, Date issuedAt, Date expiresAt, String level,
99-
String packages) throws NoSuchAlgorithmException, NoSuchProviderException, DynamicLogLevelException {
100-
Algorithm rsa256 = Algorithm.RSA256((RSAPublicKey) keyPair.getPublic(), (RSAPrivateKey) keyPair.getPrivate());
101-
if (ALLOWED_DYNAMIC_LOGLEVELS.contains(level)) {
102-
Builder builder = JWT.create().withIssuer(issuer).//
103-
withIssuedAt(issuedAt). //
104-
withExpiresAt(expiresAt).//
105-
withClaim("level", level);
106-
builder = StringUtils.isNotBlank(packages) ? builder.withClaim("packages", packages) : builder;
107-
return builder.withClaim("packages", packages).sign(rsa256);
108-
} else {
109-
throw new DynamicLogLevelException("Dynamic Log-Level [" + level
110-
+ "] provided in header is not valid. Allowed Values are " + ALLOWED_DYNAMIC_LOGLEVELS.toString());
111-
}
112-
}
113-
114-
private static RSAPublicKey publicKeyConverter(String pemKey)
115-
throws NoSuchAlgorithmException, InvalidKeySpecException {
116-
byte[] keyBytes = DatatypeConverter.parseBase64Binary(pemKey);
117-
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
118-
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
119-
return (RSAPublicKey) keyFactory.generatePublic(spec);
120-
}
121-
122-
private static RSAPrivateKey privateKeyConverter(String pemKey)
123-
throws NoSuchAlgorithmException, InvalidKeySpecException {
124-
byte[] keyBytes = DatatypeConverter.parseBase64Binary(pemKey);
125-
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
126-
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
127-
return (RSAPrivateKey) keyFactory.generatePrivate(spec);
128-
}
32+
private static final List<String> ALLOWED_DYNAMIC_LOGLEVELS = Arrays.asList("TRACE", "DEBUG", "INFO", "WARN",
33+
"ERROR");
34+
35+
/**
36+
* Run this application locally in order to generate valid dynamic log level
37+
* JWT tokens which enable you to change the log level threshold on your
38+
* CF-Application for a single thread.
39+
*/
40+
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException,
41+
DynamicLogLevelException, InvalidKeySpecException {
42+
43+
/*
44+
* PLEASE PROVIDE THIS INFORMATION ***********************************
45+
*/
46+
// Replace with email address
47+
String issuer = "[email protected]";
48+
// Replace with the log level that should be transmitted via the token
49+
// Valid log level thresholds are:
50+
// "TRACE", "DEBUG", "INFO", "WARN", "ERROR"
51+
String level = "TRACE";
52+
// Replace with the packages that should be transmitted via the token
53+
// Multiple packages should be separated by a comma.
54+
String packages = "";
55+
// Set a validity period in days
56+
long validityPeriodInDays = 2;
57+
// If available provide Base64 encoded private key here:
58+
String privateKey = "";
59+
// If available provide Base64 encoded private key here:
60+
String publicKey = "";
61+
// (If no keys are provided, new keys will be generated)
62+
/*
63+
* ********************************************************************
64+
*/
65+
66+
KeyPair keyPair;
67+
68+
if (StringUtils.isNotBlank(privateKey)) {
69+
keyPair = new KeyPair(publicKeyConverter(publicKey), privateKeyConverter(privateKey));
70+
}
71+
72+
else {
73+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
74+
keyGen.initialize(2048);
75+
keyPair = keyGen.generateKeyPair();
76+
// keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
77+
}
78+
privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
79+
publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
80+
Date issuedAt = new Date();
81+
Date expiresAt = new Date(new Date().getTime() + validityPeriodInDays * 86400000);
82+
String token = TokenCreator.createToken(keyPair, issuer, issuedAt, expiresAt, level, packages);
83+
84+
System.out.println("You successfully created a dynamic log level token with log level " + level +
85+
" and packages " + packages + "!");
86+
System.out.println();
87+
System.out.println("Your private key is:");
88+
System.out.println(privateKey);
89+
System.out.println("Your public key is:");
90+
System.out.println(publicKey);
91+
System.out.println("Your JWT token with log level " + level + " is:");
92+
System.out.println(token);
93+
System.out.println();
94+
System.out.println("Please copy and save token and keys for later usage. The JWT token can now be written");
95+
System.out.println("to an HTTP header in order to change the corresponding request's log level to " + level);
96+
System.out.println("For token validation, the public key must be added to the environment of the application.");
97+
System.out.println("In order to generate a new token with specific keys, the variables privateKey and publicKey");
98+
System.out.println("can be instantiated with these keys");
99+
100+
}
101+
102+
public static String createToken(KeyPair keyPair, String issuer, Date issuedAt, Date expiresAt, String level,
103+
String packages) throws NoSuchAlgorithmException, NoSuchProviderException,
104+
DynamicLogLevelException {
105+
Algorithm rsa256 = Algorithm.RSA256((RSAPublicKey) keyPair.getPublic(), (RSAPrivateKey) keyPair.getPrivate());
106+
if (ALLOWED_DYNAMIC_LOGLEVELS.contains(level)) {
107+
Builder builder = JWT.create().withIssuer(issuer).//
108+
withIssuedAt(issuedAt). //
109+
withExpiresAt(expiresAt).//
110+
withClaim("level", level);
111+
builder = StringUtils.isNotBlank(packages) ? builder.withClaim("packages", packages) : builder;
112+
return builder.withClaim("packages", packages).sign(rsa256);
113+
} else {
114+
throw new DynamicLogLevelException("Dynamic Log-Level [" + level +
115+
"] provided in header is not valid. Allowed Values are " +
116+
ALLOWED_DYNAMIC_LOGLEVELS.toString());
117+
}
118+
}
119+
120+
private static RSAPublicKey publicKeyConverter(String pemKey) throws NoSuchAlgorithmException,
121+
InvalidKeySpecException {
122+
byte[] keyBytes = Base64.getDecoder().decode(pemKey);
123+
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
124+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
125+
return (RSAPublicKey) keyFactory.generatePublic(spec);
126+
}
127+
128+
private static RSAPrivateKey privateKeyConverter(String pemKey) throws NoSuchAlgorithmException,
129+
InvalidKeySpecException {
130+
byte[] keyBytes = Base64.getDecoder().decode(pemKey);
131+
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
132+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
133+
return (RSAPrivateKey) keyFactory.generatePrivate(spec);
134+
}
129135

130136
}

0 commit comments

Comments
 (0)