keycloak-uncached

2213

1/7/2016 8:25:47 PM

Details

diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
index f80e57a..9729c9c 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
@@ -709,33 +709,6 @@ module.controller('ClientInstallationCtrl', function($scope, realm, client, serv
             $scope.installation = installation;
         })
     };
-
-
-    /*
-    $scope.changeFormat = function() {
-        if ($scope.configFormat == "Keycloak JSON") {
-            $scope.filename = 'keycloak.json';
-
-            var url = ClientInstallation.url({ realm: $routeParams.realm, client: $routeParams.client });
-            $http.get(url).success(function(data) {
-                var tmp = angular.fromJson(data);
-                $scope.installation = angular.toJson(tmp, true);
-                $scope.type = 'application/json';
-            })
-        } else if ($scope.configFormat == "Wildfly/EAP Subsystem XML") {
-            $scope.filename = 'keycloak.xml';
-
-            var url = ClientInstallationJBoss.url({ realm: $routeParams.realm, client: $routeParams.client });
-            $http.get(url).success(function(data) {
-                $scope.installation = data;
-                $scope.type = 'text/xml';
-            })
-        }
-
-        console.debug($scope.filename);
-    };
-    */
-
     $scope.download = function() {
         saveAs(new Blob([$scope.installation], { type: $scope.configFormat.mediaType }), $scope.configFormat.filename);
     }
