diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 25e0b06dae..1334d92747 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -16,6 +16,8 @@ public class RealmRepresentation { protected boolean enabled; protected boolean sslNotRequired; protected boolean cookieLoginAllowed; + protected String privateKey; + protected String publicKey; protected Set roles; protected List requiredCredentials; protected List users; @@ -151,4 +153,20 @@ public class RealmRepresentation { public void setRoles(Set roles) { this.roles = roles; } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } } diff --git a/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json b/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json index 3e228f1cbd..6d2cac8879 100755 --- a/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json +++ b/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json @@ -1,5 +1,8 @@ { - "realm-url" : "http://localhost:8080/auth-server/rest/realms/demo", + "realm" : "demo", + "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/auth/request", + "code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes", "ssl-not-required" : true, "client-id" : "customer-portal", "client-credentials" : { diff --git a/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json b/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json index 8e538101a2..095cd12f2a 100755 --- a/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json +++ b/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json @@ -1,5 +1,8 @@ { - "realm-url" : "http://localhost:8080/auth-server/rest/realms/demo", + "realm" : "demo", + "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/auth/request", + "code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes", "ssl-not-required" : true, "client-id" : "product-portal", "client-credentials" : { diff --git a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json index 5b913e8ed2..2d8d016b6b 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json +++ b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json @@ -3,6 +3,8 @@ "enabled" : true, "tokenLifespan" : 6000, "accessCodeLifespan" : 30, + "privateKey" : "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", + "publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "requiredCredentials" : [ { "type" : "Password", diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java index 1856cf684b..e55c3c71b4 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java @@ -98,6 +98,9 @@ public class ManagedResourceConfigLoader { remoteSkeletonKeyConfig.setRealmKey(rep.getPublicKeyPem()); remoteSkeletonKeyConfig.setAdminRole(rep.getAdminRole()); } + if (remoteSkeletonKeyConfig.getAdminRole() == null) { + remoteSkeletonKeyConfig.setAdminRole("$REALM-ADMIN$"); + } String realm = remoteSkeletonKeyConfig.getRealm(); String resource = remoteSkeletonKeyConfig.getResource(); diff --git a/services/pom.xml b/services/pom.xml index 87fa920dd3..fbfe298fdf 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -13,6 +13,11 @@ + + org.bouncycastle + bcprov-jdk16 + provided + org.keycloak keycloak-core diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index f1828f72d2..e9d879ef61 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -97,13 +97,19 @@ public class RealmManager { public void importRealm(RealmRepresentation rep, RealmModel newRealm) { - generateRealmKeys(newRealm); newRealm.setName(rep.getRealm()); newRealm.setEnabled(rep.isEnabled()); newRealm.setTokenLifespan(rep.getTokenLifespan()); newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan()); newRealm.setSslNotRequired(rep.isSslNotRequired()); newRealm.setCookieLoginAllowed(rep.isCookieLoginAllowed()); + if (rep.getPrivateKey() == null || rep.getPublicKey() == null) { + generateRealmKeys(newRealm); + } else { + newRealm.setPrivateKeyPem(rep.getPrivateKey()); + newRealm.setPublicKeyPem(rep.getPublicKey()); + } + newRealm.updateRealm(); diff --git a/services/src/test/java/org/keycloak/test/RealmKeyGenerator.java b/services/src/test/java/org/keycloak/test/RealmKeyGenerator.java new file mode 100755 index 0000000000..4f034d41cd --- /dev/null +++ b/services/src/test/java/org/keycloak/test/RealmKeyGenerator.java @@ -0,0 +1,49 @@ +package org.keycloak.test; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMWriter; +import org.jboss.resteasy.security.PemUtils; +import org.keycloak.services.models.RealmModel; + +import java.io.IOException; +import java.io.StringWriter; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Security; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class RealmKeyGenerator { + static { + if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider()); + } + public static void main(String[] args) throws Exception { + KeyPair keyPair = null; + try { + keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + System.out.println("privateKey : " + printKey(keyPair.getPrivate())); + System.out.println("publicKey : " + printKey(keyPair.getPublic())); + } + + private static String printKey(Object key){ + StringWriter writer = new StringWriter(); + PEMWriter pemWriter = new PEMWriter(writer); + try { + pemWriter.writeObject(key); + pemWriter.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + String s = writer.toString(); + return PemUtils.removeBeginEnd(s); + + } +}