Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ If you have trouble creating the patch, consult the Readme in the `/patch-tool`
6. Build the jar from the new branch and test it in our local environment with an eHerkenning-testmiddel.

* A Keycloak upgrade might be needed beforehand.
*
* You could consider also testing it with DigiD using the simulator realm.

6. Create a branch, e.g. `27.2.x-once-PR-merged`, from the previous minor, e.g. `27.1` here.

Expand All @@ -69,6 +69,8 @@ If you have trouble creating the patch, consult the Readme in the `/patch-tool`
* Rename branch `{a}.{b+1}.x-once-PR-merged` to just `{a}.{b+1}.x`, e.g. `27.2.x`.
* Remove branch `upgrade-to-{a}.{b+1}`.

10. Change the repository's main branch to the most recent version branch, `{a}.{b+1}.x`.

## Building

```mvn clean package```
Expand Down
1 change: 0 additions & 1 deletion patch-tool/keycloak-files.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java
services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToRoleMapper.java
services/src/main/java/org/keycloak/broker/saml/mappers/AttributeToRoleMapper.java
services/src/main/java/org/keycloak/broker/saml/mappers/UserAttributeMapper.java
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<description>
SAML v2.0 extensions that adds more configuration options to connect to SAML Service Providers.
</description>
<version>26.4</version>
<version>26.5</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
Expand All @@ -20,7 +20,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<keycloak.version>26.4.7</keycloak.version>
<keycloak.version>26.5.1</keycloak.version>
<spotbugs.version>4.8.3.1</spotbugs.version>

<jib-maven-plugin.version>3.4.1</jib-maven-plugin.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package nl.first8.keycloak.broker.saml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
import nl.first8.keycloak.dom.saml.v2.protocol.ResponseType;
import nl.first8.keycloak.saml.common.constants.GeneralConstants;
Expand All @@ -14,9 +18,6 @@
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.common.util.StaxUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;

