keycloak-uncached
Changes
docbook/reference/en/en-US/modules/saml.xml 18(+17 -1)
Details
docbook/reference/en/en-US/modules/saml.xml 18(+17 -1)
diff --git a/docbook/reference/en/en-US/modules/saml.xml b/docbook/reference/en/en-US/modules/saml.xml
index 1f6a1a3..5ba2e00 100755
--- a/docbook/reference/en/en-US/modules/saml.xml
+++ b/docbook/reference/en/en-US/modules/saml.xml
@@ -89,9 +89,25 @@
</variablelist>
</para>
<para>
+ You have to specify an admin URL if you want logout to work. This should be a URL that will except single logout
+ requests from the Keycloak server. You should also specify a default redirect url. Keycloak will redirect to this
+ url after single logout is complete.
+ </para>
+ <para>
One thing to note is that roles are not treated as a hierarchy. So, any role mappings will just be added
- to the role attributes in the SAML document using their basic name. So, if you have multiple applicaiton roles
+ to the role attributes in the SAML document using their basic name. So, if you have multiple application roles
you might have name collisions. You can use the Scope Mapping menu item to control which role mappings are set
in the response.
</para>
+ <section>
+ <title>SAML Entity Descriptor</title>
+ <para>
+ If you go into the admin console in the application list menu page you will see an <literal>Import</literal>
+ button. If you click on that you can import SAML Service Provider definitions using the <ulink url="http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf">Entity Descriptor</ulink>
+ format described in SAML 2.0. You should review all the information there to make sure everything is set up correctly.
+ </para>
+ <para>
+ Each realm has a URL where you can view the XML entity descriptor for the IDP. <literal>root/realms/{realm}/protocol/saml/descriptor</literal>
+ </para>
+ </section>
</chapter>
diff --git a/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java b/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
index 0ffa42c..73d0cc9 100755
--- a/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
+++ b/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
@@ -102,7 +102,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
}
deploymentContext = new AdapterDeploymentContext(kd);
context.getServletContext().setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext);
- AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deploymentContext, getNext(), getContainer(), getObjectName());
+ AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deploymentContext, getNext(), getContainer());
setNext(actions);
nodesRegistrationManagement = new NodesRegistrationManagement();
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
index 8f51234..1c8c317 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -19,7 +19,9 @@ import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.ClientSessionCode;
+import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.util.StreamUtil;
import org.picketlink.common.constants.GeneralConstants;
import org.picketlink.identity.federation.core.saml.v2.common.SAMLDocumentHolder;
import org.picketlink.identity.federation.saml.v2.SAML2Object;
@@ -32,6 +34,8 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
@@ -42,6 +46,7 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Providers;
+import java.io.InputStream;
import java.net.URI;
import java.security.PublicKey;
import java.security.Signature;
@@ -379,4 +384,19 @@ public class SamlService {
return new PostBindingProtocol().execute(samlRequest, samlResponse, relayState);
}
+ @GET
+ @Path("descriptor")
+ @Produces(MediaType.APPLICATION_XML)
+ public String getDescriptor() throws Exception {
+ InputStream is = getClass().getResourceAsStream("/idp-metadata-template.xml");
+ String template = StreamUtil.readString(is);
+ template = template.replace("${idp.entityID}", RealmsResource.realmBaseUrl(uriInfo).build(realm.getName()).toString());
+ template = template.replace("${idp.sso.HTTP-POST}", RealmsResource.protocolUrl(uriInfo).build(realm.getName(), SamlProtocol.LOGIN_PROTOCOL).toString());
+ template = template.replace("${idp.sso.HTTP-Redirect}", RealmsResource.protocolUrl(uriInfo).build(realm.getName(), SamlProtocol.LOGIN_PROTOCOL).toString());
+ template = template.replace("${idp.sls.HTTP-POST}", RealmsResource.protocolUrl(uriInfo).build(realm.getName(), SamlProtocol.LOGIN_PROTOCOL).toString());
+ template = template.replace("${idp.signing.certificate}", realm.getCertificatePem());
+ return template;
+
+ }
+
}
diff --git a/saml/saml-protocol/src/main/resources/idp-metadata-template.xml b/saml/saml-protocol/src/main/resources/idp-metadata-template.xml
new file mode 100755
index 0000000..5468cfc
--- /dev/null
+++ b/saml/saml-protocol/src/main/resources/idp-metadata-template.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor Name="urn:keycloak"
+ xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <EntityDescriptor entityID="${idp.entityID}">
+ <IDPSSODescriptor WantAuthnRequestsSigned="true"
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ </NameIDFormat>
+ <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="${idp.sso.HTTP-POST}" />
+ <SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="${idp.sso.HTTP-Redirect}" />
+ <SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="${idp.sls.HTTP-POST}" />
+ <KeyDescriptor use="signing">
+ <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ ${idp.signing.certificate}
+ </dsig:X509Certificate>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </KeyDescriptor>
+ </IDPSSODescriptor>
+ </EntityDescriptor>
+</EntitiesDescriptor>
\ No newline at end of file
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 2feeaaa..a7fe6c4 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -77,6 +77,14 @@ public class RealmsResource {
return base.path(RealmsResource.class).path(RealmsResource.class, "getAccountService");
}
+ public static UriBuilder protocolUrl(UriBuilder base) {
+ return base.path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
+ }
+
+ public static UriBuilder protocolUrl(UriInfo uriInfo) {
+ return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
+ }
+
@Path("{realm}/login-status-iframe.html")
@GET
@Produces(MediaType.TEXT_HTML)