WSS-684 - Support OpenSaml 4
diff --git a/parent/pom.xml b/parent/pom.xml
index b5edc34..2b48c16 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -42,7 +42,7 @@
         <junit.version>5.7.1</junit.version>
         <kerby.version>2.0.1</kerby.version>
         <neethi.version>3.1.1</neethi.version>
-        <opensaml.version>3.4.6</opensaml.version>
+        <opensaml.version>4.0.1</opensaml.version>
         <slf4j.version>1.7.30</slf4j.version>
         <wsdl4j.version>1.6.3</wsdl4j.version>
         <xalan.version>2.7.2</xalan.version>
diff --git a/ws-security-common/pom.xml b/ws-security-common/pom.xml
index b927ef5..c6a31c0 100644
--- a/ws-security-common/pom.xml
+++ b/ws-security-common/pom.xml
@@ -30,7 +30,6 @@
     
     <properties>
         <wss4j.osgi.import>
-            org.joda.time*;version="[1.6,3)",
             net.shibboleth*;resolution:=optional,
             com.sun.security.jgss*;resolution:=optional
         </wss4j.osgi.import>
@@ -122,7 +121,11 @@
                 </exclusion>
                 <exclusion>
                     <groupId>org.apache.velocity</groupId>
-                    <artifactId>velocity</artifactId>
+                    <artifactId>velocity-engine-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpcore</artifactId>
                 </exclusion>
                 <exclusion>
                     <groupId>org.apache.httpcomponents</groupId>
@@ -140,6 +143,10 @@
                     <groupId>org.cryptacular</groupId>
                     <artifactId>cryptacular</artifactId>
                 </exclusion>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-core</artifactId>
+                </exclusion>
             </exclusions>
         </dependency>
         <dependency>
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
index c1f3471..0430b9f 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
@@ -36,7 +36,6 @@
 import org.apache.wss4j.common.util.InetAddressUtils;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
 import org.apache.xml.security.utils.XMLUtils;
