implemented key rotation in RotatingKeyManager
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -1,12 +1,16 @@
|
|||||||
/* © SRSoftware 2024 */
|
/* © SRSoftware 2024 */
|
||||||
package de.srsoftware.oidc.backend;
|
package de.srsoftware.oidc.backend;
|
||||||
|
|
||||||
|
import static de.srsoftware.oidc.api.Constants.EXPIRATION;
|
||||||
|
import static de.srsoftware.utils.Optionals.nullable;
|
||||||
import static de.srsoftware.utils.Strings.uuid;
|
import static de.srsoftware.utils.Strings.uuid;
|
||||||
import static org.jose4j.jws.AlgorithmIdentifiers.RSA_USING_SHA256;
|
import static org.jose4j.jws.AlgorithmIdentifiers.RSA_USING_SHA256;
|
||||||
|
|
||||||
import de.srsoftware.oidc.api.KeyManager;
|
import de.srsoftware.oidc.api.KeyManager;
|
||||||
import de.srsoftware.oidc.api.KeyStorage;
|
import de.srsoftware.oidc.api.KeyStorage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import org.jose4j.jwk.PublicJsonWebKey;
|
import org.jose4j.jwk.PublicJsonWebKey;
|
||||||
import org.jose4j.jwk.RsaJwkGenerator;
|
import org.jose4j.jwk.RsaJwkGenerator;
|
||||||
import org.jose4j.lang.JoseException;
|
import org.jose4j.lang.JoseException;
|
||||||
@@ -21,8 +25,19 @@ public class RotatingKeyManager implements KeyManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PublicJsonWebKey getKey() throws KeyCreationException, IOException {
|
public PublicJsonWebKey getKey() throws KeyCreationException, IOException {
|
||||||
var list = store.listKeys();
|
for (var keyId : store.listKeys()) {
|
||||||
return list.isEmpty() ? createNewKey() : store.load(list.get(0));
|
try {
|
||||||
|
var key = store.load(keyId);
|
||||||
|
var expired = nullable(key.getOtherParameterValue(EXPIRATION, Long.class)).map(Instant::ofEpochSecond).map(expiration -> expiration.isBefore(Instant.now())).orElse(false);
|
||||||
|
if (expired) {
|
||||||
|
store.drop(keyId);
|
||||||
|
} else
|
||||||
|
return key;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(System.Logger.Level.WARNING, "Failed to load key with id {0}", keyId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return createNewKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PublicJsonWebKey createNewKey() throws KeyCreationException, IOException {
|
private PublicJsonWebKey createNewKey() throws KeyCreationException, IOException {
|
||||||
@@ -30,7 +45,9 @@ public class RotatingKeyManager implements KeyManager {
|
|||||||
var key = RsaJwkGenerator.generateJwk(2048);
|
var key = RsaJwkGenerator.generateJwk(2048);
|
||||||
key.setAlgorithm(RSA_USING_SHA256);
|
key.setAlgorithm(RSA_USING_SHA256);
|
||||||
key.setKeyId(uuid());
|
key.setKeyId(uuid());
|
||||||
|
key.setOtherParameter(EXPIRATION, Instant.now().plus(1, ChronoUnit.DAYS).getEpochSecond());
|
||||||
store.store(key);
|
store.store(key);
|
||||||
|
LOG.log(System.Logger.Level.INFO, "Created new JsonWebKey (Id: {0})", key.getKeyId());
|
||||||
return key;
|
return key;
|
||||||
} catch (JoseException e) {
|
} catch (JoseException e) {
|
||||||
throw new KeyCreationException(e);
|
throw new KeyCreationException(e);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* © SRSoftware 2024 */
|
/* © SRSoftware 2024 */
|
||||||
package de.srsoftware.oidc.datastore.file;
|
package de.srsoftware.oidc.datastore.file;
|
||||||
|
|
||||||
|
import static java.lang.System.Logger.Level.DEBUG;
|
||||||
import static java.lang.System.Logger.Level.ERROR;
|
import static java.lang.System.Logger.Level.ERROR;
|
||||||
import static org.jose4j.jwk.JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE;
|
import static org.jose4j.jwk.JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE;
|
||||||
|
|
||||||
@@ -26,7 +27,8 @@ public class PlaintextKeyStore implements KeyStorage {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public KeyStorage drop(String keyId) {
|
public KeyStorage drop(String keyId) {
|
||||||
return null;
|
if (dir.resolve(keyId + ".key").toFile().delete()) LOG.log(DEBUG, "Removed key {0}", keyId);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user