@@ -1080,7 +1053,7 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, templates,
 module.controller('CreateClientCtrl', function($scope, realm, client, templates, $route, serverInfo, Client, ClientDescriptionConverter, $location, $modal, Dialog, Notifications) {
     $scope.protocols = ['openid-connect',
         'saml'];//Object.keys(serverInfo.providers['login-protocol'].providers).sort();
-
+    $scope.create = true;
     $scope.templates = [ {name:'NONE'}];
     for (var i = 0; i < templates.length; i++) {
         var template = templates[i];
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-client.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-client.html
index 6f56467..58388ff 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-client.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-client.html
@@ -33,7 +33,7 @@
 
         <li ng-class="{active: path[4] == 'clustering'}" data-ng-show="!client.publicClient"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering">{{:: 'clustering' | translate}}</a></li>
 
-        <li ng-class="{active: path[4] == 'installation'}" data-ng-show="client.protocol != 'saml'">
+        <li ng-class="{active: path[4] == 'installation'}">
             <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/installation">{{:: 'installation' | translate}}</a>
             <kc-tooltip>{{:: 'installation.tooltip' | translate}}</kc-tooltip>
         </li>
diff --git a/model/sessions-infinispan/pom.xml b/model/sessions-infinispan/pom.xml
index c4f57b0..553895c 100755
--- a/model/sessions-infinispan/pom.xml
+++ b/model/sessions-infinispan/pom.xml
@@ -36,4 +36,16 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
index 5de2072..e0564e9 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
@@ -98,12 +98,26 @@ public class DeploymentBuilder {
 
                 }
                 if (key.isEncryption()) {
-                    KeyStore keyStore = loadKeystore(resourceLoader, key);
-                    try {
-                        PrivateKey privateKey = (PrivateKey) keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray());
-                        deployment.setDecryptionKey(privateKey);
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
+                    if (key.getKeystore() != null) {
+
+                        KeyStore keyStore = loadKeystore(resourceLoader, key);
+                        try {
+                            PrivateKey privateKey = (PrivateKey) keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray());
+                            deployment.setDecryptionKey(privateKey);
+                        } catch (Exception e) {
+                            throw new RuntimeException(e);
+                        }
+                    } else {
+                        if (key.getPrivateKeyPem() == null) {
+                            throw new RuntimeException("SP signing key must have a PrivateKey defined");
+                        }
+                        try {
+                            PrivateKey privateKey = PemUtils.decodePrivateKey(key.getPrivateKeyPem().trim());
+                            deployment.setDecryptionKey(privateKey);
+                        } catch (Exception e) {
+                            throw new RuntimeException(e);
+                        }
+
                     }
                 }
             }
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
index 20f7810..61ecbdc 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
@@ -116,7 +116,7 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo
                 attributes.put(SamlConfigAttributes.SAML_SIGNING_CERTIFICATE_ATTRIBUTE, certPem);
             } else if (keyDescriptor.getUse() == KeyTypes.ENCRYPTION) {
                 attributes.put(SamlConfigAttributes.SAML_ENCRYPT, SamlProtocol.ATTRIBUTE_TRUE_VALUE);
-                attributes.put(SamlProtocol.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, certPem);
+                attributes.put(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, certPem);
             }
         }
 
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java
new file mode 100755
index 0000000..d3abddf
--- /dev/null
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java
@@ -0,0 +1,161 @@
+package org.keycloak.protocol.saml.installation;
+
+import org.keycloak.Config;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.protocol.ClientInstallationProvider;
+import org.keycloak.protocol.saml.SamlClient;
+import org.keycloak.protocol.saml.SamlProtocol;
+import org.keycloak.services.resources.RealmsResource;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class KeycloakSamlClientInstallation implements ClientInstallationProvider {
+
+    @Override
+    public Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI baseUri) {
+        SamlClient samlClient = new SamlClient(client);
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("<keycloak-saml-adapter>\n");
+        buffer.append("    <SP entityID=\"").append(client.getClientId()).append("\"\n");
+        buffer.append("        sslPolicy=\"").append(realm.getSslRequired().name()).append("\"\n");
+        buffer.append("        logoutPage=\"SPECIFY YOUR LOGOUT PAGE!\">\n");
+        if (samlClient.requiresClientSignature() || samlClient.requiresEncryption()) {
+            buffer.append("        <Keys>\n");
+            if (samlClient.requiresClientSignature()) {
+                buffer.append("            <Key signing=\"true\">\n");
+                buffer.append("                <PrivateKeyPem>\n");
+                if (samlClient.getClientSigningPrivateKey() == null) {
+                    buffer.append("                    PRIVATE KEY NOT SET UP OR KNOWN\n");
+                } else {
+                    buffer.append("                    ").append(samlClient.getClientSigningPrivateKey()).append("\n");
+                }
+                buffer.append("                </PrivateKeyPem>\n");
+                buffer.append("                <CertificatePem>\n");
+                if (samlClient.getClientSigningCertificate() == null) {
+                    buffer.append("                    YOU MUST CONFIGURE YOUR CLIENT's SIGNING CERTIFICATE\n");
+                } else {
+                    buffer.append("                    ").append(samlClient.getClientSigningCertificate()).append("\n");
+                }
+                buffer.append("                </CertificatePem>\n");
+                buffer.append("            </Key>\n");
+            }
+            if (samlClient.requiresEncryption()) {
+                buffer.append("            <Key encryption=\"true\">\n");
+                buffer.append("                <PrivateKeyPem>\n");
+                if (samlClient.getClientEncryptingPrivateKey() == null) {
+                    buffer.append("                    PRIVATE KEY NOT SET UP OR KNOWN\n");
+                } else {
+                    buffer.append("                    ").append(samlClient.getClientEncryptingPrivateKey()).append("\n");
+                }
+                buffer.append("                </PrivateKeyPem>\n");
+                buffer.append("            </Key>\n");
+
+            }
+            buffer.append("        </Keys>\n");
+        }
+        buffer.append("        <IDP entityID=\"idp\"");
+        if (samlClient.requiresClientSignature()) {
+            buffer.append("\n             signatureAlgorithm=\"").append(samlClient.getSignatureAlgorithm()).append("\"");
+            if (samlClient.getCanonicalizationMethod() != null) {
+                buffer.append("\n             signatureCanonicalizationMethod=\"").append(samlClient.getCanonicalizationMethod()).append("\"");
+            }
+        }
+        buffer.append(">\n");
+        buffer.append("            <SingleSignOnService signRequest=\"").append(Boolean.toString(samlClient.requiresClientSignature())).append("\"\n");
+        buffer.append("                                 validateResponseSignature=\"").append(Boolean.toString(samlClient.requiresRealmSignature())).append("\"\n");
+        buffer.append("                                 requestBinding=\"POST\"\n");
+        UriBuilder bindingUrlBuilder = UriBuilder.fromUri(baseUri);
+        String bindingUrl = RealmsResource.protocolUrl(bindingUrlBuilder)
+                .build(realm.getName(), SamlProtocol.LOGIN_PROTOCOL).toString();
+        buffer.append("                                 bindingUrl=\"").append(bindingUrl).append("\"/>\n");
+
+        buffer.append("            <SingleLogoutService signRequest=\"").append(Boolean.toString(samlClient.requiresClientSignature())).append("\"\n");
+        buffer.append("                                 signResponse=\"").append(Boolean.toString(samlClient.requiresClientSignature())).append("\"\n");
+        buffer.append("                                 validateRequestSignature=\"").append(Boolean.toString(samlClient.requiresRealmSignature())).append("\"\n");
+        buffer.append("                                 validateResponseSignature=\"").append(Boolean.toString(samlClient.requiresRealmSignature())).append("\"\n");
+        buffer.append("                                 requestBinding=\"POST\"\n");
+        buffer.append("                                 responseBinding=\"POST\"\n");
+        buffer.append("                                 postBindingUrl=\"").append(bindingUrl).append("\"\n");
+        buffer.append("                                 redirectBindingUrl=\"").append(bindingUrl).append("\"");
+        buffer.append("/>\n");
+        if (samlClient.requiresRealmSignature()) {
+            buffer.append("            <Keys>\n");
+            buffer.append("                <Key signing=\"true\">\n");
+            buffer.append("                    <CertificatePem>\n");
+            buffer.append("                       ").append(realm.getCertificatePem()).append("\n");
+            buffer.append("                    </CertificatePem>\n");
+            buffer.append("                </Key>\n");
+            buffer.append("            </Keys>\n");
+        }
+        buffer.append("        </IDP>\n");
+        buffer.append("    </SP>\n");
+        buffer.append("</keycloak-saml-adapter>\n");
+        return Response.ok(buffer.toString(), MediaType.TEXT_PLAIN_TYPE).build();
+    }
+
+    @Override
+    public String getProtocol() {
+        return SamlProtocol.LOGIN_PROTOCOL;
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Keycloak SAML Adapter keycloak-saml.xml";
+    }
+
+    @Override
+    public String getHelpText() {
+        return "Keycloak SAML adapter configuration file.  Put this in WEB-INF directory if your WAR.";
+    }
+
+    @Override
+    public String getFilename() {
+        return "keycloak-saml.xml";
+    }
+
+    @Override
+    public String getMediaType() {
+        return MediaType.APPLICATION_XML;
+    }
+
+    @Override
+    public boolean isDownloadOnly() {
+        return false;
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public ClientInstallationProvider create(KeycloakSession session) {
+        return this;
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+
+    }
+
+    @Override
+    public String getId() {
+        return "keycloak-saml";
+    }
+}
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlClient.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlClient.java
index d935f83..3ac9892 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlClient.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlClient.java
@@ -121,4 +121,21 @@ public class SamlClient extends ClientConfigResolver {
 
     }
 
