keycloak-aplcache

Merge pull request #3280 from mposolda/pk-rotation Renamed

10/3/2016 2:37:18 PM

Changes

Details

diff --git a/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigDeploymentProcessor.java b/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigDeploymentProcessor.java
index cdaa375..39630d0 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigDeploymentProcessor.java
+++ b/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigDeploymentProcessor.java
@@ -68,8 +68,9 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
 
         boolean hasSubsystemConfig = service.isSecureDeployment(deploymentUnit);
         boolean webRequiresKC = loginConfig != null && "KEYCLOAK".equalsIgnoreCase(loginConfig.getAuthMethod());
+        boolean isConfigured = service.isDeploymentConfigured(deploymentUnit);
 
-        if (hasSubsystemConfig || webRequiresKC) {
+        if ((hasSubsystemConfig || webRequiresKC) && isConfigured) {
             log.debug("Setting up KEYCLOAK auth method for WAR: " + deploymentUnit.getName());
 
             // if secure-deployment configuration exists for web app, we force KEYCLOAK auth method on it
diff --git a/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigService.java b/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigService.java
index 34c5a6b..210473c 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigService.java
+++ b/adapters/oidc/as7-eap6/as7-subsystem/src/main/java/org/keycloak/subsystem/as7/KeycloakAdapterConfigService.java
@@ -158,15 +158,19 @@ public final class KeycloakAdapterConfigService {
     }
 
     public String getRealmName(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         return deployment.get(RealmDefinition.TAG_NAME).asString();
 
     }
 
+    protected boolean isDeploymentConfigured(DeploymentUnit deploymentUnit) {
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
+        ModelNode resource = deployment.get(SecureDeploymentDefinition.RESOURCE.getName());
+        return resource.isDefined();
+    }
+
     public String getJSON(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
         ModelNode realm = this.realms.get(realmName);
 
@@ -195,6 +199,11 @@ public final class KeycloakAdapterConfigService {
         String deploymentName = preferredDeploymentName(deploymentUnit);
         return this.secureDeployments.containsKey(deploymentName);
     }
+
+    private ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
+        String deploymentName = preferredDeploymentName(deploymentUnit);
+        return this.secureDeployments.get(deploymentName);
+    }
     
     // KEYCLOAK-3273: prefer module name if available
     private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
diff --git a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/org/keycloak/subsystem/as7/LocalDescriptions.properties b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/org/keycloak/subsystem/as7/LocalDescriptions.properties
index fdab53e..aa2efae 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/org/keycloak/subsystem/as7/LocalDescriptions.properties
+++ b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/org/keycloak/subsystem/as7/LocalDescriptions.properties
@@ -80,6 +80,8 @@ keycloak.secure-deployment.register-node-period=how often to re-register node
 keycloak.secure-deployment.token-store=cookie or session storage for auth session data
 keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
 keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
+keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
+keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
 
 keycloak.secure-deployment.credential=Credential value
 
diff --git a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
index 3ab31e7..53549fa 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
+++ b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
@@ -105,6 +105,8 @@
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
             <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+            <xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigDeploymentProcessor.java b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigDeploymentProcessor.java
index 0ec9335..cb341d2 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigDeploymentProcessor.java
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigDeploymentProcessor.java
@@ -67,7 +67,7 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
         DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
 
         KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
-        if (service.isSecureDeployment(deploymentUnit)) {
+        if (service.isSecureDeployment(deploymentUnit) && service.isDeploymentConfigured(deploymentUnit)) {
             addKeycloakAuthData(phaseContext, service);
         }
 
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigService.java b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigService.java
index 5978361..8214c3f 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigService.java
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/KeycloakAdapterConfigService.java
@@ -157,15 +157,19 @@ public final class KeycloakAdapterConfigService {
     }
 
     public String getRealmName(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         return deployment.get(RealmDefinition.TAG_NAME).asString();
 
     }
 
+    protected boolean isDeploymentConfigured(DeploymentUnit deploymentUnit) {
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
+        ModelNode resource = deployment.get(SecureDeploymentDefinition.RESOURCE.getName());
+        return resource.isDefined();
+    }
+
     public String getJSON(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
         ModelNode realm = this.realms.get(realmName);
 
@@ -194,6 +198,11 @@ public final class KeycloakAdapterConfigService {
         String deploymentName = preferredDeploymentName(deploymentUnit);
         return this.secureDeployments.containsKey(deploymentName);
     }
+
+    private ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
+        String deploymentName = preferredDeploymentName(deploymentUnit);
+        return this.secureDeployments.get(deploymentName);
+    }
     
     // KEYCLOAK-3273: prefer module name if available
     private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
index 5788b9e..bf9dd29 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
@@ -22,6 +22,7 @@ import org.jboss.as.controller.SimpleAttributeDefinition;
 import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
 import org.jboss.as.controller.SimpleResourceDefinition;
 import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.IntRangeValidator;
 import org.jboss.as.controller.operations.validation.StringLengthValidator;
 import org.jboss.as.controller.registry.ManagementResourceRegistration;
 import org.jboss.dmr.ModelNode;
@@ -83,6 +84,18 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
                     .setAllowExpression(true)
                     .setDefaultValue(new ModelNode(false))
                     .build();
+    protected static final SimpleAttributeDefinition TOKEN_MINIMUM_TIME_TO_LIVE =
+            new SimpleAttributeDefinitionBuilder("token-minimum-time-to-live", ModelType.INT, true)
+                    .setXmlName("token-minimum-time-to-live")
+                    .setValidator(new IntRangeValidator(-1, true))
+                    .setAllowExpression(true)
+                    .build();
+    protected static final SimpleAttributeDefinition MIN_TIME_BETWEEN_JWKS_REQUESTS =
+            new SimpleAttributeDefinitionBuilder("min-time-between-jwks-requests", ModelType.INT, true)
+                    .setXmlName("min-time-between-jwks-requests")
+                    .setValidator(new IntRangeValidator(-1, true))
+                    .setAllowExpression(true)
+                    .build();
 
     protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
     static {
@@ -93,6 +106,8 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
         DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
     }
 
     protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
index da00498..e6a581a 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
@@ -81,6 +81,8 @@ keycloak.secure-deployment.register-node-period=how often to re-register node
 keycloak.secure-deployment.token-store=cookie or session storage for auth session data
 keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
 keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
+keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
+keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
 
 keycloak.secure-deployment.credential=Credential value
 
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
index 3ab31e7..53549fa 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -105,6 +105,8 @@
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
             <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+            <xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml b/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
index ee37ae5..23e86b0 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
@@ -21,6 +21,8 @@
         <resource>web-console</resource>
         <use-resource-role-mappings>true</use-resource-role-mappings>
         <turn-off-change-session-id-on-login>false</turn-off-change-session-id-on-login>
+        <token-minimum-time-to-live>10</token-minimum-time-to-live>
+        <min-time-between-jwks-requests>20</min-time-between-jwks-requests>
         <realm-public-key>
             MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
         </realm-public-key>
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java
index 9f52c41..24e9ac0 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigDeploymentProcessor.java
@@ -67,7 +67,7 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP
         DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
 
         KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
-        if (service.isSecureDeployment(deploymentUnit)) {
+        if (service.isSecureDeployment(deploymentUnit) && service.isDeploymentConfigured(deploymentUnit)) {
             addKeycloakAuthData(phaseContext, service);
         }
 
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
index b9b3ce3..c30e3ed 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
@@ -157,15 +157,19 @@ public final class KeycloakAdapterConfigService {
     }
 
     public String getRealmName(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         return deployment.get(RealmDefinition.TAG_NAME).asString();
 
     }
 
+    protected boolean isDeploymentConfigured(DeploymentUnit deploymentUnit) {
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
+        ModelNode resource = deployment.get(SecureDeploymentDefinition.RESOURCE.getName());
+        return resource.isDefined();
+    }
+
     public String getJSON(DeploymentUnit deploymentUnit) {
-        String deploymentName = preferredDeploymentName(deploymentUnit);
-        ModelNode deployment = this.secureDeployments.get(deploymentName);
+        ModelNode deployment = getSecureDeployment(deploymentUnit);
         String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
         ModelNode realm = this.realms.get(realmName);
 
@@ -194,6 +198,11 @@ public final class KeycloakAdapterConfigService {
         String deploymentName = preferredDeploymentName(deploymentUnit);
         return this.secureDeployments.containsKey(deploymentName);
     }
+
+    private ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
+        String deploymentName = preferredDeploymentName(deploymentUnit);
+        return this.secureDeployments.get(deploymentName);
+    }
     
     // KEYCLOAK-3273: prefer module name if available
     private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
index 92fb744..636e2ea 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
@@ -22,6 +22,7 @@ import org.jboss.as.controller.SimpleAttributeDefinition;
 import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
 import org.jboss.as.controller.SimpleResourceDefinition;
 import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.IntRangeValidator;
 import org.jboss.as.controller.operations.validation.StringLengthValidator;
 import org.jboss.as.controller.registry.ManagementResourceRegistration;
 import org.jboss.dmr.ModelNode;
@@ -83,6 +84,19 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
                     .setAllowExpression(true)
                     .setDefaultValue(new ModelNode(false))
                     .build();
+    protected static final SimpleAttributeDefinition TOKEN_MINIMUM_TIME_TO_LIVE =
+            new SimpleAttributeDefinitionBuilder("token-minimum-time-to-live", ModelType.INT, true)
+                    .setXmlName("token-minimum-time-to-live")
+                    .setValidator(new IntRangeValidator(-1, true))
+                    .setAllowExpression(true)
+                    .build();
+    protected static final SimpleAttributeDefinition MIN_TIME_BETWEEN_JWKS_REQUESTS =
+            new SimpleAttributeDefinitionBuilder("min-time-between-jwks-requests", ModelType.INT, true)
+                    .setXmlName("min-time-between-jwks-requests")
+                    .setValidator(new IntRangeValidator(-1, true))
+                    .setAllowExpression(true)
+                    .build();
+
 
     protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
     static {
@@ -93,6 +107,8 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
         DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
     }
 
     protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
index da00498..e6a581a 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
@@ -81,6 +81,8 @@ keycloak.secure-deployment.register-node-period=how often to re-register node
 keycloak.secure-deployment.token-store=cookie or session storage for auth session data
 keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
 keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
+keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
+keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
 
 keycloak.secure-deployment.credential=Credential value
 
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
index dba2dae..7372e82 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -105,6 +105,8 @@
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
             <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+            <xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
index 4689065..3dcb61d 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
@@ -45,6 +45,8 @@
         <resource>web-console</resource>
         <use-resource-role-mappings>true</use-resource-role-mappings>
         <turn-off-change-session-id-on-login>false</turn-off-change-session-id-on-login>
+        <token-minimum-time-to-live>10</token-minimum-time-to-live>
+        <min-time-between-jwks-requests>20</min-time-between-jwks-requests>
         <realm-public-key>
             MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
         </realm-public-key>
diff --git a/distribution/demo-dist/src/main/xslt/standalone.xsl b/distribution/demo-dist/src/main/xslt/standalone.xsl
index 856980a..6099aa2 100755
--- a/distribution/demo-dist/src/main/xslt/standalone.xsl
+++ b/distribution/demo-dist/src/main/xslt/standalone.xsl
@@ -42,14 +42,14 @@
     <xsl:template match="//ds:datasources">
         <xsl:copy>
             <xsl:apply-templates select="node()[name(.)='datasource']"/>
-            <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" use-java-context="true">
+            <xa-datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" use-java-context="true">
                 <xa-datasource-property name="URL">jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</xa-datasource-property>
                 <driver>h2</driver>
                 <security>
                     <user-name>sa</user-name>
                     <password>sa</password>
                 </security>
-            </datasource>
+            </xa-datasource>
             <xsl:apply-templates select="node()[name(.)='drivers']"/>
         </xsl:copy>
     </xsl:template>
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
index 1468460..5173c3c 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
@@ -40,7 +40,7 @@ public interface InfinispanConnectionProvider extends Provider {
     String AUTHORIZATION_CACHE_NAME = "authorization";
 
     String KEYS_CACHE_NAME = "keys";
-    int KEYS_CACHE_DEFAULT_MAX = 500;
+    int KEYS_CACHE_DEFAULT_MAX = 1000;
     int KEYS_CACHE_MAX_IDLE_SECONDS = 3600;
 
 
diff --git a/model/infinispan/src/test/java/org/keycloak/models/keys/infinispan/InfinispanKeyStorageProviderTest.java b/model/infinispan/src/test/java/org/keycloak/models/keys/infinispan/InfinispanKeyStorageProviderTest.java
index 99a5f07..5a15dc3 100644
--- a/model/infinispan/src/test/java/org/keycloak/models/keys/infinispan/InfinispanKeyStorageProviderTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/models/keys/infinispan/InfinispanKeyStorageProviderTest.java
@@ -39,8 +39,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.common.util.Time;
 import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
-import org.keycloak.keys.KeyLoader;
-import org.keycloak.keys.infinispan.InfinispanKeyStorageProvider;
+import org.keycloak.keys.PublicKeyLoader;
+import org.keycloak.keys.infinispan.InfinispanPublicKeyStorageProvider;
 import org.keycloak.keys.infinispan.PublicKeysEntry;
 
 /**
@@ -130,14 +130,14 @@ public class InfinispanKeyStorageProviderTest {
 
         @Override
         public void run() {
-            InfinispanKeyStorageProvider provider = new InfinispanKeyStorageProvider(keys, tasksInProgress, minTimeBetweenRequests);
+            InfinispanPublicKeyStorageProvider provider = new InfinispanPublicKeyStorageProvider(keys, tasksInProgress, minTimeBetweenRequests);
             provider.getPublicKey(modelKey, "kid1", new SampleLoader(modelKey));
         }
 
     }
 
 
-    private class SampleLoader implements KeyLoader {
+    private class SampleLoader implements PublicKeyLoader {
 
         private final String modelKey;
 
diff --git a/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 5b1f529..392f3b0 100755
--- a/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/server-spi/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -65,4 +65,4 @@ org.keycloak.policy.PasswordPolicyManagerSpi
 org.keycloak.transaction.TransactionManagerLookupSpi
 org.keycloak.credential.hash.PasswordHashSpi
 org.keycloak.credential.CredentialSpi
-org.keycloak.keys.KeyStorageSpi
+org.keycloak.keys.PublicKeyStorageSpi
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
index aec70dc..16a867d 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
@@ -17,16 +17,29 @@
 
 package org.keycloak.authentication.authenticators.client;
 
+
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
 import org.keycloak.OAuth2Constants;
 import org.keycloak.authentication.AuthenticationFlowError;
 import org.keycloak.authentication.ClientAuthenticationFlowContext;
 import org.keycloak.common.util.Time;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
-import org.keycloak.keys.loader.KeyStorageManager;
+import org.keycloak.keys.loader.PublicKeyStorageManager;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.ModelException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.OIDCLoginProtocol;
 import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
@@ -34,19 +47,6 @@ import org.keycloak.provider.ProviderConfigProperty;
 import org.keycloak.representations.JsonWebToken;
 import org.keycloak.services.ServicesLogger;
 import org.keycloak.services.Urls;
-import org.keycloak.services.util.CertificateInfoHelper;
-
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * Client authentication based on JWT signed by client private key .
@@ -163,7 +163,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
     }
 
     protected PublicKey getSignatureValidationKey(ClientModel client, ClientAuthenticationFlowContext context, JWSInput jws) {
-        PublicKey publicKey = KeyStorageManager.getClientPublicKey(context.getSession(), client, jws);
+        PublicKey publicKey = PublicKeyStorageManager.getClientPublicKey(context.getSession(), client, jws);
         if (publicKey == null) {
             Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", "Unable to load public key");
             context.failure(AuthenticationFlowError.CLIENT_CREDENTIALS_SETUP_REQUIRED, challengeResponse);
diff --git a/services/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java b/services/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
index c83d03f..8f971b8 100755
--- a/services/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
+++ b/services/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
@@ -32,7 +32,7 @@ import org.keycloak.events.EventType;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.JWSInputException;
 import org.keycloak.jose.jws.crypto.RSAProvider;
-import org.keycloak.keys.loader.KeyStorageManager;
+import org.keycloak.keys.loader.PublicKeyStorageManager;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -299,7 +299,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
     protected boolean verify(JWSInput jws) {
         if (!getConfig().isValidateSignature()) return true;
 
-        PublicKey publicKey = KeyStorageManager.getIdentityProviderPublicKey(session, session.getContext().getRealm(), getConfig(), jws);
+        PublicKey publicKey = PublicKeyStorageManager.getIdentityProviderPublicKey(session, session.getContext().getRealm(), getConfig(), jws);
 
         return publicKey != null && RSAProvider.verify(jws, publicKey);
     }
diff --git a/services/src/main/java/org/keycloak/keys/loader/ClientPublicKeyLoader.java b/services/src/main/java/org/keycloak/keys/loader/ClientPublicKeyLoader.java
index 39524ce..a788b19 100644
--- a/services/src/main/java/org/keycloak/keys/loader/ClientPublicKeyLoader.java
+++ b/services/src/main/java/org/keycloak/keys/loader/ClientPublicKeyLoader.java
@@ -26,7 +26,7 @@ import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator;
 import org.keycloak.jose.jwk.JSONWebKeySet;
 import org.keycloak.jose.jwk.JWK;
 import org.keycloak.jose.jwk.JWKBuilder;
-import org.keycloak.keys.KeyLoader;
+import org.keycloak.keys.PublicKeyLoader;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelException;
@@ -41,7 +41,7 @@ import org.keycloak.util.JWKSUtils;
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
-public class ClientPublicKeyLoader implements KeyLoader {
+public class ClientPublicKeyLoader implements PublicKeyLoader {
 
     protected static ServicesLogger logger = ServicesLogger.ROOT_LOGGER;
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java
index 62d711f..06de42c 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java
@@ -17,24 +17,21 @@
 
 package org.keycloak.protocol.oidc.endpoints.request;
 
-import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
 import org.keycloak.jose.jws.Algorithm;
 import org.keycloak.jose.jws.JWSHeader;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
-import org.keycloak.keys.KeyStorageProvider;
-import org.keycloak.keys.loader.KeyStorageManager;
+import org.keycloak.keys.loader.PublicKeyStorageManager;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
-import org.keycloak.services.util.CertificateInfoHelper;
 import org.keycloak.util.JsonSerialization;
 
-import java.security.PublicKey;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Parse the parameters from OIDC "request" object
  *
@@ -57,7 +54,7 @@ class AuthzEndpointRequestObjectParser extends AuthzEndpointRequestParser {
         if (header.getAlgorithm() == Algorithm.none) {
             this.requestParams = JsonSerialization.readValue(input.getContent(), TypedHashMap.class);
         } else if (header.getAlgorithm() == Algorithm.RS256) {
-            PublicKey clientPublicKey = KeyStorageManager.getClientPublicKey(session, client, input);
+            PublicKey clientPublicKey = PublicKeyStorageManager.getClientPublicKey(session, client, input);
             if (clientPublicKey == null) {
                 throw new RuntimeException("Client public key not found");
             }
diff --git a/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties b/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
index bb4b18c..fab6bdb 100644
--- a/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
+++ b/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
@@ -73,7 +73,7 @@ keycloak.server.subsys.default.config=\
         <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>\
         <provider name="jboss" enabled="true"/>\
     </spi>\
-    <spi name="keyStorage">\
+    <spi name="publicKeyStorage">\
         <provider name="infinispan" enabled="true">\
               <properties>\
                   <property name="minTimeBetweenRequests" value="10"/>\
diff --git a/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli b/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
index cbfdd53..4147398 100644
--- a/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
+++ b/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
@@ -19,5 +19,5 @@
 /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default/:add(properties={cacheContainer => "java:comp/env/infinispan/Keycloak"},enabled=true)
 /subsystem=keycloak-server/spi=jta-lookup/:add(default-provider=${keycloak.jta.lookup.provider:jboss})
 /subsystem=keycloak-server/spi=jta-lookup/provider=jboss/:add(enabled=true)
-/subsystem=keycloak-server/spi=keyStorage/:add
-/subsystem=keycloak-server/spi=keyStorage/provider=infinispan/:add(properties={minTimeBetweenRequests => "10"},enabled=true)
\ No newline at end of file
+/subsystem=keycloak-server/spi=publicKeyStorage/:add
+/subsystem=keycloak-server/spi=publicKeyStorage/provider=infinispan/:add(properties={minTimeBetweenRequests => "10"},enabled=true)
\ No newline at end of file