keycloak-uncached

KEYCLOAK-9077 Adds support for SAML SessionNotOnOrAfter

12/13/2018 3:32:18 PM

Details

diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAssertionQNames.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAssertionQNames.java
index 85d46af..ddf5fec 100644
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAssertionQNames.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAssertionQNames.java
@@ -79,6 +79,7 @@ public enum SAMLAssertionQNames implements HasQName {
     ATTR_NOT_ON_OR_AFTER(null, "NotOnOrAfter"),
     ATTR_RECIPIENT(null, "Recipient"),
     ATTR_SESSION_INDEX(null, "SessionIndex"),
+    ATTR_SESSION_NOT_ON_OR_AFTER(null, "SessionNotOnOrAfter"),
     ATTR_SP_PROVIDED_ID(null, "SPProvidedID"),
     ATTR_SP_NAME_QUALIFIER(null, "SPNameQualifier"),
     ATTR_VERSION(null, "Version"),
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAuthnStatementParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAuthnStatementParser.java
index 6e50b44..940d005 100644
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAuthnStatementParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/assertion/SAMLAuthnStatementParser.java
@@ -48,7 +48,7 @@ public class SAMLAuthnStatementParser extends AbstractStaxSamlAssertionParser<Au
         AuthnStatementType res = new AuthnStatementType(authnInstant);
 
         res.setSessionIndex(StaxParserUtil.getAttributeValue(element, SAMLAssertionQNames.ATTR_SESSION_INDEX));
-        res.setSessionNotOnOrAfter(StaxParserUtil.getXmlTimeAttributeValue(element, SAMLAssertionQNames.ATTR_NOT_ON_OR_AFTER));
+        res.setSessionNotOnOrAfter(StaxParserUtil.getXmlTimeAttributeValue(element, SAMLAssertionQNames.ATTR_SESSION_NOT_ON_OR_AFTER));
         return res;
     }
 
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
index 5ad84da..2578b81 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
@@ -38,6 +38,7 @@ import org.keycloak.dom.saml.v2.assertion.URIType;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.exceptions.ProcessingException;
 import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.processing.core.parsers.saml.assertion.SAMLAssertionQNames;
 import org.w3c.dom.Element;
 
 import javax.xml.datatype.XMLGregorianCalendar;
@@ -221,6 +222,11 @@ public class SAMLAssertionWriter extends BaseWriter {
             StaxUtil.writeAttribute(writer, JBossSAMLConstants.SESSION_INDEX.get(), sessionIndex);
         }
 
+        XMLGregorianCalendar sessionNotOnOrAfter = authnStatement.getSessionNotOnOrAfter();
+        if (sessionNotOnOrAfter != null) {
+            StaxUtil.writeAttribute(writer, SAMLAssertionQNames.ATTR_SESSION_NOT_ON_OR_AFTER.getQName(), sessionNotOnOrAfter.toString());
+        }
+
         AuthnContextType authnContext = authnStatement.getAuthnContext();
         if (authnContext != null)
             write(authnContext);
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriterTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriterTest.java
new file mode 100644
index 0000000..8aababb
--- /dev/null
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriterTest.java
@@ -0,0 +1,37 @@
+package org.keycloak.saml.processing.core.saml.v2.writers;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.exceptions.ProcessingException;
+import org.keycloak.saml.common.util.StaxUtil;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.io.ByteArrayOutputStream;
+
+public class SAMLAssertionWriterTest {
+    @Test
+    public void testAuthnStatementSessionNotOnOrAfterExists() throws ProcessingException {
+        long sessionLengthInSeconds = 3600;
+
+        XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
+        XMLGregorianCalendar sessionExpirationDate = XMLTimeUtil.add(issueInstant, sessionLengthInSeconds);
+
+        AuthnStatementType authnStatementType = new AuthnStatementType(issueInstant);
+
+        authnStatementType.setSessionIndex("9b3cf799-225b-424a-8e5e-ee3c38e06ded::24b2f572-163c-43ad-8011-de6cd3803f76");
+        authnStatementType.setSessionNotOnOrAfter(sessionExpirationDate);
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        SAMLAssertionWriter samlAssertionWriter = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(byteArrayOutputStream));
+
+        samlAssertionWriter.write(authnStatementType, true);
+
+        String serializedAssertion = new String(byteArrayOutputStream.toByteArray(), GeneralConstants.SAML_CHARSET);
+        String expectedXMLAttribute = "SessionNotOnOrAfter=\"" + sessionExpirationDate.toString() + "\"";
+
+        Assert.assertTrue(serializedAssertion.contains(expectedXMLAttribute));
+    }
+}
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-assertion-example.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-assertion-example.xml
index f834c52..e3b221f 100644
--- a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-assertion-example.xml
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/saml20-assertion-example.xml
@@ -70,7 +70,7 @@
         </saml:AudienceRestriction>
     </saml:Conditions>
 
-    <saml:AuthnStatement AuthnInstant="2009-06-17T18:45:10.738Z" NotOnOrAfter="2009-06-17T18:55:10.738Z">
+    <saml:AuthnStatement AuthnInstant="2009-06-17T18:45:10.738Z" SessionNotOnOrAfter="2009-06-17T18:55:10.738Z">
         <saml:AuthnContext>
             <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified
             </saml:AuthnContextClassRef>