[PATCH] Add configurable time tolerance to SAML ticket validation
Wald Commits
scm-commit at wald.intevation.org
Wed Jun 28 20:11:03 CEST 2017
# HG changeset patch
# User Tom Gottfried <tom at intevation.de>
# Date 1498673393 -7200
# Node ID 2c8259176c461dcf251d1143de64ccb1fd447524
# Parent 1fa03f3c9d3d9c320f6bd37078ad7f47b367b706
Add configurable time tolerance to SAML ticket validation.
This allows e.g. to account for time skew between the ISP and
the server this servlet is run on.
diff -r 1fa03f3c9d3d -r 2c8259176c46 gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/Assertion.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/Assertion.java Tue May 30 12:51:42 2017 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/Assertion.java Wed Jun 28 20:09:53 2017 +0200
@@ -48,7 +48,6 @@
private static final String ATTR_CONT_ROLE =
"urn:conterra:names:sdi-suite:policy:attribute:role";
-
public Assertion(Element assertion) {
this.assertion = assertion;
this.roles = new LinkedList<String>();
@@ -174,14 +173,15 @@
* Returns whether the ticket to which the assertion belongs is
* valid at the time the method is called. The method returns true,
* if both dates (notbefore and notonorafter) have been determined
- * successfully and the current date/time is between both.
+ * successfully and the current date/time is between both (with given
+ * tolerance).
* @return Whether the ticket is valid now.
*/
- public boolean isValidNow() {
+ public boolean isValidNow(int timeEps) {
Date now = new Date();
return (this.notbefore != null && this.notonorafter != null
- && now.after(this.notbefore)
- && !this.notonorafter.before(now));
+ && now.after(new Date(this.notbefore.getTime() - timeEps))
+ && now.before(new Date(this.notonorafter.getTime() + timeEps)));
}
}
// vim: set fileencoding=utf-8 ts=4 sw=4 et si tw=80:
diff -r 1fa03f3c9d3d -r 2c8259176c46 gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/TicketValidator.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/TicketValidator.java Tue May 30 12:51:42 2017 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/TicketValidator.java Wed Jun 28 20:09:53 2017 +0200
@@ -48,11 +48,18 @@
private Key trustedKey;
/**
+ * Tolerance in milliseconds for validation based on NotBefore and
+ * NotOnOrAfter of the SAML ticket
+ */
+ private int timeEps;
+
+ /**
* Creates a new TicketValidator from a trusted key.
* @param trustedKey The trusted key for the signature checks.
*/
- public TicketValidator(Key trustedKey) {
+ public TicketValidator(Key trustedKey, int timeEps) {
this.trustedKey = trustedKey;
+ this.timeEps = timeEps;
}
/**
@@ -61,9 +68,10 @@
* @param filename The filename of the X509 certificate containing
* the trusted public key.
*/
- public TicketValidator(String filename) throws IOException,
- CertificateException {
+ public TicketValidator(String filename, int timeEps)
+ throws IOException, CertificateException {
this.trustedKey = loadKey(filename);
+ this.timeEps = timeEps;
}
/**
@@ -107,10 +115,11 @@
}
Assertion assertion = new Assertion(assertionElement);
- if (!assertion.isValidNow()) {
+ if (!assertion.isValidNow(this.timeEps)) {
log.error("Ticket is not valid now"
+ " (NotBefore: " + assertion.getFrom()
- + ", NotOnOrAfter: " + assertion.getUntil());
+ + ", NotOnOrAfter: " + assertion.getUntil()
+ + ", Tolerance (milliseconds): " + this.timeEps);
return null;
}
diff -r 1fa03f3c9d3d -r 2c8259176c46 gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Authenticator.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Authenticator.java Tue May 30 12:51:42 2017 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Authenticator.java Wed Jun 28 20:09:53 2017 +0200
@@ -64,8 +64,10 @@
else {
String trustedKey =
(String)context.getInitParameter("saml-trusted-public-key");
+ String timeEpsilon = context.getInitParameter(
+ "saml-time-tolerance");
return new Response(entity, username, password, features,
- context.getRealPath(trustedKey));
+ context.getRealPath(trustedKey), timeEpsilon);
}
}
catch(GeneralSecurityException e) {
diff -r 1fa03f3c9d3d -r 2c8259176c46 gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Response.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Response.java Tue May 30 12:51:42 2017 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Response.java Wed Jun 28 20:09:53 2017 +0200
@@ -45,10 +45,11 @@
private String password;
private Features features;
private String trustedKeyFile;
+ private String timeEpsilon;
public Response(HttpEntity entity, String username, String password,
- Features features, String trustedKeyFile)
+ Features features, String trustedKeyFile, String timeEpsilon)
throws AuthenticationException, IOException {
if (entity == null) {
@@ -80,6 +81,7 @@
this.password = password;
this.features = features;
this.trustedKeyFile = trustedKeyFile;
+ this.timeEpsilon = timeEpsilon;
}
@Override
@@ -97,8 +99,9 @@
public Assertion getAssertion() {
if (this.assertion == null && this.root != null) {
try {
+ int timeEps = Integer.parseInt(this.timeEpsilon);
TicketValidator validator =
- new TicketValidator(this.trustedKeyFile);
+ new TicketValidator(this.trustedKeyFile, timeEps);
this.assertion = validator.checkTicket(this.root);
}
catch (Exception e) {
diff -r 1fa03f3c9d3d -r 2c8259176c46 gwt-client/src/main/webapp/WEB-INF/web.xml
--- a/gwt-client/src/main/webapp/WEB-INF/web.xml Tue May 30 12:51:42 2017 +0200
+++ b/gwt-client/src/main/webapp/WEB-INF/web.xml Wed Jun 28 20:09:53 2017 +0200
@@ -51,6 +51,13 @@
</context-param>
<context-param>
+ <!-- Tolerance in milliseconds for validation based on NotBefore and
+ NotOnOrAfter of the SAML ticket -->
+ <param-name>saml-time-tolerance</param-name>
+ <param-value>1000</param-value>
+ </context-param>
+
+ <context-param>
<param-name>features-file</param-name>
<param-value>/WEB-INF/features.xml</param-value>
</context-param>
More information about the Dive4Elements-commits
mailing list