keycloak-aplcache
Changes
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicy.java 8(+6 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java 108(+102 -6)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicy.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicy.java 3(+1 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicy.java 3(+1 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java 38(+21 -17)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicy.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicy.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicy.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicy.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java 6(+4 -2)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java 156(+154 -2)
themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html 43(+39 -4)
themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html 43(+39 -4)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html 47(+43 -4)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html 2(+2 -0)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-drools-detail.html 2(+2 -0)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html 2(+2 -0)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html 2(+2 -0)
themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html 5(+4 -1)
Details
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
index dd9acb3..f4df4c4 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
@@ -215,6 +215,7 @@ public class PolicyResourceService {
             representation1.setId(policy.getId());
             representation1.setName(policy.getName());
             representation1.setType(policy.getType());
+            representation1.setDescription(policy.getDescription());
 
             return representation1;
         }).collect(Collectors.toList())).build();
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicy.java
index 3a27d2b..e87e27c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicy.java
@@ -17,8 +17,8 @@
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
 import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
-import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -37,6 +37,10 @@ public class AggregatePolicy implements PolicyTypeUI {
     }
 
     public void update(AggregatePolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
+    }
+
+    public void createPolicy(AbstractPolicyRepresentation expected) {
+        form().createPolicy(expected);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
index 12c4289..8ed8c39 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
@@ -16,13 +16,30 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
+import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
+import static org.openqa.selenium.By.tagName;
+
+import java.util.List;
 import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.Logic;
+import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
 import org.keycloak.testsuite.console.page.fragment.ModalDialog;
 import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
 import org.keycloak.testsuite.page.Form;
+import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
@@ -45,12 +62,36 @@ public class AggregatePolicyForm extends Form {
     private WebElement deleteButton;
 
     @FindBy(id = "s2id_policies")
-    private MultipleStringSelect2 policySelect;
+    private PolicySelect policySelect;
 
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(AggregatePolicyRepresentation expected) {
+    @FindBy(id = "create-policy")
+    private Select createPolicySelect;
+
+    @Page
+    private RolePolicy rolePolicy;
+
+    @Page
+    private UserPolicy userPolicy;
+
+    @Page
+    private ClientPolicy clientPolicy;
+
+    @Page
+    private JSPolicy jsPolicy;
+
+    @Page
+    private TimePolicy timePolicy;
+
+    @Page
+    private RulePolicy rulePolicy;
+
+    @Page
+    private GroupPolicy groupPolicy;
+
+    public void populate(AggregatePolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
@@ -58,9 +99,11 @@ public class AggregatePolicyForm extends Form {
         Set<String> selectedPolicies = policySelect.getSelected();
         Set<String> policies = expected.getPolicies();
 
-        for (String policy : policies) {
-            if (!selectedPolicies.contains(policy)) {
-                policySelect.select(policy);
+        if (policies != null) {
+            for (String policy : policies) {
+                if (!selectedPolicies.contains(policy)) {
+                    policySelect.select(policy);
+                }
             }
         }
 
@@ -79,7 +122,9 @@ public class AggregatePolicyForm extends Form {
             }
         }
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
@@ -97,4 +142,55 @@ public class AggregatePolicyForm extends Form {
 
         return representation;
     }
+
+    public void createPolicy(AbstractPolicyRepresentation expected) {
+        performOperationWithPageReload(() -> createPolicySelect.selectByValue(expected.getType()));
+
+        if ("role".equals(expected.getType())) {
+            rolePolicy.form().populate((RolePolicyRepresentation) expected, true);
+        } else if ("user".equalsIgnoreCase(expected.getType())) {
+            userPolicy.form().populate((UserPolicyRepresentation) expected, true);
+        } else if ("client".equalsIgnoreCase(expected.getType())) {
+            clientPolicy.form().populate((ClientPolicyRepresentation) expected, true);
+        } else if ("js".equalsIgnoreCase(expected.getType())) {
+            jsPolicy.form().populate((JSPolicyRepresentation) expected, true);
+        } else if ("time".equalsIgnoreCase(expected.getType())) {
+            timePolicy.form().populate((TimePolicyRepresentation) expected, true);
+        } else if ("rules".equalsIgnoreCase(expected.getType())) {
+            rulePolicy.form().populate((RulePolicyRepresentation) expected, true);
+        } else if ("group".equalsIgnoreCase(expected.getType())) {
+            groupPolicy.form().populate((GroupPolicyRepresentation) expected, true);
+        }
+    }
+
+    public class PolicySelect extends MultipleStringSelect2 {
+
+        @Override
+        protected List<WebElement> getSelectedElements() {
+            return getRoot().findElements(By.xpath("(//table[@id='selected-policies'])/tbody/tr")).stream()
+                    .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        protected BiFunction<WebElement, String, Boolean> deselect() {
+            return (webElement, name) -> {
+                List<WebElement> tds = webElement.findElements(tagName("td"));
+
+                if (!tds.get(0).getText().isEmpty()) {
+                    if (tds.get(0).getText().equals(name)) {
+                        tds.get(3).click();
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+        }
+
+        @Override
+        protected Function<WebElement, String> representation() {
+            return webElement -> webElement.findElements(tagName("td")).get(0).getText();
+        }
+    }
 }
\ No newline at end of file
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicy.java
index fe85623..1b582ce 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicy.java
@@ -36,6 +36,6 @@ public class ClientPolicy implements PolicyTypeUI {
     }
 
     public void update(ClientPolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicyForm.java
index cedacee..ad74d60 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/ClientPolicyForm.java
@@ -56,14 +56,16 @@ public class ClientPolicyForm extends Form {
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(ClientPolicyRepresentation expected) {
+    public void populate(ClientPolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
 
         clientsInput.update(expected.getClients());
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicy.java
index 2fd68f4..39703a5 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicy.java
@@ -18,7 +18,6 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
-import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -37,6 +36,6 @@ public class GroupPolicy implements PolicyTypeUI {
     }
 
     public void update(GroupPolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
index e3591e3..3ca088e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
@@ -63,7 +63,7 @@ public class GroupPolicyForm extends Form {
     @Drone
     private WebDriver driver;
 
-    public void populate(GroupPolicyRepresentation expected) {
+    public void populate(GroupPolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         setInputValue(groupsClaim, expected.getGroupsClaim());
@@ -109,7 +109,9 @@ public class GroupPolicyForm extends Form {
                     });
         }
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     private void unselect(String path) {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicy.java
index 94fbb08..3f66ff3 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicy.java
@@ -17,7 +17,6 @@
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
 import org.jboss.arquillian.graphene.page.Page;
-import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
 import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
 
 /**
@@ -37,6 +36,6 @@ public class JSPolicy implements PolicyTypeUI {
     }
 
     public void update(JSPolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicyForm.java
index 9c1c1ea..cb987a9 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/JSPolicyForm.java
@@ -45,7 +45,7 @@ public class JSPolicyForm extends Form {
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(JSPolicyRepresentation expected) {
+    public void populate(JSPolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
@@ -54,7 +54,9 @@ public class JSPolicyForm extends Form {
 
         scriptExecutor.executeScript("angular.element(document.getElementById('code')).scope().policy.code = '" + expected.getCode() + "'");
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
index 12e2fd4..31c5b99 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
@@ -79,40 +79,44 @@ public class Policies extends Form {
         return table;
     }
 
-    public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
+    public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected, boolean save) {
         String type = expected.getType();
 
         performOperationWithPageReload(() -> createSelect.selectByValue(type));
 
         if ("role".equals(type)) {
-            rolePolicy.form().populate((RolePolicyRepresentation) expected);
+            rolePolicy.form().populate((RolePolicyRepresentation) expected, save);
             return (P) rolePolicy;
         } else if ("user".equals(type)) {
-            userPolicy.form().populate((UserPolicyRepresentation) expected);
+            userPolicy.form().populate((UserPolicyRepresentation) expected, save);
             return (P) userPolicy;
         } else if ("aggregate".equals(type)) {
-            aggregatePolicy.form().populate((AggregatePolicyRepresentation) expected);
+            aggregatePolicy.form().populate((AggregatePolicyRepresentation) expected, save);
             return (P) aggregatePolicy;
         } else if ("js".equals(type)) {
-            jsPolicy.form().populate((JSPolicyRepresentation) expected);
+            jsPolicy.form().populate((JSPolicyRepresentation) expected, save);
             return (P) jsPolicy;
         } else if ("time".equals(type)) {
-            timePolicy.form().populate((TimePolicyRepresentation) expected);
+            timePolicy.form().populate((TimePolicyRepresentation) expected, save);
             return (P) timePolicy;
         } else if ("rules".equals(type)) {
-            rulePolicy.form().populate((RulePolicyRepresentation) expected);
+            rulePolicy.form().populate((RulePolicyRepresentation) expected, save);
             return (P) rulePolicy;
         } else if ("client".equals(type)) {
-            clientPolicy.form().populate((ClientPolicyRepresentation) expected);
+            clientPolicy.form().populate((ClientPolicyRepresentation) expected, save);
             return (P) clientPolicy;
         } else if ("group".equals(type)) {
-            groupPolicy.form().populate((GroupPolicyRepresentation) expected);
+            groupPolicy.form().populate((GroupPolicyRepresentation) expected, save);
             return (P) groupPolicy;
         }
 
         return null;
     }
 
+    public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
+        return create(expected, true);
+    }
+
     public void update(String name, AbstractPolicyRepresentation representation) {
         for (WebElement row : policies().rows()) {
             PolicyRepresentation actual = policies().toRepresentation(row);
@@ -121,21 +125,21 @@ public class Policies extends Form {
                 String type = representation.getType();
 
                 if ("role".equals(type)) {
-                    rolePolicy.form().populate((RolePolicyRepresentation) representation);
+                    rolePolicy.form().populate((RolePolicyRepresentation) representation, true);
                 } else if ("user".equals(type)) {
-                    userPolicy.form().populate((UserPolicyRepresentation) representation);
+                    userPolicy.form().populate((UserPolicyRepresentation) representation, true);
                 } else if ("aggregate".equals(type)) {
-                    aggregatePolicy.form().populate((AggregatePolicyRepresentation) representation);
+                    aggregatePolicy.form().populate((AggregatePolicyRepresentation) representation, true);
                 } else if ("js".equals(type)) {
-                    jsPolicy.form().populate((JSPolicyRepresentation) representation);
+                    jsPolicy.form().populate((JSPolicyRepresentation) representation, true);
                 } else if ("time".equals(type)) {
-                    timePolicy.form().populate((TimePolicyRepresentation) representation);
+                    timePolicy.form().populate((TimePolicyRepresentation) representation, true);
                 } else if ("rules".equals(type)) {
-                    rulePolicy.form().populate((RulePolicyRepresentation) representation);
+                    rulePolicy.form().populate((RulePolicyRepresentation) representation, true);
                 } else if ("client".equals(type)) {
-                    clientPolicy.form().populate((ClientPolicyRepresentation) representation);
+                    clientPolicy.form().populate((ClientPolicyRepresentation) representation, true);
                 } else if ("group".equals(type)) {
-                    groupPolicy.form().populate((GroupPolicyRepresentation) representation);
+                    groupPolicy.form().populate((GroupPolicyRepresentation) representation, true);
                 }
 
                 return;
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicy.java
index 8d4be91..e726fa9 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicy.java
@@ -36,6 +36,6 @@ public class RolePolicy implements PolicyTypeUI {
     }
 
     public void update(RolePolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
index f917678..2a866df 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
@@ -64,7 +64,7 @@ public class RolePolicyForm extends Form {
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(RolePolicyRepresentation expected) {
+    public void populate(RolePolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
@@ -88,7 +88,9 @@ public class RolePolicyForm extends Form {
         unSelect(roles, realmRoleSelect.getSelected());
         unSelect(roles, clientRoleSelect.getSelected());
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     private void unSelect(Set<RolePolicyRepresentation.RoleDefinition> roles, Set<RolePolicyRepresentation.RoleDefinition> selection) {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicy.java
index 6d46347..706b2bf 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicy.java
@@ -36,6 +36,6 @@ public class RulePolicy implements PolicyTypeUI {
     }
 
     public void update(RulePolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
index a990bc4..0103aaf 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
@@ -75,7 +75,7 @@ public class RulePolicyForm extends Form {
     @FindBy(id = "resolveModule")
     private WebElement resolveModuleButton;
 
-    public void populate(RulePolicyRepresentation expected) {
+    public void populate(RulePolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         setInputValue(artifactGroupId, expected.getArtifactGroupId());
@@ -94,7 +94,9 @@ public class RulePolicyForm extends Form {
         scannerPeriodUnit.selectByVisibleText(expected.getScannerPeriodUnit());
         logic.selectByValue(expected.getLogic().name());
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicy.java
index ce2a20a..0d74aa1 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicy.java
@@ -36,6 +36,6 @@ public class TimePolicy implements PolicyTypeUI {
     }
 
     public void update(TimePolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicyForm.java
index 47be24d..9a9f16a 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/TimePolicyForm.java
@@ -81,7 +81,7 @@ public class TimePolicyForm extends Form {
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(TimePolicyRepresentation expected) {
+    public void populate(TimePolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
@@ -98,7 +98,9 @@ public class TimePolicyForm extends Form {
         setInputValue(minute, expected.getMinute());
         setInputValue(minuteEnd, expected.getMinuteEnd());
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicy.java
index cd5b8eb..9371ad5 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicy.java
@@ -36,6 +36,6 @@ public class UserPolicy implements PolicyTypeUI {
     }
 
     public void update(UserPolicyRepresentation expected) {
-        form().populate(expected);
+        form().populate(expected, true);
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
index ec24ace..172d5ab 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
@@ -56,14 +56,16 @@ public class UserPolicyForm extends Form {
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
-    public void populate(UserPolicyRepresentation expected) {
+    public void populate(UserPolicyRepresentation expected, boolean save) {
         setInputValue(name, expected.getName());
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
 
         usersInput.update(expected.getUsers());
 
-        save();
+        if (save) {
+            save();
+        }
     }
 
     public void delete() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
index be2a984..19ccbdc 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
@@ -20,21 +20,35 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import java.util.UUID;
 import java.util.stream.Collectors;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.AuthorizationResource;
+import org.keycloak.admin.client.resource.ClientsResource;
 import org.keycloak.admin.client.resource.PoliciesResource;
+import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.admin.client.resource.RolePoliciesResource;
 import org.keycloak.admin.client.resource.RolesResource;
+import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.common.Version;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.Logic;
 import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
 import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.admin.ApiUtil;
 import org.keycloak.testsuite.console.page.clients.authorization.policy.AggregatePolicy;
 import org.keycloak.testsuite.console.page.clients.authorization.policy.UserPolicy;
+import org.keycloak.testsuite.util.ClientBuilder;
+import org.keycloak.testsuite.util.GroupBuilder;
+import org.keycloak.testsuite.util.UserBuilder;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -44,16 +58,22 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
     @Before
     public void configureTest() {
         super.configureTest();
-        RolesResource realmRoles = testRealmResource().roles();
+        RealmResource realmResource = testRealmResource();
+        RolesResource realmRoles = realmResource.roles();
         realmRoles.create(new RoleRepresentation("Role A", "", false));
         realmRoles.create(new RoleRepresentation("Role B", "", false));
+        UsersResource users = realmResource.users();
+        users.create(UserBuilder.create().username("user a").build());
+        ClientsResource clients = realmResource.clients();
+        clients.create(ClientBuilder.create().clientId("client a").build());
+        realmResource.groups().add(GroupBuilder.create().name("Group A").build());
 
         RolePolicyRepresentation policyA = new RolePolicyRepresentation();
 
         policyA.setName("Policy A");
         policyA.addRole("Role A");
 
-        AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
+        AuthorizationResource authorization = realmResource.clients().get(newClient.getId()).authorization();
         PoliciesResource policies = authorization.policies();
         RolePoliciesResource roles = policies.role();
 
@@ -138,6 +158,138 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
         assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
     }
 
+    @Test
+    public void testCreateWithChild() {
+        AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
+
+        expected.setName("Test Child Create Aggregate Policy");
+        expected.setDescription("description");
+
+        AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected, false);
+
+        RolePolicyRepresentation childPolicy = new RolePolicyRepresentation();
+
+        childPolicy.setName(UUID.randomUUID().toString());
+        childPolicy.addRole("Role A");
+
+        policy.createPolicy(childPolicy);
+        policy.form().save();
+
+        assertAlertSuccess();
+
+        expected.addPolicy(childPolicy.getName());
+
+        authorizationPage.navigateTo();
+        AggregatePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
+        assertPolicy(expected, actual);
+    }
+
+    @Test
+    public void testCreateWithChildAndSelectedPolicy() {
+        AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
+
+        expected.setName("Test Child Create And Select Aggregate Policy");
+        expected.setDescription("description");
+        expected.addPolicy("Policy C");
+
+        AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected, false);
+
+        RolePolicyRepresentation childRolePolicy = new RolePolicyRepresentation();
+        childRolePolicy.setName(UUID.randomUUID().toString());
+        childRolePolicy.addRole("Role A");
+        policy.createPolicy(childRolePolicy);
+        expected.addPolicy(childRolePolicy.getName());
+
+        UserPolicyRepresentation childUserPolicy = new UserPolicyRepresentation();
+        childUserPolicy.setName(UUID.randomUUID().toString());
+        childUserPolicy.setDescription("description");
+        childUserPolicy.addUser("user a");
+        policy.createPolicy(childUserPolicy);
+        expected.addPolicy(childUserPolicy.getName());
+
+        ClientPolicyRepresentation childClientPolicy = new ClientPolicyRepresentation();
+        childClientPolicy.setName(UUID.randomUUID().toString());
+        childClientPolicy.setDescription("description");
+        childClientPolicy.addClient("client a");
+        policy.createPolicy(childClientPolicy);
+        expected.addPolicy(childClientPolicy.getName());
+
+        JSPolicyRepresentation childJSPolicy = new JSPolicyRepresentation();
+
+        childJSPolicy.setName(UUID.randomUUID().toString());
+        childJSPolicy.setDescription("description");
+        childJSPolicy.setCode("$evaluation.grant();");
+        policy.createPolicy(childJSPolicy);
+        expected.addPolicy(childJSPolicy.getName());
+
+        TimePolicyRepresentation childTimePolicy = new TimePolicyRepresentation();
+
+        childTimePolicy.setName(UUID.randomUUID().toString());
+        childTimePolicy.setDescription("description");
+        childTimePolicy.setNotBefore("2017-01-01 00:00:00");
+        childTimePolicy.setNotBefore("2018-01-01 00:00:00");
+        policy.createPolicy(childTimePolicy);
+        expected.addPolicy(childTimePolicy.getName());
+
+        RulePolicyRepresentation rulePolicy = new RulePolicyRepresentation();
+
+        rulePolicy.setName(UUID.randomUUID().toString());
+        rulePolicy.setDescription("description");
+        rulePolicy.setArtifactGroupId("org.keycloak");
+        rulePolicy.setArtifactId("photoz-authz-policy");
+        rulePolicy.setArtifactVersion(Version.VERSION);
+        rulePolicy.setModuleName("PhotozAuthzOwnerPolicy");
+        rulePolicy.setSessionName("MainOwnerSession");
+        rulePolicy.setScannerPeriod("1");
+        rulePolicy.setScannerPeriodUnit("Minutes");
+        policy.createPolicy(rulePolicy);
+        expected.addPolicy(rulePolicy.getName());
+
+        GroupPolicyRepresentation childGroupPolicy = new GroupPolicyRepresentation();
+
+        childGroupPolicy.setName(UUID.randomUUID().toString());
+        childGroupPolicy.setDescription("description");
+        childGroupPolicy.setGroupsClaim("groups");
+        childGroupPolicy.addGroupPath("/Group A", true);
+        policy.createPolicy(childGroupPolicy);
+        expected.addPolicy(childGroupPolicy.getName());
+
+        policy.form().save();
+        assertAlertSuccess();
+
+        authorizationPage.navigateTo();
+        AggregatePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
+        assertPolicy(expected, actual);
+    }
+
+    @Test
+    public void testUpdateWithChild() {
+        AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
+
+        expected.setName("Test Child Update Aggregate Policy");
+        expected.setDescription("description");
+        expected.addPolicy("Policy C");
+
+        AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
+        assertAlertSuccess();
+        assertPolicy(expected, policy);
+
+        RolePolicyRepresentation childPolicy = new RolePolicyRepresentation();
+
+        childPolicy.setName(UUID.randomUUID().toString());
+        childPolicy.addRole("Role A");
+
+        policy.createPolicy(childPolicy);
+
+        policy.form().save();
+
+        expected.addPolicy(childPolicy.getName());
+
+        authorizationPage.navigateTo();
+        AggregatePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
+        assertPolicy(expected, actual);
+    }
+
     private AggregatePolicyRepresentation createPolicy(AggregatePolicyRepresentation expected) {
         AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
         assertAlertSuccess();
                diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index ca2c23f..dd69970 100644
--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -1106,6 +1106,7 @@ authz-resources=Resources
 authz-scope=Scope
 authz-authz-scopes=Authorization Scopes
 authz-policies=Policies
+authz-policy=Policy
 authz-permissions=Permissions
 authz-users=Users in Role
 authz-evaluate=Evaluate
@@ -1153,7 +1154,7 @@ authz-no-type-defined=No type defined.
 authz-no-uri-defined=No URI defined.
 authz-no-permission-assigned=No permission assigned.
 authz-no-policy-assigned=No policy assigned.
-authz-create-permission=Create permission
+authz-create-permission=Create Permission
 
 # Authz Resource Detail
 authz-add-resource=Add Resource
@@ -1172,7 +1173,7 @@ authz-scope-name.tooltip=An unique name for this scope. The name can be used to 
 
 # Authz Policy List
 authz-all-types=All types
-authz-create-policy=Create policy
+authz-create-policy=Create Policy
 authz-no-policies-available=No policies available.
 
 # Authz Policy Detail
@@ -1189,7 +1190,8 @@ authz-policy-decision-strategy.tooltip=The decision strategy dictates how the po
 authz-policy-decision-strategy-affirmative=Affirmative
 authz-policy-decision-strategy-unanimous=Unanimous
 authz-policy-decision-strategy-consensus=Consensus
-authz-select-a-policy=Select a policy
+authz-select-a-policy=Select existing policy
+authz-no-policies-assigned=No policies assigned.
 
 # Authz Role Policy Detail
 authz-add-role-policy=Add Role Policy
                diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index 116c124..e6f7d5c 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -871,7 +871,7 @@ module.controller('ResourceServerPolicyDroolsDetailCtrl', function($scope, $http
     }, realm, client, $scope);
 });
 
-module.controller('ResourceServerPolicyResourceDetailCtrl', function($scope, $route, $location, realm, client, PolicyController, ResourceServerPermission, ResourceServerResource) {
+module.controller('ResourceServerPolicyResourceDetailCtrl', function($scope, $route, $location, realm, client, PolicyController, ResourceServerPermission, ResourceServerResource, policyState) {
     PolicyController.onInit({
         getPolicyType : function() {
             return "resource";
@@ -1009,7 +1009,7 @@ module.controller('ResourceServerPolicyResourceDetailCtrl', function($scope, $ro
         },
 
         onInitCreate : function(newPolicy) {
-            newPolicy.decisionStrategy = 'UNANIMOUS';
+            policyState.state.previousPage.name = 'authz-add-resource-permission';
             $scope.selectedResource = null;
             var copy = angular.copy($scope.selectedResource);
             $scope.$watch('selectedResource', function() {
@@ -1058,11 +1058,22 @@ module.controller('ResourceServerPolicyResourceDetailCtrl', function($scope, $ro
 
             $scope.policy.policies = policies;
             delete $scope.policy.config;
+        },
+
+        onSaveState : function(policy) {
+            policyState.state.selectedResource = $scope.selectedResource;
+            policyState.state.applyToResourceTypeFlag = $scope.applyToResourceTypeFlag;
+        },
+
+        onRestoreState : function(policy) {
+            $scope.selectedResource = policyState.state.selectedResource;
+            $scope.applyToResourceTypeFlag = policyState.state.applyToResourceTypeFlag;
+            policy.resourceType = policyState.state.policy.resourceType;
         }
     }, realm, client, $scope);
 });
 
-module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route, $location, realm, client, PolicyController, ResourceServerPolicy, ResourceServerResource, ResourceServerScope) {
+module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route, $location, realm, client, PolicyController, ResourceServerPolicy, ResourceServerResource, ResourceServerScope, policyState) {
     PolicyController.onInit({
         getPolicyType : function() {
             return "scope";
@@ -1307,8 +1318,7 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
         },
 
         onInitCreate : function(newPolicy) {
-            newPolicy.decisionStrategy = 'UNANIMOUS';
-
+            policyState.state.previousPage.name = 'authz-add-scope-permission';
             var scopeId = $location.search()['scpid'];
 
             if (scopeId) {
@@ -1351,6 +1361,18 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
 
             $scope.policy.policies = policies;
             delete $scope.policy.config;
+        },
+
+        onSaveState : function(policy) {
+            policyState.state.selectedScopes = $scope.selectedScopes;
+            policyState.state.selectedResource = $scope.selectedResource;
+            policyState.state.resourceScopes = $scope.resourceScopes;
+        },
+
+        onRestoreState : function(policy) {
+            $scope.selectedScopes = policyState.state.selectedScopes;
+            $scope.selectedResource = policyState.state.selectedResource;
+            $scope.resourceScopes = policyState.state.resourceScopes;
         }
     }, realm, client, $scope);
 });
@@ -1814,7 +1836,7 @@ module.controller('ResourceServerPolicyGroupDetailCtrl', function($scope, $route
                 if (!angular.equals($scope.selectedGroups, selectedGroups)) {
                     $scope.changed = true;
                 } else {
-                    $scope.changed = false;
+                    $scope.changed = PolicyController.isNewAssociatedPolicy();
                 }
             }, true);
         },
@@ -1890,6 +1912,7 @@ module.controller('ResourceServerPolicyTimeDetailCtrl', function($scope, $route,
         },
 
         onInit : function() {
+
         },
 
         onInitUpdate : function(policy) {
@@ -1956,7 +1979,7 @@ module.controller('ResourceServerPolicyTimeDetailCtrl', function($scope, $route,
     }
 });
 
-module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $route, $location, realm, PolicyController, ResourceServerPolicy, client) {
+module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $route, $location, realm, PolicyController, ResourceServerPolicy, client, PolicyProvider, policyState) {
     PolicyController.onInit({
         getPolicyType : function() {
             return "aggregate";
@@ -2025,7 +2048,7 @@ module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $r
         },
 
         onInitCreate : function(newPolicy) {
-            newPolicy.decisionStrategy = 'UNANIMOUS';
+            policyState.state.previousPage.name = 'authz-add-aggregated-policy';
         },
 
         onCreate : function() {
@@ -2041,11 +2064,116 @@ module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $r
     }, realm, client, $scope);
 });
 
-module.service("PolicyController", function($http, $route, $location, ResourceServer, ResourceServerPolicy, ResourceServerPermission, AuthzDialog, Notifications) {
+module.service("PolicyController", function($http, $route, $location, ResourceServer, ResourceServerPolicy, ResourceServerPermission, AuthzDialog, Notifications, policyState, PolicyProvider) {
 
     var PolicyController = {};
 
+    PolicyController.isNewAssociatedPolicy = function() {
+        return $route.current.params['new_policy'] != null;
+    }
+
+    PolicyController.isBackNewAssociatedPolicy = function() {
+        return $route.current.params['back'] != null;
+    }
+
     PolicyController.onInit = function(delegate, realm, client, $scope) {
+        $scope.policyProviders = [];
+
+        PolicyProvider.query({
+            realm : $route.current.params.realm,
+            client : client.id
+        }, function (data) {
+            for (i = 0; i < data.length; i++) {
+                if (data[i].type != 'resource' && data[i].type != 'scope') {
+                    $scope.policyProviders.push(data[i]);
+                }
+            }
+        });
+
+        if ((!policyState.state || !PolicyController.isBackNewAssociatedPolicy()) && !PolicyController.isNewAssociatedPolicy()) {
+            policyState.state = {};
+        }
+
+        if (!policyState.state.previousPage) {
+            policyState.state.previousPage = {};
+        }
+
+        $scope.policyState = policyState;
+
+        $scope.addPolicy = function(policyType) {
+            policyState.state.policy = $scope.policy;
+
+            if (delegate.onSaveState) {
+               delegate.onSaveState($scope.policy);
+            }
+
+            if ($scope.selectedPolicies) {
+                policyState.state.selectedPolicies = $scope.selectedPolicies;
+            }
+            var previousUrl = window.location.href.substring(window.location.href.indexOf('/realms'));
+
+            if (previousUrl.indexOf('back=true') == -1) {
+                previousUrl = previousUrl + '?back=true';
+            }
+            policyState.state.previousUrl = previousUrl;
+            $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/" + policyType.type + "/create?new_policy=true");
+        }
+
+        $scope.detailPolicy = function(policy) {
+            policyState.state.policy = $scope.policy;
+            if (delegate.onSaveState) {
+               delegate.onSaveState($scope.policy);
+            }
+            if ($scope.selectedPolicies) {
+                policyState.state.selectedPolicies = $scope.selectedPolicies;
+            }
+            var previousUrl = window.location.href.substring(window.location.href.indexOf('/realms'));
+
+            if (previousUrl.indexOf('back=true') == -1) {
+                previousUrl = previousUrl + '?back=true';
+            }
+            policyState.state.previousUrl = previousUrl;
+            $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/" + policy.type + "/" + policy.id + "?new_policy=true");
+        }
+
+        $scope.removePolicy = function(list, policy) {
+            for (i = 0; i < angular.copy(list).length; i++) {
+                if (policy.id == list[i].id) {
+                    list.splice(i, 1);
+                }
+            }
+        }
+
+        $scope.selectPolicy = function(policy) {
+            if (!policy || !policy.id) {
+                return;
+            }
+
+            if (!$scope.selectedPolicies) {
+                $scope.selectedPolicies = [];
+            }
+
+            $scope.selectedPolicy = null;
+
+            for (i = 0; i < $scope.selectedPolicies.length; i++) {
+                if ($scope.selectedPolicies[i].id == policy.id) {
+                    return;
+                }
+            }
+
+            $scope.selectedPolicies.push(policy);
+        }
+
+        $scope.createNewPolicy = function() {
+            $scope.showNewPolicy = true;
+        }
+
+        $scope.cancelCreateNewPolicy = function() {
+            $scope.showNewPolicy = false;
+        }
+
+        $scope.historyBackOnSaveOrCancel = PolicyController.isNewAssociatedPolicy();
+
         if (!delegate.isPermission) {
             delegate.isPermission = function () {
                 return false;
@@ -2078,17 +2206,15 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
 
             if (!policyId) {
                 $scope.create = true;
-                $scope.changed = false;
 
                 var policy = {};
 
                 policy.type = delegate.getPolicyType();
                 policy.config = {};
                 policy.logic = 'POSITIVE';
+                policy.decisionStrategy = 'UNANIMOUS';
 
-                if (delegate.onInitCreate) {
-                    delegate.onInitCreate(policy);
-                }
+                $scope.changed = $scope.historyBackOnSaveOrCancel || PolicyController.isBackNewAssociatedPolicy();
 
                 $scope.policy = angular.copy(policy);
 
@@ -2098,6 +2224,15 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                     }
                 }, true);
 
+                if (PolicyController.isBackNewAssociatedPolicy()) {
+                    if (delegate.onRestoreState) {
+                        delegate.onRestoreState($scope.policy);
+                    }
+                    $instance.restoreState($scope);
+                } else if (delegate.onInitCreate) {
+                   delegate.onInitCreate(policy);
+                }
+
                 $scope.save = function() {
                     $instance.checkNameAvailability(function () {
                         if (delegate.onCreate) {
@@ -2105,10 +2240,20 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                         }
                         service.save({realm : realm.realm, client : client.id, type: $scope.policy.type}, $scope.policy, function(data) {
                             if (delegate.isPermission()) {
-                                $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission/" + $scope.policy.type + "/" + data.id);
+                                if ($scope.historyBackOnSaveOrCancel) {
+                                    policyState.state.newPolicyName = $scope.policy.name;
+                                    $location.url(policyState.state.previousUrl);
+                                } else {
+                                    $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission/" + $scope.policy.type + "/" + data.id);
+                                }
                                 Notifications.success("The permission has been created.");
                             } else {
-                                $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/" + $scope.policy.type + "/" + data.id);
+                                if ($scope.historyBackOnSaveOrCancel) {
+                                    policyState.state.newPolicyName = $scope.policy.name;
+                                    $location.url(policyState.state.previousUrl);
+                                } else {
+                                    $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/" + $scope.policy.type + "/" + data.id);
+                                }
                                 Notifications.success("The policy has been created.");
                             }
                         });
@@ -2117,9 +2262,17 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
 
                 $scope.reset = function() {
                     if (delegate.isPermission()) {
-                        $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission/");
+                        if ($scope.historyBackOnSaveOrCancel) {
+                            $location.url(policyState.state.previousUrl);
+                        } else {
+                            $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission/");
+                        }
                     } else {
-                        $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/");
+                        if ($scope.historyBackOnSaveOrCancel) {
+                            $location.url(policyState.state.previousUrl);
+                        } else {
+                            $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/");
+                        }
                     }
                 }
             } else {
@@ -2132,12 +2285,18 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                     $scope.originalPolicy = data;
                     var policy = angular.copy(data);
 
-                    if (delegate.onInitUpdate) {
+                    $scope.changed = $scope.historyBackOnSaveOrCancel || PolicyController.isBackNewAssociatedPolicy();
+
+                    if (PolicyController.isBackNewAssociatedPolicy()) {
+                        if (delegate.onRestoreState) {
+                            delegate.onRestoreState($scope.policy);
+                        }
+                        $instance.restoreState($scope);
+                    } else if (delegate.onInitUpdate) {
                         delegate.onInitUpdate(policy);
                     }
 
                     $scope.policy = angular.copy(policy);
-                    $scope.changed = false;
 
                     $scope.$watch('policy', function() {
                         if (!angular.equals($scope.policy, policy)) {
@@ -2145,16 +2304,28 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                         }
                     }, true);
 
+
                     $scope.save = function() {
                         $instance.checkNameAvailability(function () {
                             if (delegate.onUpdate) {
                                 delegate.onUpdate();
                             }
                             service.update({realm : realm.realm, client : client.id, type: $scope.policy.type, id : $scope.policy.id}, $scope.policy, function() {
-                                $route.reload();
                                 if (delegate.isPermission()) {
+                                    if ($scope.historyBackOnSaveOrCancel) {
+                                        $location.url(policyState.state.previousUrl);
+                                    } else {
+                                        $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission/" + $scope.policy.type + "/" + $scope.policy.id);
+                                    }
+                                    $route.reload();
                                     Notifications.success("The permission has been updated.");
                                 } else {
+                                    if ($scope.historyBackOnSaveOrCancel) {
+                                        $location.url(policyState.state.previousUrl);
+                                    } else {
+                                        $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy/" + $scope.policy.type + "/" + $scope.policy.id);
+                                    }
+                                    $route.reload();
                                     Notifications.success("The policy has been updated.");
                                 }
                             });
@@ -2162,14 +2333,18 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                     }
 
                     $scope.reset = function() {
-                        var freshPolicy = angular.copy(data);
+                        if ($scope.historyBackOnSaveOrCancel) {
+                            $location.url(policyState.state.previousUrl);
+                        } else {
+                            var freshPolicy = angular.copy(data);
 
-                        if (delegate.onInitUpdate) {
-                            delegate.onInitUpdate(freshPolicy);
-                        }
+                            if (delegate.onInitUpdate) {
+                                delegate.onInitUpdate(freshPolicy);
+                            }
 
-                        $scope.policy = angular.copy(freshPolicy);
-                        $scope.changed = false;
+                            $scope.policy = angular.copy(freshPolicy);
+                            $scope.changed = false;
+                        }
                     }
                 });
 
@@ -2199,6 +2374,44 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
                 }
             });
         }
+
+        this.restoreState = function($scope) {
+            $scope.policy.name = policyState.state.policy.name;
+            $scope.policy.description = policyState.state.policy.description;
+            $scope.policy.decisionStrategy = policyState.state.policy.decisionStrategy;
+            $scope.policy.logic = policyState.state.policy.logic;
+            $scope.selectedPolicies = policyState.state.selectedPolicies;
+
+            if (!$scope.selectedPolicies) {
+                $scope.selectedPolicies = [];
+            }
+
+            $scope.changed = true;
+            var previousPage = policyState.state.previousPage;
+
+            if (policyState.state.newPolicyName) {
+                ResourceServerPolicy.query({
+                   realm: realm.realm,
+                   client : client.id,
+                   permission: false,
+                   name: policyState.state.newPolicyName,
+                   max : 20,
+                   first : 0
+               }, function(response) {
+                    for (i = 0; i < response.length; i++) {
+                        if (response[i].name == policyState.state.newPolicyName) {
+                            response[i].text = response[i].name;
+                            $scope.selectedPolicies.push(response[i]);
+                        }
+                    }
+                    policyState.state = {};
+                    policyState.state.previousPage = previousPage;
+                });
+            } else {
+                policyState.state = {};
+                policyState.state.previousPage = previousPage;
+            }
+        }
     }
 
     return PolicyController;
                diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
index 12315ed..12ca430 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
@@ -200,5 +200,11 @@ module.factory('GroupManagementPermissions', function($resource) {
     });
 });
 
-
+module.factory('policyState', [function () {
+    return {
+        model: {
+            state: {}
+        }
+    };
+}]);
 
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
index 89f8b36..cbd06fd 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
@@ -54,11 +54,46 @@
             </div>
             <div class="form-group clearfix">
                 <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
-
-                <div class="col-md-6">
-                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple />
+                <div class="col-sm-6">
+                     <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." />
+                    <p/>
+                    <table class="table table-striped table-bordered" id="selected-policies">
+                        <thead>
+                        <tr>
+                            <th class="kc-table-actions" colspan="3">
+                                <div class="form-inline">
+                                    <div class="form-group">
+                                    </div>
+                                    <div class="pull-right">
+                                        <select id="create-policy" class="form-control" ng-model="policyType"
+                                                ng-options="p.name for p in policyProviders track by p.type"
+                                                data-ng-change="addPolicy(policyType);">
+                                            <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </th>
+                        </tr>
+                        <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
+                            <th>{{:: 'name' | translate}}</th>
+                            <th>{{:: 'description' | translate}}</th>
+                            <th>{{:: 'actions' | translate}}</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        <tr ng-repeat="policy in selectedPolicies">
+                            <td><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+                            <td>{{policy.description}}</td>
+                            <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+                                {{:: 'remove' | translate}}
+                            </td>
+                        </tr>
+                        <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0">
+                            <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td>
+                        </tr>
+                        </tbody>
+                    </table>
                 </div>
-
                 <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
index 49e533f..4f469a2 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
@@ -58,11 +58,46 @@
             </div>
             <div class="form-group clearfix">
                 <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
-
-                <div class="col-md-6">
-                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple />
+                <div class="col-sm-6">
+                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." />
+                    <p/>
+                    <table class="table table-striped table-bordered" id="selected-policies">
+                        <thead>
+                        <tr>
+                            <th class="kc-table-actions" colspan="3">
+                                <div class="form-inline">
+                                    <div class="form-group">
+                                    </div>
+                                    <div class="pull-right">
+                                        <select id="create-policy" class="form-control" ng-model="policyType"
+                                                ng-options="p.name for p in policyProviders track by p.type"
+                                                data-ng-change="addPolicy(policyType);">
+                                            <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </th>
+                        </tr>
+                        <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
+                            <th>{{:: 'name' | translate}}</th>
+                            <th>{{:: 'description' | translate}}</th>
+                            <th>{{:: 'actions' | translate}}</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        <tr ng-repeat="policy in selectedPolicies">
+                            <td><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+                            <td>{{policy.description}}</td>
+                            <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+                                {{:: 'remove' | translate}}
+                            </td>
+                        </tr>
+                        <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0">
+                            <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td>
+                        </tr>
+                        </tbody>
+                    </table>
                 </div>
-
                 <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
index 11d0827..acaa7a2 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
@@ -5,6 +5,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-aggregated-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'authz-aggregated' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
@@ -32,15 +34,52 @@
             </div>
             <div class="form-group clearfix">
                 <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
-
-                <div class="col-md-6">
-                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
+                <div class="col-sm-6">
+                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." data-ng-required="!selectedPolicies || selectedPolicies.length == 0"/>
+                    <p/>
+                    <table class="table table-striped table-bordered" id="selected-policies">
+                        <thead>
+                            <tr>
+                                <th class="kc-table-actions" colspan="3">
+                                    <div class="form-inline">
+                                        <div class="form-group">
+                                        </div>
+                                        <div class="pull-right">
+                                            <select id="create-policy" class="form-control" ng-model="policyType"
+                                                    ng-options="p.name for p in policyProviders track by p.type"
+                                                    data-ng-change="addPolicy(policyType);"
+                                                    data-ng-hide="historyBackOnSaveOrCancel">
+                                                <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+                                            </select>
+                                        </div>
+                                    </div>
+                                </th>
+                            </tr>
+                            <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
+                                <th>{{:: 'name' | translate}}</th>
+                                <th>{{:: 'description' | translate}}</th>
+                                <th>{{:: 'actions' | translate}}</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr ng-repeat="policy in selectedPolicies">
+                                <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+                                <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td>
+                                <td>{{policy.description}}</td>
+                                <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+                                    {{:: 'remove' | translate}}
+                                </td>
+                            </tr>
+                            <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0">
+                                <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td>
+                            </tr>
+                        </tbody>
+                    </table>
                 </div>
                 <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
                 <label class="col-md-2 control-label" for="policy.decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label>
-
                 <div class="col-sm-2">
                     <select class="form-control" id="policy.decisionStrategy"
                             data-ng-model="policy.decisionStrategy"
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html
index de2da05..9c5630a 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html
@@ -5,6 +5,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-client-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'client' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-drools-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-drools-detail.html
index 612a8a4..583548f 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-drools-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-drools-detail.html
@@ -5,6 +5,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-drools-policy' | translate}}</li>
         <li data-ng-hide="create">Rules</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html
index 61af0f1..71cec33 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html
@@ -22,6 +22,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-group-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'groups' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html
index 679c15a..80f70e1 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html
@@ -8,6 +8,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-js-policy' | translate}}</li>
         <li data-ng-hide="create">JavaScript</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html
index 47e563a..9448682 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html
@@ -23,6 +23,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-role-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'roles' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
@@ -157,9 +159,10 @@
         <div class="form-group" data-ng-show="access.manageAuthorization">
             <div class="col-md-10 col-md-offset-2">
                 <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
-                <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
+                <button kc-reset data-ng-disabled="!changed && !historyBackOnSaveOrCancel">{{:: 'cancel' | translate}}</button>
             </div>
         </div>
+        {{policyState.page.previous}}
     </form>
 </div>
 
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html
index 81793d5..4af9014 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html
@@ -8,6 +8,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-time-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'time' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
                diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html
index c619910..80d81ac 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html
@@ -5,6 +5,8 @@
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li>
+        <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li>
+        <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li>
         <li data-ng-show="create">{{:: 'authz-add-user-policy' | translate}}</li>
         <li data-ng-hide="create">{{:: 'user' | translate}}</li>
         <li data-ng-hide="create">{{originalPolicy.name}}</li>
@@ -82,7 +84,7 @@
         <div class="form-group" data-ng-show="access.manageAuthorization">
             <div class="col-md-10 col-md-offset-2">
                 <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
-                <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
+                <button kc-reset data-ng-disabled="!changed && !historyBackOnSaveOrCancel">{{:: 'cancel' | translate}}</button>
             </div>
         </div>
     </form>