+    public String getClientEncryptingCertificate() {
+        return client.getAttribute(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE);
+    }
+
+    public void setClientEncryptingCertificate(String val) {
+        client.setAttribute(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, val);
+
+    }
+    public String getClientEncryptingPrivateKey() {
+        return client.getAttribute(SamlConfigAttributes.SAML_ENCRYPTION_PRIVATE_KEY_ATTRIBUTE);
+    }
+
+    public void setClientEncryptingPrivateKey(String val) {
+        client.setAttribute(SamlConfigAttributes.SAML_ENCRYPTION_PRIVATE_KEY_ATTRIBUTE, val);
+
+    }
+
 }
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java
index eea258a..c6bc60a 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java
@@ -19,4 +19,6 @@ public interface SamlConfigAttributes {
     String SAML_ENCRYPT = "saml.encrypt";
     String SAML_CLIENT_SIGNATURE_ATTRIBUTE = "saml.client.signature";
     String SAML_SIGNING_CERTIFICATE_ATTRIBUTE = "saml.signing." + ClientAttributeCertificateResource.X509CERTIFICATE;
+    String SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE = "saml.encryption." + ClientAttributeCertificateResource.X509CERTIFICATE;
+    String SAML_ENCRYPTION_PRIVATE_KEY_ATTRIBUTE = "saml.encryption." + ClientAttributeCertificateResource.PRIVATE_KEY;
 }
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index e7bd3eb..c76c853 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -70,7 +70,6 @@ public class SamlProtocol implements LoginProtocol {
 
     public static final String ATTRIBUTE_TRUE_VALUE = "true";
     public static final String ATTRIBUTE_FALSE_VALUE = "false";
-    public static final String SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE = "saml.encryption." + ClientAttributeCertificateResource.X509CERTIFICATE;
     public static final String SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE = "saml_assertion_consumer_url_post";
     public static final String SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE = "saml_assertion_consumer_url_redirect";
     public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE = "saml_single_logout_service_url_post";
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
index 5742f7d..3e03ed4 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
@@ -49,7 +49,7 @@ public class SamlProtocolUtils {
     }
 
     public static PublicKey getEncryptionValidationKey(ClientModel client) throws VerificationException {
-        return getPublicKey(client, SamlProtocol.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE);
+        return getPublicKey(client, SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE);
     }
 
     public static PublicKey getPublicKey(ClientModel client, String attribute) throws VerificationException {
diff --git a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ClientInstallationProvider b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ClientInstallationProvider
new file mode 100755
index 0000000..f8e9df5
--- /dev/null
+++ b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ClientInstallationProvider
@@ -0,0 +1 @@
+org.keycloak.protocol.saml.installation.KeycloakSamlClientInstallation
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index a1a3acc..e0ea200 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -57,6 +57,10 @@ public class RealmsResource {
         return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
     }
 
+    public static UriBuilder protocolUrl(UriBuilder builder) {
+        return builder.path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
+    }
+
     public static UriBuilder clientRegistrationUrl(UriInfo uriInfo) {
         return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getClientsService");
     }