KEYCLOAK-11486 Add support for system property or env variable in AllowedClockSkew in keycloak-saml subsystem

This commit is contained in:
vramik 2020-01-13 13:58:20 +01:00 committed by Hynek Mlnařík
parent e1f8e5d08c
commit 3b1bdb216a
7 changed files with 51 additions and 34 deletions

View file

@ -32,8 +32,8 @@ abstract public class AllowedClockSkew {
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_VALUE =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_VALUE, ModelType.INT, false)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW)
.setAllowExpression(false)
.setValidator(new IntRangeValidator(1, Integer.MAX_VALUE, true, false))
.setAllowExpression(true)
.setValidator(new IntRangeValidator(1, Integer.MAX_VALUE, true, true))
.build();
static private enum AllowedClockSkewUnits {MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
@ -41,9 +41,9 @@ abstract public class AllowedClockSkew {
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_UNIT =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_UNIT, ModelType.STRING, true)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW_UNIT)
.setAllowExpression(false)
.setAllowExpression(true)
.setDefaultValue(new ModelNode(AllowedClockSkewUnits.SECONDS.name()))
.setValidator(EnumValidator.create(AllowedClockSkewUnits.class, true, false))
.setValidator(EnumValidator.create(AllowedClockSkewUnits.class, true, true))
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {ALLOWED_CLOCK_SKEW_UNIT, ALLOWED_CLOCK_SKEW_VALUE};

View file

@ -184,16 +184,15 @@ public class SubsystemParsingAllowedClockSkewTestCase extends AbstractSubsystemB
testSubsystem("30", "invalid-unit");
}
// For the moment no expressions allowed as the rest of the subsystem doesn't resolve expressions
//@Test
//public void testExpression() throws Exception {
// System.setProperty("test.prop.SKEW_TIME", "30");
// System.setProperty("test.prop.SKEW_UNIT", "MILLISECONDS");
// try {
// testSubsystem("${test.prop.SKEW_TIME}", "${test.prop.SKEW_UNIT}", 30, "MILLISECONDS");
// } finally {
// System.clearProperty("test.prop.SKEW_TIME");
// System.clearProperty("test.prop.SKEW_UNIT");
// }
//}
@Test
public void testExpression() throws Exception {
System.setProperty("test.prop.SKEW_TIME", "30");
System.setProperty("test.prop.SKEW_UNIT", "MILLISECONDS");
try {
testSubsystem("${test.prop.SKEW_TIME}", "${test.prop.SKEW_UNIT}", 30, "MILLISECONDS");
} finally {
System.clearProperty("test.prop.SKEW_TIME");
System.clearProperty("test.prop.SKEW_UNIT");
}
}
}

View file

@ -78,7 +78,7 @@ public class IdpParser extends AbstractKeycloakSamlAdapterV1Parser<IDP> {
String timeUnitString = StaxParserUtil.getAttributeValueRP(elementDetail, KeycloakSamlAdapterV1QNames.ATTR_UNIT);
target.setAllowedClockSkewUnit(timeUnitString == null ? TimeUnit.SECONDS : TimeUnit.valueOf(timeUnitString));
StaxParserUtil.advance(xmlEventReader);
target.setAllowedClockSkew(Integer.parseInt(StaxParserUtil.getElementText(xmlEventReader)));
target.setAllowedClockSkew(Integer.parseInt(StaxParserUtil.getElementTextRP(xmlEventReader)));
break;
}
}

View file

@ -16,6 +16,7 @@
*/
package org.keycloak.subsystem.adapter.saml.extension;
import java.util.EnumSet;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.operations.validation.EnumValidator;
@ -32,8 +33,8 @@ abstract public class AllowedClockSkew {
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_VALUE =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_VALUE, ModelType.INT, false)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW)
.setAllowExpression(false)
.setValidator(new IntRangeValidator(1, Integer.MAX_VALUE, true, false))
.setAllowExpression(true)
.setValidator(new IntRangeValidator(1, Integer.MAX_VALUE, true, true))
.build();
static private enum AllowedClockSkewUnits {MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
@ -41,12 +42,12 @@ abstract public class AllowedClockSkew {
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_UNIT =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_UNIT, ModelType.STRING, true)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW_UNIT)
.setAllowExpression(false)
.setAllowExpression(true)
.setDefaultValue(new ModelNode(AllowedClockSkewUnits.SECONDS.name()))
.setAllowedValues(AllowedClockSkewUnits.MINUTES.name(), AllowedClockSkewUnits.SECONDS.name(),
AllowedClockSkewUnits.MILLISECONDS.name(), AllowedClockSkewUnits.MICROSECONDS.name(),
AllowedClockSkewUnits.NANOSECONDS.name())
.setValidator(EnumValidator.create(AllowedClockSkewUnits.class, true, false))
.setValidator(EnumValidator.create(AllowedClockSkewUnits.class, EnumSet.allOf(AllowedClockSkewUnits.class)))
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {ALLOWED_CLOCK_SKEW_UNIT, ALLOWED_CLOCK_SKEW_VALUE};

View file

@ -223,16 +223,15 @@ public class SubsystemParsingAllowedClockSkewTestCase extends AbstractSubsystemB
testSubsystem("30", "invalid-unit");
}
// For the moment no expressions allowed as the rest of the subsystem doesn't resolve expressions
//@Test
//public void testExpression() throws Exception {
// System.setProperty("test.prop.SKEW_TIME", "30");
// System.setProperty("test.prop.SKEW_UNIT", "MILLISECONDS");
// try {
// testSubsystem("${test.prop.SKEW_TIME}", "${test.prop.SKEW_UNIT}", 30, "MILLISECONDS");
// } finally {
// System.clearProperty("test.prop.SKEW_TIME");
// System.clearProperty("test.prop.SKEW_UNIT");
// }
//}
@Test
public void testExpression() throws Exception {
System.setProperty("test.prop.SKEW_TIME", "30");
System.setProperty("test.prop.SKEW_UNIT", "MILLISECONDS");
try {
testSubsystem("${test.prop.SKEW_TIME}", "${test.prop.SKEW_UNIT}", 30, "MILLISECONDS");
} finally {
System.clearProperty("test.prop.SKEW_TIME");
System.clearProperty("test.prop.SKEW_UNIT");
}
}
}

View file

@ -494,6 +494,24 @@ public class StaxParserUtil {
return str;
}
/**
* Get the element text, replacing every occurrence of ${..} by corresponding system property value
*
* @param xmlEventReader
*
* @return A <b>trimmed</b> string value with all property references replaced if any.
* If there are no valid references the input string will be returned
*
* @throws ParsingException
*/
public static String getElementTextRP(XMLEventReader xmlEventReader) throws ParsingException {
try {
return trim(StringPropertyReplacer.replaceProperties(xmlEventReader.getElementText()));
} catch (XMLStreamException e) {
throw logger.parserException(e);
}
}
/**
* Get the XML event reader
*

View file

@ -134,7 +134,7 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest {
if (clockSkewSec != null) {
String keycloakSamlXMLContent = IOUtils.toString(keycloakSAMLConfig.openStream(), Charset.forName("UTF-8"))
.replace("%CLOCK_SKEW%", String.valueOf(clockSkewSec));
.replace("%CLOCK_SKEW%", "${allowed.clock.skew:" + String.valueOf(clockSkewSec) + "}");
deployment.addAsWebInfResource(new StringAsset(keycloakSamlXMLContent), "keycloak-saml.xml");
} else {
deployment.addAsWebInfResource(keycloakSAMLConfig, "keycloak-saml.xml");