-import org.joda.time.DateTime;
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.common.SAMLObjectContentReference;
@@ -260,33 +259,19 @@
     }
 
     public Instant getNotBefore() {
-        DateTime validFrom = null;
         if (getSamlVersion().equals(SAMLVersion.VERSION_20)) {
-            validFrom = getSaml2().getConditions().getNotBefore();
+            return getSaml2().getConditions().getNotBefore();
         } else {
-            validFrom = getSaml1().getConditions().getNotBefore();
+            return getSaml1().getConditions().getNotBefore();
         }
-
-        // Now convert to a Java Instant Object
-        if (validFrom != null) {
-            return validFrom.toDate().toInstant();
-        }
-        return null;
     }
 
     public Instant getNotOnOrAfter() {
-        DateTime validTill = null;
         if (getSamlVersion().equals(SAMLVersion.VERSION_20)) {
-            validTill = getSaml2().getConditions().getNotOnOrAfter();
+            return getSaml2().getConditions().getNotOnOrAfter();
         } else {
-            validTill = getSaml1().getConditions().getNotOnOrAfter();
+            return getSaml1().getConditions().getNotOnOrAfter();
         }
-
-        // Now convert to a Java Instant Object
-        if (validTill != null) {
-            return validTill.toDate().toInstant();
-        }
-        return null;
     }
 
     /**
@@ -805,8 +790,8 @@
      * Check the Conditions of the Assertion.
      */
     public void checkConditions(int futureTTL) throws WSSecurityException {
-        DateTime validFrom = null;
-        DateTime validTill = null;
+        Instant validFrom = null;
+        Instant validTill = null;
 
         if (getSamlVersion().equals(SAMLVersion.VERSION_20)
             && getSaml2().getConditions() != null) {
@@ -819,7 +804,7 @@
         }
 
         if (validFrom != null) {
-            DateTime currentTime = new DateTime();
+            Instant currentTime = Instant.now();
             currentTime = currentTime.plusSeconds(futureTTL);
             if (validFrom.isAfter(currentTime)) {
                 LOG.warn("SAML Token condition (Not Before) not met");
@@ -827,7 +812,7 @@
             }
         }
 
-        if (validTill != null && validTill.isBeforeNow()) {
+        if (validTill != null && validTill.isBefore(Instant.now())) {
             LOG.warn("SAML Token condition (Not On Or After) not met");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
@@ -837,8 +822,8 @@
      * Check the IssueInstant value of the Assertion.
      */
     public void checkIssueInstant(int futureTTL, int ttl) throws WSSecurityException {
-        DateTime issueInstant = null;
-        DateTime validTill = null;
+        Instant issueInstant = null;
+        Instant validTill = null;
 
         if (getSamlVersion().equals(SAMLVersion.VERSION_20)
             && getSaml2().getConditions() != null) {
@@ -852,7 +837,7 @@
 
         // Check the IssueInstant is not in the future, subject to the future TTL
         if (issueInstant != null) {
-            DateTime currentTime = new DateTime().plusSeconds(futureTTL);
+            Instant currentTime = Instant.now().plusSeconds(futureTTL);
             if (issueInstant.isAfter(currentTime)) {
                 LOG.warn("SAML Token IssueInstant not met");
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
@@ -860,7 +845,7 @@
 
             // If there is no NotOnOrAfter, then impose a TTL on the IssueInstant.
             if (validTill == null) {
-                currentTime = new DateTime().minusSeconds(ttl);
+                currentTime = currentTime.minusSeconds(ttl);
 
                 if (issueInstant.isBefore(currentTime)) {
                     LOG.warn("SAML Token IssueInstant not met. The assertion was created too long ago.");
@@ -940,8 +925,8 @@
             List<AuthnStatement> authnStatements = getSaml2().getAuthnStatements();
 
             for (AuthnStatement authnStatement : authnStatements) {
-                DateTime authnInstant = authnStatement.getAuthnInstant();
-                DateTime sessionNotOnOrAfter = authnStatement.getSessionNotOnOrAfter();
+                Instant authnInstant = authnStatement.getAuthnInstant();
+                Instant sessionNotOnOrAfter = authnStatement.getSessionNotOnOrAfter();
                 String subjectLocalityAddress = null;
 
                 if (authnStatement.getSubjectLocality() != null
@@ -958,7 +943,7 @@
                 getSaml1().getAuthenticationStatements();
 
             for (AuthenticationStatement authnStatement : authnStatements) {
-                DateTime authnInstant = authnStatement.getAuthenticationInstant();
+                Instant authnInstant = authnStatement.getAuthenticationInstant();
                 String subjectLocalityAddress = null;
 
                 if (authnStatement.getSubjectLocality() != null
@@ -973,11 +958,11 @@
     }
 
     private void validateAuthnStatement(
-        DateTime authnInstant, DateTime sessionNotOnOrAfter, String subjectLocalityAddress,
+        Instant authnInstant, Instant sessionNotOnOrAfter, String subjectLocalityAddress,
         int futureTTL
     ) throws WSSecurityException {
         // AuthnInstant in the future
-        DateTime currentTime = new DateTime();
+        Instant currentTime = Instant.now();
         currentTime = currentTime.plusSeconds(futureTTL);
         if (authnInstant.isAfter(currentTime)) {
             LOG.warn("SAML Token AuthnInstant not met");
@@ -985,7 +970,7 @@
         }
 
         // Stale SessionNotOnOrAfter
-        if (sessionNotOnOrAfter != null && sessionNotOnOrAfter.isBeforeNow()) {
+        if (sessionNotOnOrAfter != null && sessionNotOnOrAfter.isBefore(Instant.now())) {
             LOG.warn("SAML Token SessionNotOnOrAfter not met");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/AuthenticationStatementBean.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/AuthenticationStatementBean.java
index 07eaf42..dfff545 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/AuthenticationStatementBean.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/AuthenticationStatementBean.java
@@ -19,8 +19,7 @@
 
 package org.apache.wss4j.common.saml.bean;
 
-import org.joda.time.DateTime;
-
+import java.time.Instant;
 
 /**
  * Class AuthenticationStatementBean represents the raw data required to create
@@ -28,8 +27,8 @@
  */
 public class AuthenticationStatementBean {
     private SubjectBean subject;
-    private DateTime sessionNotOnOrAfter;
-    private DateTime authenticationInstant;
+    private Instant sessionNotOnOrAfter;
+    private Instant authenticationInstant;
     private String authenticationMethod;
     private SubjectLocalityBean subjectLocality;
     private String sessionIndex;
@@ -51,8 +50,8 @@
     public AuthenticationStatementBean(
         SubjectBean subject,
         String authenticationMethod,
-        DateTime authenticationInstant,
-        DateTime sessionNotOnOrAfter
+        Instant authenticationInstant,
+        Instant sessionNotOnOrAfter
     ) {
         this.subject = subject;
         this.authenticationMethod = authenticationMethod;
@@ -96,7 +95,7 @@
      * Get the authentication instant
      * @return the authentication instant
      */
-    public DateTime getAuthenticationInstant() {
+    public Instant getAuthenticationInstant() {
         return authenticationInstant;
     }
 
@@ -104,7 +103,7 @@
      * Set the authentication instant
      * @param authenticationInstant the authentication instant
      */
-    public void setAuthenticationInstant(DateTime authenticationInstant) {
+    public void setAuthenticationInstant(Instant authenticationInstant) {
         this.authenticationInstant = authenticationInstant;
     }
 
@@ -112,7 +111,7 @@
      * Get the sessionNotOnOrAfter
      * @return the sessionNotOnOrAfter
      */
-    public DateTime getSessionNotOnOrAfter() {
+    public Instant getSessionNotOnOrAfter() {
         return sessionNotOnOrAfter;
     }
 
@@ -120,7 +119,7 @@
      * Set the sessionNotOnOrAfter
      * @param sessionNotOnOrAfter the sessionNotOnOrAfter
      */
-    public void setSessionNotOnOrAfter(DateTime sessionNotOnOrAfter) {
+    public void setSessionNotOnOrAfter(Instant sessionNotOnOrAfter) {
         this.sessionNotOnOrAfter = sessionNotOnOrAfter;
     }
 
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java
index b9665d2..139ed2f 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java
@@ -23,16 +23,13 @@
 import java.util.Date;
 import java.util.List;
 
-import org.joda.time.DateTime;
-
-
 /**
  * Class ConditionsBean represents a SAML Conditions object (can be used to create
  * both SAML v1.1 and v2.0 statements)
  */
 public class ConditionsBean {
-    private DateTime notBefore;
-    private DateTime notAfter;
+    private Instant notBefore;
+    private Instant notAfter;
     private long tokenPeriodSeconds;
     private List<AudienceRestrictionBean> audienceRestrictions;
     private boolean oneTimeUse;
@@ -52,28 +49,14 @@
      * @param notAfter The notAfter instance
      */
     public ConditionsBean(
-        DateTime notBefore,
-        DateTime notAfter
-    ) {
-        this.notBefore = notBefore;
-        this.notAfter = notAfter;
-    }
-
-    /**
-     * Constructor ConditionsBean creates a new ConditionsBean instance.
-     *
-     * @param notBefore The notBefore instance
-     * @param notAfter The notAfter instance
-     */
-    public ConditionsBean(
         Instant notBefore,
         Instant notAfter
     ) {
         if (notBefore != null) {
-            this.notBefore = new DateTime(Date.from(notBefore));
+            this.notBefore = Date.from(notBefore).toInstant();
         }
         if (notAfter != null) {
-            this.notAfter = new DateTime(Date.from(notAfter));
+            this.notAfter = Date.from(notAfter).toInstant();
         }
     }
 
@@ -93,7 +76,7 @@
      *
      * @return the notBefore instance
      */
-    public DateTime getNotBefore() {
+    public Instant getNotBefore() {
         return notBefore;
     }
 
@@ -102,18 +85,9 @@
      *
      * @param notBefore the notBefore instance to set
      */
-    public void setNotBefore(DateTime notBefore) {
-        this.notBefore = notBefore;
-    }
-
-    /**
-     * Set the notBefore instance
-     *
-     * @param notBefore the notBefore instance to set
-     */
     public void setNotBefore(Instant notBefore) {
         if (notBefore != null) {
-            this.notBefore = new DateTime(Date.from(notBefore));
+            this.notBefore = Date.from(notBefore).toInstant();
         } else {
             this.notBefore = null;
         }
@@ -124,7 +98,7 @@
      *
      * @return the notAfter instance
      */
-    public DateTime getNotAfter() {
+    public Instant getNotAfter() {
         return notAfter;
     }
 
@@ -133,18 +107,9 @@
      *
      * @param notAfter the notAfter instance to set
      */
-    public void setNotAfter(DateTime notAfter) {
-        this.notAfter = notAfter;
-    }
-
-    /**
-     * Set the notAfter instance
-     *
-     * @param notAfter the notAfter instance to set
-     */
     public void setNotAfter(Instant notAfter) {
         if (notAfter != null) {
-            this.notAfter = new DateTime(Date.from(notAfter));
+            this.notAfter = Date.from(notAfter).toInstant();
         } else {
             this.notAfter = null;
         }
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/DelegateBean.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/DelegateBean.java
index d783e6b..c324ef1 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/DelegateBean.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/DelegateBean.java
@@ -22,8 +22,6 @@
 import java.time.Instant;
 import java.util.Date;
 
-import org.joda.time.DateTime;
-
 /**
  * Class DelegateBean represents a SAML 2.0 Delegate object. Only NameIDs are supported for now, not
  * BaseID or EncryptedIDs.
@@ -32,21 +30,17 @@
  * http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-delegation-cs-01.pdf
  */
 public class DelegateBean {
-    private DateTime delegationInstant;
+    private Instant delegationInstant;
     private String confirmationMethod;
     private NameIDBean nameIDBean;
 
-    public DateTime getDelegationInstant() {
+    public Instant getDelegationInstant() {
         return delegationInstant;
     }
 
-    public void setDelegationInstant(DateTime delegationInstant) {
-        this.delegationInstant = delegationInstant;
-    }
-    
     public void setDelegationInstant(Instant delegationInstant) {
         if (delegationInstant != null) {
-            this.delegationInstant = new DateTime(Date.from(delegationInstant));
+            this.delegationInstant = Date.from(delegationInstant).toInstant();
         } else {
             this.delegationInstant = null;
         }
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/SubjectConfirmationDataBean.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/SubjectConfirmationDataBean.java
index 8df3137..746a634 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/SubjectConfirmationDataBean.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/SubjectConfirmationDataBean.java
@@ -24,8 +24,6 @@
 import java.util.Date;
 import java.util.List;
 
-import org.joda.time.DateTime;
-
 /**
  * Class SubjectConfirmationDataBean represents a SAML (2) SubjectConfirmationData. Please note that
  * KeyInfo functionality is in SubjectBean for backwards compatibility reasons.
@@ -34,8 +32,8 @@
     private String recipient;
     private String address;
     private String inResponseTo;
-    private DateTime notBefore;
-    private DateTime notAfter;
+    private Instant notBefore;
+    private Instant notAfter;
     private List<Object> any;
 
     /**
@@ -96,26 +94,18 @@
      * Get the NotBefore time of the SubjectConfirmationDataBean
      * @return the NotBefore time of the SubjectConfirmationDataBean
      */
-    public DateTime getNotBefore() {
+    public Instant getNotBefore() {
         return notBefore;
     }
 
     /**
-     * Set the NotBefore time of the SubjectConfirmationDataBean
-     * @param notBefore the NotBefore time of the SubjectConfirmationDataBean
-     */
-    public void setNotBefore(DateTime notBefore) {
-        this.notBefore = notBefore;
-    }
-    
-    /**
      * Set the notBefore instance
      *
      * @param notBefore the notBefore instance to set
      */
     public void setNotBefore(Instant notBefore) {
         if (notBefore != null) {
-            this.notBefore = new DateTime(Date.from(notBefore));
+            this.notBefore = Date.from(notBefore).toInstant();
         } else {
             this.notBefore = null;
         }
@@ -125,26 +115,18 @@
      * Get the NotOnOrAfter time of the SubjectConfirmationDataBean
      * @return the NotOnOrAfter time of the SubjectConfirmationDataBean
      */
-    public DateTime getNotAfter() {
+    public Instant getNotAfter() {
         return notAfter;
     }
 
     /**
-     * Set the NotOnOrAfter time of the SubjectConfirmationDataBean
-     * @param notAfter the NotOnOrAfter time of the SubjectConfirmationDataBean
-     */
-    public void setNotAfter(DateTime notAfter) {
-        this.notAfter = notAfter;
-    }
-    
-    /**
      * Set the notAfter instance
      *
      * @param notAfter the notAfter instance to set
      */
     public void setNotAfter(Instant notAfter) {
         if (notAfter != null) {
-            this.notAfter = new DateTime(Date.from(notAfter));
+            this.notAfter = Date.from(notAfter).toInstant();
         } else {
             this.notAfter = null;
         }
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML1ComponentBuilder.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML1ComponentBuilder.java
index cae6f7b..4b08dd0 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML1ComponentBuilder.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML1ComponentBuilder.java
@@ -19,6 +19,8 @@
 
 package org.apache.wss4j.common.saml.builder;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,7 +38,6 @@
 import org.apache.wss4j.common.saml.bean.SubjectBean;
 import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
-import org.joda.time.DateTime;
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.XMLObjectBuilderFactory;
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
@@ -145,7 +146,7 @@
             );
         assertion.setVersion(SAMLVersion.VERSION_11);
         assertion.setIssuer(issuer);
-        assertion.setIssueInstant(new DateTime()); // now
+        assertion.setIssueInstant(Instant.now()); // now
         assertion.setID(IDGenerator.generateID("_"));
         return assertion;
     }
@@ -208,7 +209,7 @@
      * Create an Opensaml KeyInfo object from the parameters
      * @param keyInfo the KeyInfo bean from which to extract security credentials
      * @return the KeyInfo object
-     * @throws org.opensaml.xml.security.SecurityException
+     * @throws org.opensaml.security.SecurityException
      */
     public static KeyInfo createKeyInfo(KeyInfoBean keyInfo)
         throws org.opensaml.security.SecurityException, WSSecurityException {
@@ -261,15 +262,15 @@
         Conditions conditions = conditionsV1Builder.buildObject();
 
         if (conditionsBean == null) {
-            DateTime newNotBefore = new DateTime();
+            Instant newNotBefore = Instant.now();
             conditions.setNotBefore(newNotBefore);
-            conditions.setNotOnOrAfter(newNotBefore.plusMinutes(5));
+            conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
             return conditions;
         }
 
         long tokenPeriodSeconds = conditionsBean.getTokenPeriodSeconds();
-        DateTime notBefore = conditionsBean.getNotBefore();
-        DateTime notAfter = conditionsBean.getNotAfter();
+        Instant notBefore = conditionsBean.getNotBefore();
+        Instant notAfter = conditionsBean.getNotAfter();
 
         if (notBefore != null && notAfter != null) {
             if (notBefore.isAfter(notAfter)) {
@@ -280,14 +281,12 @@
             conditions.setNotBefore(notBefore);
             conditions.setNotOnOrAfter(notAfter);
         } else {
-            DateTime newNotBefore = new DateTime();
+            Instant newNotBefore = Instant.now();
             conditions.setNotBefore(newNotBefore);
             if (tokenPeriodSeconds <= 0) {
                 tokenPeriodSeconds = 5L * 60L;
             }
-            DateTime notOnOrAfter =
-                new DateTime(newNotBefore.getMillis() + tokenPeriodSeconds * 1000L);
-
+            Instant notOnOrAfter = newNotBefore.plusSeconds(tokenPeriodSeconds);
             conditions.setNotOnOrAfter(notOnOrAfter);
         }
 
@@ -413,7 +412,7 @@
                         statementBean.getAuthenticationInstant()
                     );
                 } else {
-                    authenticationStatement.setAuthenticationInstant(new DateTime());
+                    authenticationStatement.setAuthenticationInstant(Instant.now());
                 }
 
                 authenticationStatement.setAuthenticationMethod(
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java
index 3e7051b..d3e19fc 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java
@@ -19,6 +19,8 @@
 
 package org.apache.wss4j.common.saml.builder;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -41,7 +43,6 @@
 import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
 import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
-import org.joda.time.DateTime;
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.XMLObjectBuilderFactory;
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
@@ -169,7 +170,7 @@
             assertionBuilder.buildObject(Assertion.DEFAULT_ELEMENT_NAME, Assertion.TYPE_NAME);
         assertion.setID(IDGenerator.generateID("_"));
         assertion.setVersion(SAMLVersion.VERSION_20);
-        assertion.setIssueInstant(new DateTime());
+        assertion.setIssueInstant(Instant.now());
         return assertion;
     }
 
@@ -214,15 +215,15 @@
         Conditions conditions = conditionsBuilder.buildObject();
 
         if (conditionsBean == null) {
-            DateTime newNotBefore = new DateTime();
+            Instant newNotBefore = Instant.now();
             conditions.setNotBefore(newNotBefore);
-            conditions.setNotOnOrAfter(newNotBefore.plusMinutes(5));
+            conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
             return conditions;
         }
 
         long tokenPeriodSeconds = conditionsBean.getTokenPeriodSeconds();
-        DateTime notBefore = conditionsBean.getNotBefore();
-        DateTime notAfter = conditionsBean.getNotAfter();
+        Instant notBefore = conditionsBean.getNotBefore();
+        Instant notAfter = conditionsBean.getNotAfter();
 
         if (notBefore != null && notAfter != null) {
             if (notBefore.isAfter(notAfter)) {
@@ -233,14 +234,12 @@
             conditions.setNotBefore(notBefore);
             conditions.setNotOnOrAfter(notAfter);
         } else {
-            DateTime newNotBefore = new DateTime();
+            Instant newNotBefore = Instant.now();
             conditions.setNotBefore(newNotBefore);
             if (tokenPeriodSeconds <= 0) {
                 tokenPeriodSeconds = 5L * 60L;
             }
-            DateTime notOnOrAfter =
-                new DateTime(newNotBefore.getMillis() + tokenPeriodSeconds * 1000L);
-
+            Instant notOnOrAfter = newNotBefore.plusSeconds(tokenPeriodSeconds);
             conditions.setNotOnOrAfter(notOnOrAfter);
         }
 
@@ -473,13 +472,13 @@
         if (authBeans != null && !authBeans.isEmpty()) {
             for (AuthenticationStatementBean statementBean : authBeans) {
                 AuthnStatement authnStatement = authnStatementBuilder.buildObject();
-                DateTime authInstant = statementBean.getAuthenticationInstant();
+                Instant authInstant = statementBean.getAuthenticationInstant();
                 if (authInstant == null) {
-                    authInstant = new DateTime();
+                    authInstant = Instant.now();
                 }
                 authnStatement.setAuthnInstant(authInstant);
 
-                DateTime sessionNotOnOrAfter = statementBean.getSessionNotOnOrAfter();
+                Instant sessionNotOnOrAfter = statementBean.getSessionNotOnOrAfter();
                 if (sessionNotOnOrAfter != null) {
                     authnStatement.setSessionNotOnOrAfter(sessionNotOnOrAfter);
                 }
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
index 60dd6ed..16bb384 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
@@ -30,7 +30,6 @@
 import org.apache.wss4j.common.saml.builder.SAML1Constants;
 import org.apache.wss4j.common.saml.builder.SAML2Constants;
 import org.apache.wss4j.dom.handler.RequestData;
-import org.joda.time.DateTime;
 import org.opensaml.saml.common.SAMLVersion;
 
 /**
@@ -261,10 +260,9 @@
                     new Object[] {"A replay attack has been detected"});
             }
 
-            DateTime expires = samlAssertion.getSaml2().getConditions().getNotOnOrAfter();
+            Instant expires = samlAssertion.getSaml2().getConditions().getNotOnOrAfter();
             if (expires != null) {
-                Instant zonedExpires = Instant.ofEpochMilli(expires.getMillis());
-                replayCache.add(identifier, zonedExpires);
+                replayCache.add(identifier, expires);
             } else {
                 replayCache.add(identifier);
             }
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java
index 50b1dd7..3bdd0bc 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java
@@ -36,7 +36,6 @@
 import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
 import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
 import org.apache.wss4j.dom.message.WSSecEncryptedKey;
-import org.joda.time.DateTime;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -47,6 +46,7 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import java.security.cert.X509Certificate;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -73,8 +73,8 @@
     protected String subjectNameIDFormat;
     protected String subjectLocalityIpAddress;
     protected String subjectLocalityDnsAddress;
-    protected DateTime sessionNotOnOrAfter;
-    protected DateTime authenticationInstant;
+    protected Instant sessionNotOnOrAfter;
+    protected Instant authenticationInstant;
     protected String resource;
     protected List<Object> customAttributeValues;
     protected ConditionsBean conditions;
@@ -119,7 +119,7 @@
         confirmationMethod = confMethod;
     }
 
-    public void setSessionNotOnOrAfter(DateTime sessionNotOnOrAfter) {
+    public void setSessionNotOnOrAfter(Instant sessionNotOnOrAfter) {
         this.sessionNotOnOrAfter = sessionNotOnOrAfter;
     }
 
@@ -164,11 +164,11 @@
         this.customAttributeValues = customAttributeValues;
     }
 
-    public DateTime getAuthenticationInstant() {
+    public Instant getAuthenticationInstant() {
         return authenticationInstant;
     }
 
-    public void setAuthenticationInstant(DateTime authenticationInstant) {
+    public void setAuthenticationInstant(Instant authenticationInstant) {
         this.authenticationInstant = authenticationInstant;
     }
 
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAuthnTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAuthnTest.java
index 2655892..ffef677 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAuthnTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAuthnTest.java
@@ -19,6 +19,9 @@
 
 package org.apache.wss4j.dom.saml;
 
+import java.time.Duration;
+import java.time.Instant;
+
 import javax.security.auth.callback.CallbackHandler;
 
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -38,7 +41,6 @@
 import org.apache.wss4j.dom.handler.WSHandlerResult;
 import org.apache.wss4j.dom.message.WSSecHeader;
 import org.apache.wss4j.dom.message.WSSecSAMLToken;
-import org.joda.time.DateTime;
 
 import org.junit.jupiter.api.Test;
 import org.w3c.dom.Document;
@@ -86,7 +88,7 @@
         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setAuthenticationInstant(new DateTime().plusMinutes(70));
+        callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
 
         createAndVerifyMessage(callbackHandler, false);
     }
@@ -97,7 +99,7 @@
         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setAuthenticationInstant(new DateTime().plusMinutes(70));
+        callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
 
         createAndVerifyMessage(callbackHandler, false);
     }
@@ -108,7 +110,7 @@
         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setSessionNotOnOrAfter(new DateTime().minusMinutes(70));
+        callbackHandler.setSessionNotOnOrAfter(Instant.now().minus(Duration.ofMinutes(70)));
 
         createAndVerifyMessage(callbackHandler, false);
     }
@@ -193,7 +195,7 @@
      * Verifies the soap envelope
      * <p/>
      *
-     * @param envelope
+     * @param doc
      * @throws Exception Thrown when there is a problem in verification
      */
     private WSHandlerResult verify(Document doc) throws Exception {
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
index 84c01d6..a3272d7 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.wss4j.dom.saml;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -48,7 +50,6 @@
 import org.apache.wss4j.dom.handler.WSHandlerResult;
 import org.apache.wss4j.dom.message.WSSecHeader;
 import org.apache.wss4j.dom.message.WSSecSAMLToken;
-import org.joda.time.DateTime;
 
 import org.junit.jupiter.api.Test;
 import org.w3c.dom.Document;
@@ -83,9 +84,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
+        Instant notBefore = Instant.now();
         conditions.setNotBefore(notBefore);
-        conditions.setNotAfter(notBefore.plusMinutes(20));
+        conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(20)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, true);
@@ -102,9 +103,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
-        conditions.setNotBefore(notBefore.minusMinutes(5));
-        conditions.setNotAfter(notBefore.minusMinutes(3));
+        Instant notBefore = Instant.now();
+        conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(5)));
+        conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(3)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, false);
@@ -117,9 +118,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
-        conditions.setNotAfter(notBefore.minusMinutes(60));
-        conditions.setNotBefore(notBefore.minusMinutes(70));
+        Instant notBefore = Instant.now();
+        conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(60)));
+        conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(70)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, false);
@@ -132,9 +133,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
-        conditions.setNotAfter(new DateTime().plusMinutes(70));
-        conditions.setNotBefore(notBefore.plusMinutes(60));
+        Instant notBefore = Instant.now();
+        conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(70)));
+        conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(60)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, false);
@@ -150,8 +151,8 @@
         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
 
-        DateTime issueInstant = new DateTime();
-        issueInstant = issueInstant.plusMinutes(60);
+        Instant issueInstant = Instant.now();
+        issueInstant = issueInstant.plus(Duration.ofMinutes(60));
         samlAssertion.getSaml2().setIssueInstant(issueInstant);
 
         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
@@ -187,8 +188,8 @@
         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
 
-        DateTime issueInstant = new DateTime();
-        issueInstant = issueInstant.minusMinutes(31);
+        Instant issueInstant = Instant.now();
+        issueInstant = issueInstant.minus(Duration.ofMinutes(31));
         samlAssertion.getSaml2().setIssueInstant(issueInstant);
         samlAssertion.getSaml2().getConditions().setNotOnOrAfter(null);
 
@@ -225,7 +226,7 @@
         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
 
-        DateTime issueInstant = new DateTime().minusSeconds(5);
+        Instant issueInstant = Instant.now().minusSeconds(5);
         samlAssertion.getSaml2().setIssueInstant(issueInstant);
         samlAssertion.getSaml2().getConditions().setNotOnOrAfter(null);
 
@@ -258,11 +259,11 @@
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
 
         ConditionsBean conditions = new ConditionsBean();
-        conditions.setNotBefore(new DateTime());
-        conditions.setNotAfter(new DateTime().plusMinutes(35));
+        Instant issueInstant = Instant.now();
+        conditions.setNotBefore(issueInstant);
+        conditions.setNotAfter(issueInstant.plus(Duration.ofMinutes(35)));
 
-        DateTime issueInstant = new DateTime();
-        issueInstant = issueInstant.minusMinutes(31);
+        issueInstant = issueInstant.minus(Duration.ofMinutes(31));
         samlAssertion.getSaml2().setIssueInstant(issueInstant);
 
         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
@@ -293,8 +294,8 @@
         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
 
-        DateTime issueInstant = new DateTime();
-        issueInstant = issueInstant.minusMinutes(31);
+        Instant issueInstant = Instant.now();
+        issueInstant = issueInstant.minus(Duration.ofMinutes(31));
         samlAssertion.getSaml1().setIssueInstant(issueInstant);
         samlAssertion.getSaml1().getConditions().setNotOnOrAfter(null);
 
@@ -332,9 +333,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
-        conditions.setNotBefore(notBefore.plusMinutes(2));
-        conditions.setNotAfter(notBefore.plusMinutes(5));
+        Instant notBefore = Instant.now();
+        conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(2)));
+        conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, false);
@@ -351,9 +352,9 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
+        Instant notBefore = Instant.now();
         conditions.setNotBefore(notBefore.plusSeconds(30));
-        conditions.setNotAfter(notBefore.plusMinutes(5));
+        conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
         callbackHandler.setConditions(conditions);
 
         createAndVerifyMessage(callbackHandler, true);
@@ -724,12 +725,12 @@
         callbackHandler.setIssuer("www.example.com");
 
         ConditionsBean conditions = new ConditionsBean();
-        DateTime notBefore = new DateTime();
+        Instant notBefore = Instant.now();
         conditions.setNotBefore(notBefore);
-        conditions.setNotAfter(notBefore.plusMinutes(20));
+        conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(20)));
 
         DelegateBean delegate = new DelegateBean();
-        delegate.setDelegationInstant(DateTime.now());
+        delegate.setDelegationInstant(Instant.now());
         delegate.setConfirmationMethod(SAML2Constants.CONF_BEARER);
 
         NameIDBean nameID = new NameIDBean();
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenTest.java
index 5511293..6b77614 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenTest.java
@@ -24,6 +24,8 @@
 import java.security.Key;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -76,7 +78,6 @@
 import org.apache.xml.security.keys.content.RetrievalMethod;
 import org.apache.xml.security.keys.content.X509Data;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
-import org.joda.time.DateTime;
 
 import org.junit.jupiter.api.Test;
 import org.opensaml.core.xml.XMLObjectBuilder;
@@ -458,7 +459,7 @@
     public void testSAML2SessionNotOnOrAfter() throws Exception {
         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
-        callbackHandler.setSessionNotOnOrAfter(new DateTime().plusHours(1));
+        callbackHandler.setSessionNotOnOrAfter(Instant.now().plus(Duration.ofHours(1)));
         callbackHandler.setIssuer("www.example.com");
 
         SAMLCallback samlCallback = new SAMLCallback();
@@ -592,9 +593,9 @@
         SAMLObjectBuilder<Conditions> conditionsV2Builder =
                 (SAMLObjectBuilder<Conditions>)builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
         Conditions conditions = conditionsV2Builder.buildObject();
-        DateTime newNotBefore = new DateTime();
+        Instant newNotBefore = Instant.now();
         conditions.setNotBefore(newNotBefore);
-        conditions.setNotOnOrAfter(newNotBefore.plusMinutes(5));
+        conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
 
         XMLObjectBuilder<XSAny> xsAnyBuilder =
             (XMLObjectBuilder<XSAny>)builderFactory.getBuilder(XSAny.TYPE_NAME);
@@ -681,7 +682,7 @@
         SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
         subjectConfirmationData.setAddress("http://apache.org");
         subjectConfirmationData.setInResponseTo("12345");
-        subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+        subjectConfirmationData.setNotAfter(Instant.now().plus(Duration.ofMinutes(5)));
         subjectConfirmationData.setRecipient("http://recipient.apache.org");
         callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
 
@@ -1451,7 +1452,7 @@
      * Verifies the soap envelope
      * <p/>
      *
-     * @param envelope
+     * @param doc
      * @throws Exception Thrown when there is a problem in verification
      */
     private WSHandlerResult verify(Document doc) throws Exception {
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/SamlTokenValidatorImpl.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/SamlTokenValidatorImpl.java
index bc3ddf1..235742c 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/SamlTokenValidatorImpl.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/SamlTokenValidatorImpl.java
@@ -32,7 +32,6 @@
 import org.apache.wss4j.stax.impl.securityToken.SamlSecurityTokenImpl;
 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
 import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
-import org.joda.time.DateTime;
 import org.opensaml.saml.common.SAMLVersion;
 
 public class SamlTokenValidatorImpl extends SignatureTokenValidatorImpl implements SamlTokenValidator {
@@ -259,10 +258,9 @@
                     new Object[] {"A replay attack has been detected"});
             }
 
-            DateTime expires = samlAssertion.getSaml2().getConditions().getNotOnOrAfter();
+            Instant expires = samlAssertion.getSaml2().getConditions().getNotOnOrAfter();
             if (expires != null) {
-                Instant zonedExpires = Instant.ofEpochMilli(expires.getMillis());
-                replayCache.add(identifier, zonedExpires);
+                replayCache.add(identifier, expires);
             } else {
                 replayCache.add(identifier);
             }
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SAMLTokenTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SAMLTokenTest.java
index f8fd820..de0b084 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SAMLTokenTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SAMLTokenTest.java
@@ -24,6 +24,8 @@
 import java.nio.charset.StandardCharsets;
 import java.security.Key;
 import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -71,7 +73,6 @@
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.keys.KeyInfo;
 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
-import org.joda.time.DateTime;
 import org.junit.jupiter.api.Test;
 import org.opensaml.core.xml.XMLObjectBuilder;
 import org.opensaml.core.xml.XMLObjectBuilderFactory;
@@ -762,9 +763,9 @@
             SAMLObjectBuilder<Conditions> conditionsV2Builder =
                     (SAMLObjectBuilder<Conditions>) builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
             Conditions conditions = conditionsV2Builder.buildObject();
-            DateTime newNotBefore = new DateTime();
+            Instant newNotBefore = Instant.now();
             conditions.setNotBefore(newNotBefore);
-            conditions.setNotOnOrAfter(newNotBefore.plusMinutes(5));
+            conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
 
             XMLObjectBuilder<XSAny> xsAnyBuilder =
                 (XMLObjectBuilder<XSAny>)builderFactory.getBuilder(XSAny.TYPE_NAME);
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlAuthnTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlAuthnTest.java
index f65f92a..a4f4d50 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlAuthnTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlAuthnTest.java
@@ -21,6 +21,8 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Properties;
 
 import javax.security.auth.callback.CallbackHandler;
@@ -38,7 +40,6 @@
 import org.apache.wss4j.stax.setup.WSSec;
 import org.apache.wss4j.stax.test.AbstractTestBase;
 import org.apache.wss4j.stax.test.utils.StAX2DOM;
-import org.joda.time.DateTime;
 import org.junit.jupiter.api.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
@@ -85,7 +86,7 @@
         callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setAuthenticationInstant(new DateTime().plusMinutes(70));
+        callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
 
         createDOMMessageAndVerifyStAX(callbackHandler, false);
     }
@@ -98,7 +99,7 @@
         callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setAuthenticationInstant(new DateTime().plusMinutes(70));
+        callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
 
         createDOMMessageAndVerifyStAX(callbackHandler, false);
     }
@@ -111,7 +112,7 @@
         callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
         callbackHandler.setIssuer("www.example.com");
 
-        callbackHandler.setSessionNotOnOrAfter(new DateTime().minusMinutes(70));
+        callbackHandler.setSessionNotOnOrAfter(Instant.now().minus(Duration.ofMinutes(70)));
 
         createDOMMessageAndVerifyStAX(callbackHandler, false);
     }
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlConditionsTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlConditionsTest.java
index c2a2b38..0e8da6d 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlConditionsTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/saml/SamlConditionsTest.java
@@ -22,6 +22,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -33,6 +35,7 @@
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
+import net.shibboleth.utilities.java.support.xml.DOMTypeSupport;
 import org.apache.wss4j.common.saml.bean.AudienceRestrictionBean;
 import org.apache.wss4j.common.saml.bean.ConditionsBean;
 import org.apache.wss4j.common.saml.bean.ProxyRestrictionBean;
@@ -48,9 +51,7 @@
 import org.apache.wss4j.stax.test.utils.StAX2DOM;
 import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
-import org.joda.time.DateTime;
 import org.junit.jupiter.api.Test;
-import org.opensaml.saml.config.SAMLConfigurationSupport;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -79,9 +80,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
+            Instant notBefore = Instant.now();
             conditions.setNotBefore(notBefore);
-            DateTime notAfter = notBefore.plusMinutes(20);
+            Instant notAfter = notBefore.plus(Duration.ofMinutes(20));
             conditions.setNotAfter(notAfter);
             callbackHandler.setConditions(conditions);
 
@@ -104,8 +105,8 @@
 
             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "Conditions");
             assertEquals(nodeList.getLength(), 1);
-            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotBefore"), SAMLConfigurationSupport.getSAMLDateFormatter().print(notBefore));
-            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotOnOrAfter"), SAMLConfigurationSupport.getSAMLDateFormatter().print(notAfter));
+            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotBefore"), DOMTypeSupport.instantToString(notBefore));
+            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotOnOrAfter"), DOMTypeSupport.instantToString(notAfter));
         }
 
         //done signature; now test sig-verification:
@@ -131,9 +132,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
+            Instant notBefore = Instant.now();
             conditions.setNotBefore(notBefore);
-            DateTime notAfter = notBefore.plusMinutes(20);
+            Instant notAfter = notBefore.plus(Duration.ofMinutes(20));
             conditions.setNotAfter(notAfter);
             callbackHandler.setConditions(conditions);
 
@@ -151,8 +152,8 @@
 
             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "Conditions");
             assertEquals(nodeList.getLength(), 1);
-            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotBefore"), SAMLConfigurationSupport.getSAMLDateFormatter().print(notBefore));
-            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotOnOrAfter"), SAMLConfigurationSupport.getSAMLDateFormatter().print(notAfter));
+            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotBefore"), DOMTypeSupport.instantToString(notBefore));
+            assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "NotOnOrAfter"), DOMTypeSupport.instantToString(notAfter));
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -184,9 +185,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
-            conditions.setNotBefore(notBefore.minusMinutes(5));
-            conditions.setNotAfter(notBefore.minusMinutes(3));
+            Instant notBefore = Instant.now();
+            conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(5)));
+            conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(3)));
             callbackHandler.setConditions(conditions);
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
@@ -225,9 +226,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
-            conditions.setNotAfter(notBefore.minusMinutes(60));
-            conditions.setNotBefore(notBefore.minusMinutes(70));
+            Instant notBefore = Instant.now();
+            conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(60)));
+            conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(70)));
             callbackHandler.setConditions(conditions);
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
@@ -266,9 +267,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
-            conditions.setNotAfter(new DateTime().plusMinutes(70));
-            conditions.setNotBefore(notBefore.plusMinutes(60));
+            Instant notBefore = Instant.now();
+            conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(70)));
+            conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(60)));
             callbackHandler.setConditions(conditions);
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
@@ -311,9 +312,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
-            conditions.setNotBefore(notBefore.plusMinutes(2));
-            conditions.setNotAfter(notBefore.plusMinutes(5));
+            Instant notBefore = Instant.now();
+            conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(2)));
+            conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
             callbackHandler.setConditions(conditions);
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
@@ -355,9 +356,9 @@
             callbackHandler.setIssuer("www.example.com");
 
             ConditionsBean conditions = new ConditionsBean();
-            DateTime notBefore = new DateTime();
+            Instant notBefore = Instant.now();
             conditions.setNotBefore(notBefore.plusSeconds(30));
-            conditions.setNotAfter(notBefore.plusMinutes(5));
+            conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
             callbackHandler.setConditions(conditions);
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");