keycloak-uncached

Details

diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/StaxParserUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxParserUtil.java
index 8667a90..8cba8eb 100755
--- a/saml-core/src/main/java/org/keycloak/saml/common/util/StaxParserUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxParserUtil.java
@@ -94,6 +94,20 @@ public class StaxParserUtil {
     }
 
     /**
+     * Bypass an entire XML element block from startElement to endElement.
+     * It is expected that the {@code xmlEventReader} is positioned at (has not yet read)
+     * the start element of the block it should bypass.
+     *
+     * @param xmlEventReader
+     * @param tag Tag of the XML element that we need to bypass
+     *
+     * @throws org.keycloak.saml.common.exceptions.ParsingException
+     */
+    public static void bypassElementBlock(XMLEventReader xmlEventReader, JBossSAMLConstants tag) throws ParsingException {
+        bypassElementBlock(xmlEventReader, tag == null ? null : tag.get());
+    }
+
+    /**
      * Bypass an entire XML element block.
      * It is expected that the {@code xmlEventReader} is positioned at (has not yet read)
      * the start element of the block it should bypass.
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java
index f1d3349..8cf9482 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParser.java
@@ -78,6 +78,8 @@ public class SAMLAuthNRequestParser extends SAMLRequestAbstractParser implements
                 continue;
             } else if (JBossSAMLConstants.EXTENSIONS.get().equals(elementName)) {
                 continue;
+            } else if (JBossSAMLConstants.SCOPING.get().equals(elementName)) {
+                StaxParserUtil.bypassElementBlock(xmlEventReader, JBossSAMLConstants.SCOPING);
             } else
                 throw new RuntimeException(ErrorCodes.UNKNOWN_START_ELEMENT + elementName + "::location="
                         + startElement.getLocation());
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java
index e63860c..2070730 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLSloResponseParser.java
@@ -58,7 +58,7 @@ public class SAMLSloResponseParser extends SAMLStatusResponseTypeParser implemen
                 issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
                 response.setIssuer(issuer);
             } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
-                StaxParserUtil.bypassElementBlock(xmlEventReader, JBossSAMLConstants.SIGNATURE.get());
+                StaxParserUtil.bypassElementBlock(xmlEventReader, JBossSAMLConstants.SIGNATURE);
             } else if (JBossSAMLConstants.EXTENSIONS.get().equals(elementName)) {
                 SAMLExtensionsParser extensionsParser = new SAMLExtensionsParser();
                 response.setExtensions(extensionsParser.parse(xmlEventReader));
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParserTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParserTest.java
index e16a3d0..e1efea8 100644
--- a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParserTest.java
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAuthNRequestParserTest.java
@@ -73,8 +73,9 @@ public class SAMLAuthNRequestParserTest {
             assertThat(req.getNameIDPolicy().getFormat().toString(), is("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"));
 
             assertThat(req.getExtensions(), not(nullValue()));
-            assertThat(req.getExtensions().getAny().size(), is(1));
+            assertThat(req.getExtensions().getAny().size(), is(2));
             assertThat(req.getExtensions().getAny().get(0), instanceOf(Element.class));
+            assertThat(req.getExtensions().getAny().get(1), instanceOf(Element.class));
             Element el = (Element) req.getExtensions().getAny().get(0);
             assertThat(el.getLocalName(), is("KeyInfo"));
             assertThat(el.getNamespaceURI(), is("urn:keycloak:ext:key:1.0"));
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
index d5df478..839847f 100644
--- a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
@@ -42,6 +42,7 @@ import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
 import org.keycloak.dom.saml.v2.assertion.AttributeType;
 import org.keycloak.dom.saml.v2.assertion.NameIDType;
 import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
+import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
 import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
 import org.keycloak.dom.saml.v2.protocol.ResponseType;
 import org.keycloak.saml.common.exceptions.ParsingException;
@@ -253,6 +254,14 @@ public class SAMLParserTest {
     }
 
     @Test
+    public void testAuthnRequestScoping() throws Exception {
+        try (InputStream st = SAMLParserTest.class.getResourceAsStream("KEYCLOAK-6109-authnrequest-scoping.xml")) {
+            Object parsedObject = parser.parse(st);
+            assertThat(parsedObject, instanceOf(AuthnRequestType.class));
+        }
+    }
+
+    @Test
     public void testSaml20AssertionsAnyTypeAttributeValue() throws Exception {
 
         String[] xmlSamples = {
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-6109-authnrequest-scoping.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-6109-authnrequest-scoping.xml
new file mode 100644
index 0000000..43d5998
--- /dev/null
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-6109-authnrequest-scoping.xml
@@ -0,0 +1,14 @@
+<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
+                    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+                    ID="_c327a0622c69920a4bdefa8a2fd98847b67cf18473"
+                    Version="2.0"
+                    IssueInstant="2017-11-16T07:09:05Z"
+                    Destination="https://idp.example.com/auth/realms/MYIDP/protocol/saml"
+                    AssertionConsumerServiceURL="https://iif.example.com/idp/module.php/saml/sp/saml2-acs.php/default-sp"
+                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+                    >
+    <saml:Issuer>https://iif.example.com/idp/module.php/saml/sp/metadata.php/default-sp</saml:Issuer>
+    <samlp:Scoping>
+        <samlp:RequesterID>https://some.domain/sp</samlp:RequesterID>
+    </samlp:Scoping>
+</samlp:AuthnRequest>
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-authnrequest-with-extension.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-authnrequest-with-extension.xml
index 655eae6..9781fc0 100644
--- a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-authnrequest-with-extension.xml
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-authnrequest-with-extension.xml
@@ -4,5 +4,8 @@
     <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
     <samlp:Extensions>
         <kckey:KeyInfo xmlns:kckey="urn:keycloak:ext:key:1.0" MessageSigningKeyId="FJ86GcF3jTbNLOco4NvZkUCIUmfYCqoqtOQeMfbhNlE"/>
+        <saml:Invalid xmlns:a="urn:invalid">
+            <a:a>text</a:a>
+        </saml:Invalid>
     </samlp:Extensions>
 </samlp:AuthnRequest>
\ No newline at end of file
diff --git a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
index 0a26062..13deac5 100755
--- a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
+++ b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
@@ -52,7 +52,7 @@ public enum JBossSAMLConstants {
             "OrganizationUrl"), PDP_DESCRIPTOR("PDPDescriptor"), PROTOCOL_BINDING("ProtocolBinding"), PROTOCOL_SUPPORT_ENUMERATION(
             "protocolSupportEnumeration"), PROVIDER_NAME("ProviderName"), REQUESTED_AUTHN_CONTEXT("RequestedAuthnContext"), REASON(
             "Reason"), RECIPIENT("Recipient"), REQUEST("Request"), REQUESTED_ATTRIBUTE("RequestedAttribute"), REQUEST_ABSTRACT(
-            "RequestAbstract"), RESPONSE("Response"), RESPONSE_LOCATION("ResponseLocation"), RETURN_CONTEXT("ReturnContext"), SESSION_INDEX(
+            "RequestAbstract"), RESPONSE("Response"), RESPONSE_LOCATION("ResponseLocation"), RETURN_CONTEXT("ReturnContext"), SCOPING("Scoping"), SESSION_INDEX(
             "SessionIndex"), SERVICE_NAME("ServiceName"), SERVICE_DESCRIPTION("ServiceDescription"), SP_PROVIDED_ID(
             "SPProvidedID"), SP_NAME_QUALIFIER("SPNameQualifier"), SP_SSO_DESCRIPTOR("SPSSODescriptor"), SIGNATURE("Signature"), SIGNATURE_SHA1_WITH_DSA(
             "http://www.w3.org/2000/09/xmldsig#dsa-sha1"), SIGNATURE_SHA1_WITH_RSA("http://www.w3.org/2000/09/xmldsig#rsa-sha1"), SINGLE_SIGNON_SERVICE(