public class SAMLDataMarshaller extends DefaultDataMarshaller {
Expand Down
67 changes: 47 additions & 20 deletions src/main/java/nl/first8/keycloak/broker/saml/SAMLEndpoint.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
package nl.first8.keycloak.broker.saml;

import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import java.io.IOException;
import java.net.URI;
import java.security.Key;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Predicate;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.namespace.QName;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;

import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
import nl.first8.keycloak.dom.saml.v2.assertion.AttributeStatementType;
import nl.first8.keycloak.dom.saml.v2.protocol.ResponseType;
import nl.first8.keycloak.protocol.saml.SamlProtocolUtils;
import nl.first8.keycloak.saml.SAMLRequestParser;
import nl.first8.keycloak.saml.common.constants.GeneralConstants;
import nl.first8.keycloak.saml.common.constants.JBossSAMLConstants;
Expand All @@ -15,7 +45,7 @@
import org.jboss.resteasy.reactive.NoCache;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.IdentityProvider;
import org.keycloak.broker.provider.UserAuthenticationIdentityProvider;
import org.keycloak.common.ClientConnection;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.Base64;
Expand All @@ -35,7 +65,14 @@
import org.keycloak.models.*;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.LoginProtocolFactory;
import org.keycloak.protocol.saml.*;
import org.keycloak.protocol.saml.SAMLDecryptionKeysLocator;
import org.keycloak.protocol.saml.SamlMetadataKeyLocator;
import org.keycloak.protocol.saml.SamlMetadataPublicKeyLoader;
import org.keycloak.protocol.saml.SamlPrincipalType;
import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.protocol.saml.SamlProtocolUtils;
import org.keycloak.protocol.saml.SamlService;
import org.keycloak.protocol.saml.SamlSessionUtils;
import org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor;
import org.keycloak.rotation.HardcodedKeyLocator;
import org.keycloak.rotation.KeyLocator;
Expand All @@ -56,22 +93,12 @@
import org.keycloak.services.messages.Messages;
import org.keycloak.services.util.CacheControlUtil;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.util.Booleans;
import org.keycloak.utils.StringUtil;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.net.URI;
import java.security.Key;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class SAMLEndpoint {
protected static final Logger logger = Logger.getLogger(SAMLEndpoint.class);
public static final String SAML_FEDERATED_SESSION_INDEX = "SAML_FEDERATED_SESSION_INDEX";
Expand All @@ -86,7 +113,7 @@ public class SAMLEndpoint {
protected final RealmModel realm;
protected EventBuilder event;
protected final SAMLIdentityProviderConfig config;
protected final IdentityProvider.AuthenticationCallback callback;
protected final UserAuthenticationIdentityProvider.AuthenticationCallback callback;
protected final SAMLIdentityProvider provider;
private final DestinationValidator destinationValidator;

Expand All @@ -100,7 +127,7 @@ public class SAMLEndpoint {
public SAMLEndpoint(KeycloakSession session,
SAMLIdentityProvider provider,
SAMLIdentityProviderConfig config,
IdentityProvider.AuthenticationCallback callback,
UserAuthenticationIdentityProvider.AuthenticationCallback callback,
DestinationValidator destinationValidator) {
this.realm = session.getContext().getRealm();
this.config = config;
Expand Down Expand Up @@ -526,7 +553,7 @@ protected Response handleLoginResponse(String samlResponse, SAMLDocumentHolder h
identity.setEmail(subjectNameID.getValue());
}

if (config.isStoreToken()) {
if (Booleans.isTrue(config.isStoreToken())) {
identity.setToken(samlResponse);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
package nl.first8.keycloak.broker.saml;

import java.net.URI;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.xml.parsers.ParserConfigurationException;

import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;

import nl.first8.keycloak.dom.saml.v2.metadata.AttributeConsumingService;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
Expand All @@ -8,12 +28,12 @@
import nl.first8.keycloak.dom.saml.v2.metadata.AttributeConsumingServiceType;
import nl.first8.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
import nl.first8.keycloak.protocol.saml.JaxrsSAML2BindingBuilder;
import org.keycloak.protocol.saml.SAMLEncryptionAlgorithms;
import nl.first8.keycloak.saml.SAML2ArtifactResolutionBuilder;
import nl.first8.keycloak.saml.SPMetadataDescriptorBuilder;
import nl.first8.keycloak.saml.common.constants.GeneralConstants;
import nl.first8.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
import nl.first8.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter;
import org.jboss.logging.Logger;
import org.keycloak.broker.provider.*;
import org.keycloak.common.util.PemUtils;
import org.keycloak.crypto.Algorithm;
Expand Down Expand Up @@ -46,22 +66,19 @@
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
import org.keycloak.saml.validators.DestinationValidator;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.util.Booleans;
import org.keycloak.util.JsonSerialization;

import org.jboss.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.stream.Collectors;

import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC;

Expand Down Expand Up @@ -115,7 +132,7 @@ public Response performLogin(AuthenticationRequest request) {

Integer attributeConsumingServiceIndex = getConfig().getAttributeConsumingServiceIndex();

String loginHint = getConfig().isLoginHint() ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
String loginHint = Booleans.isTrue(getConfig().isLoginHint()) ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
Boolean allowCreate = null;
if (getConfig().getConfig().get(org.keycloak.broker.saml.SAMLIdentityProviderConfig.ALLOW_CREATE) == null || getConfig().isAllowCreate())
allowCreate = Boolean.TRUE;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package nl.first8.keycloak.broker.saml.mappers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import nl.first8.keycloak.broker.saml.SAMLEndpoint;
import nl.first8.keycloak.broker.saml.SAMLIdentityProviderFactory;
import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
Expand All @@ -12,9 +20,6 @@
import org.keycloak.models.IdentityProviderSyncMode;
import org.keycloak.provider.ProviderConfigProperty;

import java.util.*;
import java.util.stream.Collectors;

import static org.keycloak.utils.RegexUtils.valueMatchesRegex;

public class AdvancedAttributeToRoleMapper extends AbstractAttributeToRoleMapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package nl.first8.keycloak.broker.saml.mappers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import nl.first8.keycloak.broker.saml.SAMLEndpoint;
import nl.first8.keycloak.broker.saml.SAMLIdentityProviderFactory;
import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
Expand All @@ -19,9 +27,9 @@
import org.keycloak.protocol.saml.mappers.SamlMetadataDescriptorUpdater;
import org.keycloak.provider.ProviderConfigProperty;

import java.util.*;
import java.util.stream.Collectors;


import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
package nl.first8.keycloak.broker.saml.mappers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import nl.first8.keycloak.broker.saml.SAMLIdentityProviderFactory;
import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
import nl.first8.keycloak.dom.saml.v2.assertion.AttributeStatementType;
Expand Down Expand Up @@ -28,11 +42,6 @@

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package nl.first8.keycloak.broker.saml.mappers;

import org.keycloak.broker.saml.SAMLEndpoint;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import nl.first8.keycloak.broker.saml.SAMLIdentityProviderFactory;
import nl.first8.keycloak.dom.saml.v2.assertion.AssertionType;
import nl.first8.keycloak.dom.saml.v2.assertion.AttributeStatementType;
Expand All @@ -11,27 +21,28 @@
import nl.first8.keycloak.protocol.saml.mappers.SamlMetadataDescriptorUpdater;
import nl.first8.keycloak.saml.encryption.DecryptionException;
import nl.first8.keycloak.saml.encryption.SamlDecrypter;

import org.jboss.logging.Logger;
import org.keycloak.broker.provider.AbstractIdentityProviderMapper;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.saml.SAMLEndpoint;
import org.keycloak.common.util.CollectionUtil;
import org.keycloak.crypto.Algorithm;
import org.keycloak.crypto.KeyUse;
import org.keycloak.crypto.KeyWrapper;
import org.keycloak.dom.saml.v2.assertion.AttributeType;
import org.keycloak.models.*;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderSyncMode;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.common.util.StringUtil;

import java.security.PrivateKey;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC;


public class UserEncryptedAttributeMapper extends AbstractIdentityProviderMapper implements SamlMetadataDescriptorUpdater {

protected static final Logger logger = Logger.getLogger(UserEncryptedAttributeMapper.class);
Expand Down
Loading