KEYCLOAK-905
Realm key rotation for OIDC
This commit is contained in:
1 parent
1e51952006
commit
d2cae0f8c3
161 files changed
+4905
-2704
No files matched your search
-121
@@ -60,10 +60,6 @@ public class RealmAdapter implements RealmModel {
|
||||
protected RealmCacheSession cacheSession;
|
||||
protected RealmModel updated;
|
||||
protected RealmCache cache;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected volatile transient Key codeSecretKey;
|
||||
protected volatile transient X509Certificate certificate;
|
||||
|
||||
public RealmAdapter(CachedRealm cached, RealmCacheSession cacheSession) {
|
||||
this.cached = cached;
|
||||
@@ -423,123 +419,6 @@ public class RealmAdapter implements RealmModel {
|
||||
updated.setAccessCodeLifespanLogin(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyId() {
|
||||
if (isUpdated()) return updated.getKeyId();
|
||||
return cached.getKeyId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
if (isUpdated()) return updated.getPublicKeyPem();
|
||||
return cached.getPublicKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
getDelegateForUpdate();
|
||||
updated.setPublicKeyPem(publicKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
if (isUpdated()) return updated.getPrivateKeyPem();
|
||||
return cached.getPrivateKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
getDelegateForUpdate();
|
||||
updated.setPrivateKeyPem(privateKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublicKey() {
|
||||
if (isUpdated()) return updated.getPublicKey();
|
||||
if (publicKey != null) return publicKey;
|
||||
publicKey = cached.getPublicKey();
|
||||
if (publicKey != null) return publicKey;
|
||||
publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
|
||||
setPublicKeyPem(publicKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate getCertificate() {
|
||||
if (isUpdated()) return updated.getCertificate();
|
||||
if (certificate != null) return certificate;
|
||||
certificate = cached.getCertificate();
|
||||
if (certificate != null) return certificate;
|
||||
certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
|
||||
return certificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificate(X509Certificate certificate) {
|
||||
this.certificate = certificate;
|
||||
String certPem = KeycloakModelUtils.getPemFromCertificate(certificate);
|
||||
setCertificatePem(certPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCertificatePem() {
|
||||
if (isUpdated()) return updated.getCertificatePem();
|
||||
return cached.getCertificatePem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificatePem(String certificate) {
|
||||
getDelegateForUpdate();
|
||||
updated.setCertificatePem(certificate);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey() {
|
||||
if (isUpdated()) return updated.getPrivateKey();
|
||||
if (privateKey != null) {
|
||||
return privateKey;
|
||||
}
|
||||
privateKey = cached.getPrivateKey();
|
||||
if (privateKey != null) {
|
||||
return privateKey;
|
||||
}
|
||||
privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
|
||||
setPrivateKeyPem(privateKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodeSecret() {
|
||||
return isUpdated() ? updated.getCodeSecret() : cached.getCodeSecret();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getCodeSecretKey() {
|
||||
if (codeSecretKey == null) {
|
||||
codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
|
||||
}
|
||||
return codeSecretKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
getDelegateForUpdate();
|
||||
updated.setCodeSecret(codeSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
if (isUpdated()) return updated.getRequiredCredentials();
|
||||
|
||||
Vendored
-50
@@ -89,15 +89,6 @@ public class CachedRealm extends AbstractRevisioned {
|
||||
protected PasswordPolicy passwordPolicy;
|
||||
protected OTPPolicy otpPolicy;
|
||||
|
||||
protected transient String keyId;
|
||||
protected transient PublicKey publicKey;
|
||||
protected String publicKeyPem;
|
||||
protected transient PrivateKey privateKey;
|
||||
protected String privateKeyPem;
|
||||
protected transient X509Certificate certificate;
|
||||
protected String certificatePem;
|
||||
protected String codeSecret;
|
||||
|
||||
protected String loginTheme;
|
||||
protected String accountTheme;
|
||||
protected String adminTheme;
|
||||
@@ -191,15 +182,6 @@ public class CachedRealm extends AbstractRevisioned {
|
||||
passwordPolicy = model.getPasswordPolicy();
|
||||
otpPolicy = model.getOTPPolicy();
|
||||
|
||||
keyId = model.getKeyId();
|
||||
publicKeyPem = model.getPublicKeyPem();
|
||||
publicKey = model.getPublicKey();
|
||||
privateKeyPem = model.getPrivateKeyPem();
|
||||
privateKey = model.getPrivateKey();
|
||||
certificatePem = model.getCertificatePem();
|
||||
certificate = model.getCertificate();
|
||||
codeSecret = model.getCodeSecret();
|
||||
|
||||
loginTheme = model.getLoginTheme();
|
||||
accountTheme = model.getAccountTheme();
|
||||
adminTheme = model.getAdminTheme();
|
||||
@@ -415,22 +397,6 @@ public class CachedRealm extends AbstractRevisioned {
|
||||
return accessCodeLifespanLogin;
|
||||
}
|
||||
|
||||
public String getKeyId() {
|
||||
return keyId;
|
||||
}
|
||||
|
||||
public String getPublicKeyPem() {
|
||||
return publicKeyPem;
|
||||
}
|
||||
|
||||
public String getPrivateKeyPem() {
|
||||
return privateKeyPem;
|
||||
}
|
||||
|
||||
public String getCodeSecret() {
|
||||
return codeSecret;
|
||||
}
|
||||
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
return requiredCredentials;
|
||||
}
|
||||
@@ -507,10 +473,6 @@ public class CachedRealm extends AbstractRevisioned {
|
||||
return userFederationMappers;
|
||||
}
|
||||
|
||||
public String getCertificatePem() {
|
||||
return certificatePem;
|
||||
}
|
||||
|
||||
public List<IdentityProviderModel> getIdentityProviders() {
|
||||
return identityProviders;
|
||||
}
|
||||
@@ -591,18 +553,6 @@ public class CachedRealm extends AbstractRevisioned {
|
||||
return clientTemplates;
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public X509Certificate getCertificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public Set<UserFederationMapperModel> getUserFederationMapperSet() {
|
||||
return userFederationMapperSet;
|
||||
}
|
||||
|
||||
-1
@@ -106,7 +106,6 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
||||
tx.put(sessionCache, id, entity);
|
||||
|
||||
ClientSessionAdapter wrap = wrap(realm, entity, false);
|
||||
wrap.setNote(ClientSessionModel.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
|
||||
return wrap;
|
||||
}
|
||||
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.connections.jpa.updater.liquibase.custom;
|
||||
|
||||
import liquibase.exception.CustomChangeException;
|
||||
import liquibase.statement.core.InsertStatement;
|
||||
import liquibase.structure.core.Table;
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ExtractRealmKeysFromRealmTable extends CustomKeycloakTask {
|
||||
|
||||
@Override
|
||||
protected void generateStatementsImpl() throws CustomChangeException {
|
||||
try {
|
||||
PreparedStatement statement = jdbcConnection.prepareStatement("select ID, PRIVATE_KEY, CERTIFICATE from " + getTableName("REALM"));
|
||||
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
try {
|
||||
while (resultSet.next()) {
|
||||
String realmId = resultSet.getString(1);
|
||||
String privateKeyPem = resultSet.getString(2);
|
||||
String certificatePem = resultSet.getString(3);
|
||||
|
||||
String componentId = KeycloakModelUtils.generateId();
|
||||
|
||||
InsertStatement insertComponent = new InsertStatement(null, null, database.correctObjectName("COMPONENT", Table.class))
|
||||
.addColumnValue("ID", componentId)
|
||||
.addColumnValue("REALM_ID", realmId)
|
||||
.addColumnValue("PARENT_ID", realmId)
|
||||
.addColumnValue("NAME", "rsa")
|
||||
.addColumnValue("PROVIDER_ID", "rsa")
|
||||
.addColumnValue("PROVIDER_TYPE", KeyProvider.class.getName());
|
||||
|
||||
statements.add(insertComponent);
|
||||
|
||||
statements.add(componentConfigStatement(componentId, "priority", "100"));
|
||||
statements.add(componentConfigStatement(componentId, "privateKey", privateKeyPem));
|
||||
statements.add(componentConfigStatement(componentId, "certificate", certificatePem));
|
||||
}
|
||||
} finally {
|
||||
resultSet.close();
|
||||
}
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
|
||||
confirmationMessage.append("Updated " + statements.size() + " records in USER_FEDERATION_PROVIDER table");
|
||||
} catch (Exception e) {
|
||||
throw new CustomChangeException(getTaskId() + ": Exception when updating data from previous version", e);
|
||||
}
|
||||
}
|
||||
|
||||
private InsertStatement componentConfigStatement(String componentId, String name, String value) {
|
||||
return new InsertStatement(null, null, database.correctObjectName("COMPONENT_CONFIG", Table.class))
|
||||
.addColumnValue("ID", KeycloakModelUtils.generateId())
|
||||
.addColumnValue("COMPONENT_ID", componentId)
|
||||
.addColumnValue("NAME", name)
|
||||
.addColumnValue("VALUE", value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTaskId() {
|
||||
return "Update 2.3.0.Final";
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package org.keycloak.models.jpa;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.enums.SslRequired;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.component.ComponentFactory;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.jose.jwk.JWKBuilder;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
@@ -60,6 +61,7 @@ import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
|
||||
import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
|
||||
import org.keycloak.models.utils.ComponentUtil;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
@@ -88,10 +90,6 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||
protected static final Logger logger = Logger.getLogger(RealmAdapter.class);
|
||||
protected RealmEntity realm;
|
||||
protected EntityManager em;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected volatile transient X509Certificate certificate;
|
||||
protected volatile transient Key codeSecretKey;
|
||||
protected KeycloakSession session;
|
||||
private PasswordPolicy passwordPolicy;
|
||||
private OTPPolicy otpPolicy;
|
||||
@@ -488,106 +486,6 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyId() {
|
||||
PublicKey publicKey = getPublicKey();
|
||||
return publicKey != null ? JWKBuilder.create().rs256(publicKey).getKeyId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
return realm.getPublicKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realm.setPublicKeyPem(publicKeyPem);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate getCertificate() {
|
||||
if (certificate != null) return certificate;
|
||||
certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
|
||||
return certificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificate(X509Certificate certificate) {
|
||||
this.certificate = certificate;
|
||||
String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
|
||||
setCertificatePem(certificatePem);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCertificatePem() {
|
||||
return realm.getCertificatePem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificatePem(String certificate) {
|
||||
realm.setCertificatePem(certificate);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
return realm.getPrivateKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realm.setPrivateKeyPem(privateKeyPem);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublicKey() {
|
||||
if (publicKey != null) return publicKey;
|
||||
publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
|
||||
setPublicKeyPem(publicKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey() {
|
||||
if (privateKey != null) return privateKey;
|
||||
privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
|
||||
setPrivateKeyPem(privateKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodeSecret() {
|
||||
return realm.getCodeSecret();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getCodeSecretKey() {
|
||||
if (codeSecretKey == null) {
|
||||
codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
|
||||
}
|
||||
return codeSecretKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
realm.setCodeSecret(codeSecret);
|
||||
}
|
||||
|
||||
protected RequiredCredentialModel initRequiredCredentialModel(String type) {
|
||||
RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
|
||||
if (model == null) {
|
||||
@@ -2138,6 +2036,13 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||
|
||||
@Override
|
||||
public ComponentModel addComponentModel(ComponentModel model) {
|
||||
ComponentFactory componentFactory = ComponentUtil.getComponentFactory(session, model);
|
||||
if (componentFactory == null) {
|
||||
throw new IllegalArgumentException("Invalid component type");
|
||||
}
|
||||
|
||||
componentFactory.validateConfiguration(session, model);
|
||||
|
||||
ComponentEntity c = new ComponentEntity();
|
||||
if (model.getId() == null) {
|
||||
c.setId(KeycloakModelUtils.generateId());
|
||||
@@ -2171,6 +2076,8 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||
|
||||
@Override
|
||||
public void updateComponent(ComponentModel component) {
|
||||
ComponentUtil.getComponentFactory(session, component).validateConfiguration(session, component);
|
||||
|
||||
ComponentEntity c = em.find(ComponentEntity.class, component.getId());
|
||||
if (c == null) return;
|
||||
c.setName(component.getName());
|
||||
|
||||
@@ -117,15 +117,6 @@ public class RealmEntity {
|
||||
@Column(name="NOT_BEFORE")
|
||||
protected int notBefore;
|
||||
|
||||
@Column(name="PUBLIC_KEY", length = 4000)
|
||||
protected String publicKeyPem;
|
||||
@Column(name="PRIVATE_KEY", length = 4000)
|
||||
protected String privateKeyPem;
|
||||
@Column(name="CERTIFICATE", length = 4000)
|
||||
protected String certificatePem;
|
||||
@Column(name="CODE_SECRET", length = 255)
|
||||
protected String codeSecret;
|
||||
|
||||
@Column(name="LOGIN_THEME")
|
||||
protected String loginTheme;
|
||||
@Column(name="ACCOUNT_THEME")
|
||||
@@ -384,30 +375,6 @@ public class RealmEntity {
|
||||
this.accessCodeLifespanLogin = accessCodeLifespanLogin;
|
||||
}
|
||||
|
||||
public String getPublicKeyPem() {
|
||||
return publicKeyPem;
|
||||
}
|
||||
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
this.publicKeyPem = publicKeyPem;
|
||||
}
|
||||
|
||||
public String getPrivateKeyPem() {
|
||||
return privateKeyPem;
|
||||
}
|
||||
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
this.privateKeyPem = privateKeyPem;
|
||||
}
|
||||
|
||||
public String getCodeSecret() {
|
||||
return codeSecret;
|
||||
}
|
||||
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
this.codeSecret = codeSecret;
|
||||
}
|
||||
|
||||
public Collection<RequiredCredentialEntity> getRequiredCredentials() {
|
||||
return requiredCredentials;
|
||||
}
|
||||
@@ -567,14 +534,6 @@ public class RealmEntity {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getCertificatePem() {
|
||||
return certificatePem;
|
||||
}
|
||||
|
||||
public void setCertificatePem(String certificatePem) {
|
||||
this.certificatePem = certificatePem;
|
||||
}
|
||||
|
||||
public List<IdentityProviderEntity> getIdentityProviders() {
|
||||
return this.identityProviders;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
<addColumn tableName="IDENTITY_PROVIDER">
|
||||
<column name="PROVIDER_DISPLAY_NAME" type="VARCHAR(255)"></column>
|
||||
</addColumn>
|
||||
|
||||
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.ExtractRealmKeysFromRealmTable"/>
|
||||
<dropColumn tableName="REALM" columnName="CODE_SECRET" />
|
||||
<dropColumn tableName="REALM" columnName="PRIVATE_KEY" />
|
||||
<dropColumn tableName="REALM" columnName="PUBLIC_KEY" />
|
||||
<dropColumn tableName="REALM" columnName="CERTIFICATE" />
|
||||
|
||||
</changeSet>
|
||||
|
||||
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import org.keycloak.connections.mongo.updater.impl.updates.Update1_4_0;
|
||||
import org.keycloak.connections.mongo.updater.impl.updates.Update1_7_0;
|
||||
import org.keycloak.connections.mongo.updater.impl.updates.Update1_8_0;
|
||||
import org.keycloak.connections.mongo.updater.impl.updates.Update1_9_2;
|
||||
import org.keycloak.connections.mongo.updater.impl.updates.Update2_3_0;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -57,7 +58,8 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
|
||||
Update1_4_0.class,
|
||||
Update1_7_0.class,
|
||||
Update1_8_0.class,
|
||||
Update1_9_2.class
|
||||
Update1_9_2.class,
|
||||
Update2_3_0.class
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.connections.mongo.updater.impl.updates;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import org.keycloak.keys.KeyProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.mongo.keycloak.entities.ComponentEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class Update2_3_0 extends Update {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "2.3.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(KeycloakSession session) {
|
||||
|
||||
DBCollection realms = db.getCollection("realms");
|
||||
DBCursor cursor = realms.find();
|
||||
while (cursor.hasNext()) {
|
||||
BasicDBObject realm = (BasicDBObject) cursor.next();
|
||||
|
||||
String realmId = realm.getString("_id");
|
||||
|
||||
String privateKeyPem = realm.getString("privateKeyPem");
|
||||
String certificatePem = realm.getString("certificatePem");
|
||||
|
||||
BasicDBList entities = (BasicDBList) realm.get("componentEntities");
|
||||
|
||||
BasicDBObject component = new BasicDBObject();
|
||||
component.put("id", KeycloakModelUtils.generateId());
|
||||
component.put("name", "rsa");
|
||||
component.put("providerType", KeyProvider.class.getName());
|
||||
component.put("providerId", "rsa");
|
||||
component.put("parentId", realmId);
|
||||
|
||||
BasicDBObject config = new BasicDBObject();
|
||||
config.put("priority", Collections.singletonList("100"));
|
||||
config.put("privateKey", Collections.singletonList(privateKeyPem));
|
||||
config.put("certificate", Collections.singletonList(certificatePem));
|
||||
|
||||
component.put("config", config);
|
||||
|
||||
entities.add(component);
|
||||
|
||||
realm.remove("privateKeyPem");
|
||||
realm.remove("certificatePem");
|
||||
realm.remove("publicKeyPem");
|
||||
realm.remove("codeSecret");
|
||||
|
||||
realms.update(new BasicDBObject().append("_id", realmId), realm);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-109
@@ -59,6 +59,7 @@ import org.keycloak.models.mongo.keycloak.entities.RequiredActionProviderEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UserFederationMapperEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UserFederationProviderEntity;
|
||||
import org.keycloak.models.utils.ComponentUtil;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.security.Key;
|
||||
@@ -85,11 +86,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||
private final MongoRealmEntity realm;
|
||||
private final RealmProvider model;
|
||||
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected volatile transient X509Certificate certificate;
|
||||
protected volatile transient Key codeSecretKey;
|
||||
|
||||
private volatile transient OTPPolicy otpPolicy;
|
||||
private volatile transient PasswordPolicy passwordPolicy;
|
||||
private volatile transient KeycloakSession session;
|
||||
@@ -455,110 +451,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||
return realm.getAccessCodeLifespanLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyId() {
|
||||
PublicKey publicKey = getPublicKey();
|
||||
return publicKey != null ? JWKBuilder.create().rs256(publicKey).getKeyId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
return realm.getPublicKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realm.setPublicKeyPem(publicKeyPem);
|
||||
this.publicKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate getCertificate() {
|
||||
if (certificate != null) return certificate;
|
||||
certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
|
||||
return certificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificate(X509Certificate certificate) {
|
||||
this.certificate = certificate;
|
||||
String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
|
||||
setCertificatePem(certificatePem);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCertificatePem() {
|
||||
return realm.getCertificatePem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCertificatePem(String certificate) {
|
||||
realm.setCertificatePem(certificate);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
return realm.getPrivateKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realm.setPrivateKeyPem(privateKeyPem);
|
||||
this.privateKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublicKey() {
|
||||
if (publicKey != null) return publicKey;
|
||||
publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
|
||||
setPublicKeyPem(publicKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey() {
|
||||
if (privateKey != null) return privateKey;
|
||||
privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
|
||||
setPrivateKeyPem(privateKeyPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodeSecret() {
|
||||
return realm.getCodeSecret();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getCodeSecretKey() {
|
||||
if (codeSecretKey == null) {
|
||||
codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
|
||||
}
|
||||
return codeSecretKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
realm.setCodeSecret(codeSecret);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginTheme() {
|
||||
return realm.getLoginTheme();
|
||||
@@ -2062,6 +1954,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||
|
||||
@Override
|
||||
public ComponentModel addComponentModel(ComponentModel model) {
|
||||
ComponentUtil.getComponentFactory(session, model).validateConfiguration(session, model);
|
||||
|
||||
ComponentEntity entity = new ComponentEntity();
|
||||
if (model.getId() == null) {
|
||||
entity.setId(KeycloakModelUtils.generateId());
|
||||
@@ -2082,6 +1976,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||
|
||||
@Override
|
||||
public void updateComponent(ComponentModel model) {
|
||||
ComponentUtil.getComponentFactory(session, model).validateConfiguration(session, model);
|
||||
|
||||
for (ComponentEntity entity : realm.getComponentEntities()) {
|
||||
if (entity.getId().equals(model.getId())) {
|
||||
entity.setConfig(model.getConfig());
|
||||
|
||||
-37
@@ -70,11 +70,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||
private int accessCodeLifespanLogin;
|
||||
private int notBefore;
|
||||
|
||||
private String publicKeyPem;
|
||||
private String privateKeyPem;
|
||||
private String certificatePem;
|
||||
private String codeSecret;
|
||||
|
||||
private String loginTheme;
|
||||
private String accountTheme;
|
||||
private String adminTheme;
|
||||
@@ -351,30 +346,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public String getPublicKeyPem() {
|
||||
return publicKeyPem;
|
||||
}
|
||||
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
this.publicKeyPem = publicKeyPem;
|
||||
}
|
||||
|
||||
public String getPrivateKeyPem() {
|
||||
return privateKeyPem;
|
||||
}
|
||||
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
this.privateKeyPem = privateKeyPem;
|
||||
}
|
||||
|
||||
public String getCodeSecret() {
|
||||
return codeSecret;
|
||||
}
|
||||
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
this.codeSecret = codeSecret;
|
||||
}
|
||||
|
||||
public String getLoginTheme() {
|
||||
return loginTheme;
|
||||
}
|
||||
@@ -527,14 +498,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||
this.identityProviders = identityProviders;
|
||||
}
|
||||
|
||||
public String getCertificatePem() {
|
||||
return certificatePem;
|
||||
}
|
||||
|
||||
public void setCertificatePem(String certificatePem) {
|
||||
this.certificatePem = certificatePem;
|
||||
}
|
||||
|
||||
public boolean isInternationalizationEnabled() {
|
||||
return internationalizationEnabled;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user