Merge pull request #840 from stianst/master
KEYCLOAK-820 Don't expose realm private key through admin endpoints
This commit is contained in:
commit
5041d6ed80
9 changed files with 43 additions and 15 deletions
|
@ -60,6 +60,13 @@
|
||||||
</modules>
|
</modules>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -45,7 +45,7 @@ import java.util.Set;
|
||||||
public class ExportUtils {
|
public class ExportUtils {
|
||||||
|
|
||||||
public static RealmRepresentation exportRealm(KeycloakSession session, RealmModel realm, boolean includeUsers) {
|
public static RealmRepresentation exportRealm(KeycloakSession session, RealmModel realm, boolean includeUsers) {
|
||||||
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
|
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, true);
|
||||||
|
|
||||||
// Audit
|
// Audit
|
||||||
rep.setEventsEnabled(realm.isEventsEnabled());
|
rep.setEventsEnabled(realm.isEventsEnabled());
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h2><span>{{realm.realm}}</span> Realm Public Key <span tooltip-placement="right" tooltip="Realm's public key. This is used to verify any signed tokens or documents created by the realm." class="fa fa-info-circle"></span></h2>
|
<h2><span>{{realm.realm}}</span> Realm Public Key <span tooltip-placement="right" tooltip="Realm's public key. This is used to verify any signed tokens or documents created by the realm." class="fa fa-info-circle"></span></h2>
|
||||||
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
|
||||||
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
|
|
||||||
<button class="btn btn-primary btn-lg" type="submit" data-ng-click="generate()">Generate new keys</button>
|
|
||||||
</div>
|
|
||||||
<fieldset class="border-top">
|
<fieldset class="border-top">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label" for="publicKey">Public key</label>
|
<label class="col-sm-2 control-label" for="publicKey">Public key</label>
|
||||||
|
@ -18,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label" for="publicKey">Certificate</label>
|
<label class="col-sm-2 control-label" for="certificate">Certificate</label>
|
||||||
|
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea type="text" id="certificate" name="certificate" class="form-control" rows="5"
|
<textarea type="text" id="certificate" name="certificate" class="form-control" rows="5"
|
||||||
|
@ -26,6 +23,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
|
||||||
|
<button class="btn btn-primary btn-lg" type="submit" data-ng-click="generate()">Generate new keys</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -75,7 +75,7 @@ public class ModelToRepresentation {
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RealmRepresentation toRepresentation(RealmModel realm) {
|
public static RealmRepresentation toRepresentation(RealmModel realm, boolean internal) {
|
||||||
RealmRepresentation rep = new RealmRepresentation();
|
RealmRepresentation rep = new RealmRepresentation();
|
||||||
rep.setId(realm.getId());
|
rep.setId(realm.getId());
|
||||||
rep.setRealm(realm.getName());
|
rep.setRealm(realm.getName());
|
||||||
|
@ -85,13 +85,15 @@ public class ModelToRepresentation {
|
||||||
rep.setUpdateProfileOnInitialSocialLogin(realm.isUpdateProfileOnInitialSocialLogin());
|
rep.setUpdateProfileOnInitialSocialLogin(realm.isUpdateProfileOnInitialSocialLogin());
|
||||||
rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
|
rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
|
||||||
rep.setPublicKey(realm.getPublicKeyPem());
|
rep.setPublicKey(realm.getPublicKeyPem());
|
||||||
rep.setPrivateKey(realm.getPrivateKeyPem());
|
if (internal) {
|
||||||
String privateKeyPem = realm.getPrivateKeyPem();
|
rep.setPrivateKey(realm.getPrivateKeyPem());
|
||||||
if (realm.getCertificatePem() == null && privateKeyPem != null) {
|
String privateKeyPem = realm.getPrivateKeyPem();
|
||||||
KeycloakModelUtils.generateRealmCertificate(realm);
|
if (realm.getCertificatePem() == null && privateKeyPem != null) {
|
||||||
|
KeycloakModelUtils.generateRealmCertificate(realm);
|
||||||
|
}
|
||||||
|
rep.setCodeSecret(realm.getCodeSecret());
|
||||||
}
|
}
|
||||||
rep.setCertificate(realm.getCertificatePem());
|
rep.setCertificate(realm.getCertificatePem());
|
||||||
rep.setCodeSecret(realm.getCodeSecret());
|
|
||||||
rep.setPasswordCredentialGrantAllowed(realm.isPasswordCredentialGrantAllowed());
|
rep.setPasswordCredentialGrantAllowed(realm.isPasswordCredentialGrantAllowed());
|
||||||
rep.setRegistrationAllowed(realm.isRegistrationAllowed());
|
rep.setRegistrationAllowed(realm.isRegistrationAllowed());
|
||||||
rep.setRememberMe(realm.isRememberMe());
|
rep.setRememberMe(realm.isRememberMe());
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class RealmAdminResource {
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public RealmRepresentation getRealm() {
|
public RealmRepresentation getRealm() {
|
||||||
if (auth.hasView()) {
|
if (auth.hasView()) {
|
||||||
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
|
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false);
|
||||||
if (session.realms() instanceof CacheRealmProvider) {
|
if (session.realms() instanceof CacheRealmProvider) {
|
||||||
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
|
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
|
||||||
rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
|
rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class RealmsAdminResource {
|
||||||
|
|
||||||
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ApplicationModel realmManagementApplication) {
|
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ApplicationModel realmManagementApplication) {
|
||||||
if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) {
|
if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) {
|
||||||
reps.add(ModelToRepresentation.toRepresentation(realm));
|
reps.add(ModelToRepresentation.toRepresentation(realm, false));
|
||||||
} else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) {
|
} else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) {
|
||||||
RealmRepresentation rep = new RealmRepresentation();
|
RealmRepresentation rep = new RealmRepresentation();
|
||||||
rep.setRealm(realm.getName());
|
rep.setRealm(realm.getName());
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.keycloak.admin.client.Keycloak;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.representations.idm.ApplicationRepresentation;
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
import org.keycloak.representations.idm.OAuthClientRepresentation;
|
import org.keycloak.representations.idm.OAuthClientRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -42,6 +43,7 @@ public abstract class AbstractClientTest {
|
||||||
|
|
||||||
RealmModel testRealm = manager.createRealm(REALM_NAME);
|
RealmModel testRealm = manager.createRealm(REALM_NAME);
|
||||||
testRealm.setEnabled(true);
|
testRealm.setEnabled(true);
|
||||||
|
KeycloakModelUtils.generateRealmKeys(testRealm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,11 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +20,15 @@ public class RealmTest extends AbstractClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getRealms() {
|
public void getRealms() {
|
||||||
assertNames(keycloak.realms().findAll(), "master", "test", REALM_NAME);
|
List<RealmRepresentation> realms = keycloak.realms().findAll();
|
||||||
|
assertNames(realms, "master", "test", REALM_NAME);
|
||||||
|
|
||||||
|
for (RealmRepresentation rep : realms) {
|
||||||
|
assertNull(rep.getPrivateKey());
|
||||||
|
assertNull(rep.getCodeSecret());
|
||||||
|
assertNotNull(rep.getPublicKey());
|
||||||
|
assertNotNull(rep.getCertificate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -65,6 +77,11 @@ public class RealmTest extends AbstractClientTest {
|
||||||
RealmRepresentation rep = realm.toRepresentation();
|
RealmRepresentation rep = realm.toRepresentation();
|
||||||
assertEquals(REALM_NAME, rep.getRealm());
|
assertEquals(REALM_NAME, rep.getRealm());
|
||||||
assertTrue(rep.isEnabled());
|
assertTrue(rep.isEnabled());
|
||||||
|
|
||||||
|
assertNull(rep.getPrivateKey());
|
||||||
|
assertNull(rep.getCodeSecret());
|
||||||
|
assertNotNull(rep.getPublicKey());
|
||||||
|
assertNotNull(rep.getCertificate());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class ModelTest extends AbstractModelTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RealmModel importExport(RealmModel src, String copyName) {
|
private RealmModel importExport(RealmModel src, String copyName) {
|
||||||
RealmRepresentation representation = ModelToRepresentation.toRepresentation(src);
|
RealmRepresentation representation = ModelToRepresentation.toRepresentation(src, true);
|
||||||
representation.setRealm(copyName);
|
representation.setRealm(copyName);
|
||||||
representation.setId(copyName);
|
representation.setId(copyName);
|
||||||
RealmModel copy = realmManager.importRealm(representation);
|
RealmModel copy = realmManager.importRealm(representation);
|
||||||
|
|
Loading…
Reference in a new issue