keycloak-aplcache

Details

diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java
index 5dfe8b7..80e6956 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/SAMLAssertionParser.java
@@ -24,6 +24,8 @@ import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
 import org.keycloak.dom.saml.v2.assertion.NameIDType;
 import org.keycloak.dom.saml.v2.assertion.SubjectType;
 import org.keycloak.saml.common.ErrorCodes;
+import org.keycloak.saml.common.PicketLinkLogger;
+import org.keycloak.saml.common.PicketLinkLoggerFactory;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.exceptions.ConfigurationException;
@@ -52,6 +54,7 @@ import javax.xml.stream.events.XMLEvent;
  * @since Oct 12, 2010
  */
 public class SAMLAssertionParser implements ParserNamespaceSupport {
+    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
 
     private final String ASSERTION = JBossSAMLConstants.ASSERTION.get();
 
@@ -157,15 +160,22 @@ public class SAMLAssertionParser implements ParserNamespaceSupport {
     }
 
     private AssertionType parseBaseAttributes(StartElement nextElement) throws ParsingException {
-        Attribute idAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.ID.get()));
-        String id = StaxParserUtil.getAttributeValue(idAttribute);
+        String id = StaxParserUtil.getAttributeValue(nextElement, JBossSAMLConstants.ID.get());
+        if (id == null) {
+            throw logger.parserRequiredAttribute(JBossSAMLConstants.ID.get());
+        }
 
-        Attribute versionAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.VERSION.get()));
-        String version = StaxParserUtil.getAttributeValue(versionAttribute);
-        StringUtil.match(JBossSAMLConstants.VERSION_2_0.get(), version);
+        String version = StaxParserUtil.getAttributeValue(nextElement, JBossSAMLConstants.VERSION.get());
+        if (!JBossSAMLConstants.VERSION_2_0.get().equals(version)) {
+            throw logger.parserException(new RuntimeException(
+                    String.format("Assertion %s required to be \"%s\"", JBossSAMLConstants.VERSION.get(), JBossSAMLConstants.VERSION_2_0.get())));
+        }
 
-        Attribute issueInstantAttribute = nextElement.getAttributeByName(new QName(JBossSAMLConstants.ISSUE_INSTANT.get()));
-        XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstantAttribute));
+        String issueInstantString = StaxParserUtil.getAttributeValue(nextElement, JBossSAMLConstants.ISSUE_INSTANT.get());
+        if (issueInstantString == null) {
+            throw logger.parserRequiredAttribute(JBossSAMLConstants.ISSUE_INSTANT.get());
+        }
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(issueInstantString);
 
         return new AssertionType(id, issueInstant);
     }
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 68baf0d..81ebbe0 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
@@ -16,25 +16,28 @@
  */
 package org.keycloak.saml.processing.core.parsers.saml;
 
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.security.PrivateKey;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.hamcrest.CustomMatcher;
 import org.keycloak.common.util.Base64;
 import org.keycloak.common.util.DerUtils;
+import org.keycloak.common.util.StreamUtil;
 import org.keycloak.dom.saml.v2.assertion.AssertionType;
 import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
 import org.keycloak.dom.saml.v2.assertion.AttributeType;
@@ -67,6 +70,9 @@ public class SAMLParserTest {
 
     private SAMLParser parser;
 
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
     @Before
     public void initParser() {
         this.parser = new SAMLParser();
@@ -326,5 +332,40 @@ public class SAMLParserTest {
         }
     }
 
+    @Test
+    public void testSaml20AssertionsMissingId() throws IOException, ParsingException {
+        try (InputStream st = removeAttribute("saml20-assertion-example.xml", "ID")) {
+            thrown.expect(ParsingException.class);
+            thrown.expectMessage(endsWith("Required attribute missing: ID"));
+            parser.parse(st);
+        }
+    }
+
+    @Test
+    public void testSaml20AssertionsMissingVersion() throws IOException, ParsingException {
+        try (InputStream st = removeAttribute("saml20-assertion-example.xml", "Version")) {
+            thrown.expect(ParsingException.class);
+            thrown.expectMessage(endsWith("Assertion Version required to be \"2.0\""));
+            parser.parse(st);
+        }
+    }
+
+    @Test
+    public void testSaml20AssertionsMissingIssueInstance() throws IOException, ParsingException {
+        try (InputStream st = removeAttribute("saml20-assertion-example.xml", "IssueInstant")) {
+            thrown.expect(ParsingException.class);
+            thrown.expectMessage(endsWith("Required attribute missing: IssueInstant"));
+            parser.parse(st);
+        }
+    }
+
+    private InputStream removeAttribute(String resourceName, String attribute) throws IOException {
+        try (InputStream st = SAMLParserTest.class.getResourceAsStream(resourceName)) {
+            String str = StreamUtil.readString(st, StandardCharsets.UTF_8);
+            String processed = str.replaceAll(attribute + "=\"[^\"]+\"", "");
+            return new ByteArrayInputStream(processed.getBytes());
+        }
+    }
+
 
 }