adapter refactor
This commit is contained in:
parent
333ad0efac
commit
3f792030d3
23 changed files with 171 additions and 48 deletions
|
@ -25,8 +25,8 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.protocol.saml.SAMLRequestParser;
|
||||
import org.keycloak.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.saml.SAMLRequestParser;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.protocol.saml.SamlProtocolUtils;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
|
|
|
@ -34,20 +34,16 @@ import org.keycloak.models.FederatedIdentityModel;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2AuthnRequestBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2LogoutRequestBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2NameIDPolicyBuilder;
|
||||
import org.keycloak.saml.SAML2AuthnRequestBuilder;
|
||||
import org.keycloak.saml.SAML2LogoutRequestBuilder;
|
||||
import org.keycloak.saml.SAML2NameIDPolicyBuilder;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
|
|
@ -9,11 +9,11 @@ import org.keycloak.KeycloakPrincipal;
|
|||
*/
|
||||
public abstract class RequestAuthenticator {
|
||||
protected static Logger log = Logger.getLogger(RequestAuthenticator.class);
|
||||
|
||||
protected HttpFacade facade;
|
||||
protected AuthChallenge challenge;
|
||||
|
||||
protected KeycloakDeployment deployment;
|
||||
protected AdapterTokenStore tokenStore;
|
||||
protected AuthChallenge challenge;
|
||||
protected int sslRedirectPort;
|
||||
|
||||
public RequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort) {
|
||||
|
|
60
saml/client-adapter/core/pom.xml
Executable file
60
saml/client-adapter/core/pom.xml
Executable file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.5.0.Final-SNAPSHOT</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-saml-adapter-core</artifactId>
|
||||
<name>Keycloak SAML Adapter Core</name>
|
||||
<description/>
|
||||
|
||||
<properties>
|
||||
<timestamp>${maven.build.timestamp}</timestamp>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,25 @@
|
|||
package org.keycloak.adapters.saml;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.adapters.AuthChallenge;
|
||||
import org.keycloak.adapters.AuthOutcome;
|
||||
import org.keycloak.adapters.HttpFacade;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SamlAuthenticator {
|
||||
protected static Logger log = Logger.getLogger(SamlAuthenticator.class);
|
||||
|
||||
protected HttpFacade facade;
|
||||
protected AuthChallenge challenge;
|
||||
|
||||
public AuthChallenge getChallenge() {
|
||||
return challenge;
|
||||
}
|
||||
|
||||
public AuthOutcome authenticate() {
|
||||
return null;
|
||||
}
|
||||
}
|
19
saml/client-adapter/pom.xml
Executable file
19
saml/client-adapter/pom.xml
Executable file
|
@ -0,0 +1,19 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.5.0.Final-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Client Adapter Modules</name>
|
||||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-saml-client-adapter-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>core</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -16,5 +16,6 @@
|
|||
<modules>
|
||||
<module>saml-core</module>
|
||||
<module>saml-protocol</module>
|
||||
<module>client-adapter</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
<artifactId>jboss-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.santuario</groupId>
|
||||
<artifactId>xmlsec</artifactId>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
|
@ -177,7 +177,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
|
||||
|
||||
|
||||
private String getSAMLNSPrefix(Document samlResponseDocument) {
|
||||
public String getSAMLNSPrefix(Document samlResponseDocument) {
|
||||
Node assertionElement = samlResponseDocument.getDocumentElement()
|
||||
.getElementsByTagNameNS(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ASSERTION.get()).item(0);
|
||||
|
||||
|
@ -188,14 +188,14 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
return assertionElement.getPrefix();
|
||||
}
|
||||
|
||||
protected void encryptDocument(Document samlDocument) throws ProcessingException {
|
||||
public void encryptDocument(Document samlDocument) throws ProcessingException {
|
||||
String samlNSPrefix = getSAMLNSPrefix(samlDocument);
|
||||
|
||||
try {
|
||||
QName encryptedAssertionElementQName = new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(),
|
||||
JBossSAMLConstants.ENCRYPTED_ASSERTION.get(), samlNSPrefix);
|
||||
|
||||
byte[] secret = SamlProtocolUtils.createRandomSecret(encryptionKeySize / 8);
|
||||
byte[] secret = RandomSecret.createRandomSecret(encryptionKeySize / 8);
|
||||
SecretKey secretKey = new SecretKeySpec(secret, encryptionAlgorithm);
|
||||
|
||||
// encrypt the Assertion element and replace it with a EncryptedAssertion element.
|
||||
|
@ -208,7 +208,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
|
||||
}
|
||||
|
||||
protected void signDocument(Document samlDocument) throws ProcessingException {
|
||||
public void signDocument(Document samlDocument) throws ProcessingException {
|
||||
String signatureMethod = signatureAlgorithm.getXmlSignatureMethod();
|
||||
String signatureDigestMethod = signatureAlgorithm.getXmlSignatureDigestMethod();
|
||||
SAML2Signature samlSignature = new SAML2Signature();
|
||||
|
@ -232,7 +232,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
samlSignature.signSAMLDocument(samlDocument, signingKeyPair, canonicalizationMethodType);
|
||||
}
|
||||
|
||||
protected void signAssertion(Document samlDocument) throws ProcessingException {
|
||||
public void signAssertion(Document samlDocument) throws ProcessingException {
|
||||
Element originalAssertionElement = org.keycloak.saml.common.util.DocumentUtil.getChildElement(samlDocument.getDocumentElement(), new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ASSERTION.get()));
|
||||
if (originalAssertionElement == null) return;
|
||||
Node clonedAssertionElement = originalAssertionElement.cloneNode(true);
|
||||
|
@ -257,14 +257,14 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
}
|
||||
|
||||
|
||||
protected String buildHtmlPostResponse(Document responseDoc, String actionUrl, boolean asRequest) throws ProcessingException, ConfigurationException, IOException {
|
||||
public String buildHtmlPostResponse(Document responseDoc, String actionUrl, boolean asRequest) throws ProcessingException, ConfigurationException, IOException {
|
||||
byte[] responseBytes = org.keycloak.saml.common.util.DocumentUtil.getDocumentAsString(responseDoc).getBytes("UTF-8");
|
||||
String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes));
|
||||
|
||||
return buildHtml(samlResponse, actionUrl, asRequest);
|
||||
}
|
||||
|
||||
protected String buildHtml(String samlResponse, String actionUrl, boolean asRequest) {
|
||||
public String buildHtml(String samlResponse, String actionUrl, boolean asRequest) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String key = GeneralConstants.SAML_RESPONSE_KEY;
|
||||
|
@ -297,7 +297,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
protected String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||
public String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||
String documentAsString = DocumentUtil.getDocumentAsString(document);
|
||||
logger.debugv("saml docment: {0}", documentAsString);
|
||||
byte[] responseBytes = documentAsString.getBytes("UTF-8");
|
||||
|
@ -306,7 +306,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
|||
}
|
||||
|
||||
|
||||
protected URI generateRedirectUri(String samlParameterName, String redirectUri, Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||
public URI generateRedirectUri(String samlParameterName, String redirectUri, Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||
KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(redirectUri)
|
||||
.replaceQuery(null)
|
||||
.queryParam(samlParameterName, base64Encoded(document));
|
25
saml/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java
Executable file
25
saml/saml-core/src/main/java/org/keycloak/saml/RandomSecret.java
Executable file
|
@ -0,0 +1,25 @@
|
|||
package org.keycloak.saml;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RandomSecret {
|
||||
/**
|
||||
* <p>
|
||||
* Creates a random {@code byte[]} secret of the specified size.
|
||||
* </p>
|
||||
*
|
||||
* @param size the size of the secret to be created, in bytes.
|
||||
*
|
||||
* @return a {@code byte[]} containing the generated secret.
|
||||
*/
|
||||
public static byte[] createRandomSecret(final int size) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] secret = new byte[size];
|
||||
random.nextBytes(secret);
|
||||
return secret;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
|
|
@ -1,7 +1,6 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
|
||||
import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.PicketLinkLogger;
|
||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
|
@ -15,7 +15,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.dom.saml.v2.protocol.NameIDPolicyType;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import org.keycloak.saml.common.PicketLinkLogger;
|
||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
package org.keycloak.saml;
|
||||
|
||||
import java.security.Signature;
|
||||
import java.util.HashMap;
|
|
@ -5,6 +5,7 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
|
|||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.saml.SignatureAlgorithm;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.protocol.saml;
|
||||
|
||||
import org.keycloak.saml.BaseSAML2BindingBuilder;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.w3c.dom.Document;
|
||||
|
|
|
@ -26,6 +26,11 @@ import org.keycloak.protocol.RestartLoginCookie;
|
|||
import org.keycloak.protocol.saml.mappers.SAMLAttributeStatementMapper;
|
||||
import org.keycloak.protocol.saml.mappers.SAMLLoginResponseMapper;
|
||||
import org.keycloak.protocol.saml.mappers.SAMLRoleListMapper;
|
||||
import org.keycloak.saml.SAML2ErrorResponseBuilder;
|
||||
import org.keycloak.saml.SAML2LoginResponseBuilder;
|
||||
import org.keycloak.saml.SAML2LogoutRequestBuilder;
|
||||
import org.keycloak.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.saml.SignatureAlgorithm;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.protocol.saml;
|
|||
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.saml.SignatureAlgorithm;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature;
|
||||
|
@ -23,22 +24,6 @@ import java.security.cert.Certificate;
|
|||
*/
|
||||
public class SamlProtocolUtils {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Creates a random {@code byte[]} secret of the specified size.
|
||||
* </p>
|
||||
*
|
||||
* @param size the size of the secret to be created, in bytes.
|
||||
*
|
||||
* @return a {@code byte[]} containing the generated secret.
|
||||
*/
|
||||
public static byte[] createRandomSecret(final int size) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] secret = new byte[size];
|
||||
random.nextBytes(secret);
|
||||
return secret;
|
||||
}
|
||||
|
||||
|
||||
public static void verifyDocumentSignature(ClientModel client, Document document) throws VerificationException {
|
||||
if (!"true".equals(client.getAttribute(SamlProtocol.SAML_CLIENT_SIGNATURE_ATTRIBUTE))) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.keycloak.protocol.saml;
|
|||
import org.jboss.logging.Logger;
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.jboss.resteasy.spi.HttpResponse;
|
||||
import org.jboss.resteasy.spi.NotFoundException;
|
||||
import org.keycloak.ClientConnection;
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.authentication.AuthenticationProcessor;
|
||||
|
@ -24,10 +23,12 @@ import org.keycloak.models.IdentityProviderModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.RestartLoginCookie;
|
||||
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
||||
import org.keycloak.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.saml.SAMLRequestParser;
|
||||
import org.keycloak.saml.SignatureAlgorithm;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||
|
|
Loading…
Reference in a new issue