keycloak-aplcache

expand required credentials

8/4/2013 12:48:09 PM

Changes

examples/as7-eap-demo/server/src/main/webapp/saas/realm-login.html 75(+0 -75)

examples/as7-eap-demo/server/src/main/webapp/saas/realm-register.html 81(+0 -81)

examples/as7-eap-demo/server/src/main/webapp/saas/saas-login.html 77(+0 -77)

examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.html 80(+0 -80)

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 0fedfad..896c1c9 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -21,6 +21,8 @@ public class RealmRepresentation {
     protected String publicKey;
     protected List<RoleRepresentation> roles;
     protected List<RequiredCredentialRepresentation> requiredCredentials;
+    protected List<RequiredCredentialRepresentation> requiredResourceCredentials;
+    protected List<RequiredCredentialRepresentation> requiredOAuthClientCredentials;
     protected List<UserRepresentation> users;
     protected List<RoleMappingRepresentation> roleMappings;
     protected List<ScopeMappingRepresentation> scopeMappings;
@@ -147,6 +149,22 @@ public class RealmRepresentation {
         this.requiredCredentials = requiredCredentials;
     }
 
+    public List<RequiredCredentialRepresentation> getRequiredResourceCredentials() {
+        return requiredResourceCredentials;
+    }
+
+    public void setRequiredResourceCredentials(List<RequiredCredentialRepresentation> requiredResourceCredentials) {
+        this.requiredResourceCredentials = requiredResourceCredentials;
+    }
+
+    public List<RequiredCredentialRepresentation> getRequiredOAuthClientCredentials() {
+        return requiredOAuthClientCredentials;
+    }
+
+    public void setRequiredOAuthClientCredentials(List<RequiredCredentialRepresentation> requiredOAuthClientCredentials) {
+        this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
+    }
+
     public int getAccessCodeLifespan() {
         return accessCodeLifespan;
     }
diff --git a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
index 84d499f..9a09302 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
@@ -15,6 +15,7 @@ public class ResourceRepresentation {
     protected String adminUrl;
     protected boolean surrogateAuthRequired;
     protected boolean useRealmMappings;
+    protected boolean enabled;
     protected List<CredentialRepresentation> credentials;
     protected List<RoleRepresentation> roles;
     protected List<RoleMappingRepresentation> roleMappings;
@@ -36,6 +37,14 @@ public class ResourceRepresentation {
         this.name = name;
     }
 
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
     public boolean isSurrogateAuthRequired() {
         return surrogateAuthRequired;
     }
@@ -52,6 +61,13 @@ public class ResourceRepresentation {
         this.roles = roles;
     }
 
+    public ResourceRepresentation role(RoleRepresentation role) {
+        if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
+        this.roles.add(role);
+        return this;
+    }
+
+
     public ResourceRepresentation role(String role, String description) {
         if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
         this.roles.add(new RoleRepresentation(role, description));
diff --git a/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json b/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
index b81aad6..a1500d1 100755
--- a/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
+++ b/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
@@ -14,6 +14,20 @@
             "secret" : true
         }
    ],
+    "requiredResourceCredentials" : [
+        {
+            "type" : "Password",
+            "input" : true,
+            "secret" : true
+        }
+    ],
+    "requiredOAuthClientCredentials" : [
+        {
+            "type" : "Password",
+            "input" : true,
+            "secret" : true
+        }
+    ],
    "users" : [
       {
             "username" : "bburke@redhat.com",
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
index 39686d6..6521861 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
@@ -49,7 +49,6 @@
                     </button>
                     <button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
                     </button>
-                    <a href="#/realms/{{realm.id}}/users" data-ng-hide="changed">View users &#187;</a>
                     <button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
                         Delete
                     </button>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/saas-login.jsp b/examples/as7-eap-demo/server/src/main/webapp/saas/saas-login.jsp
index ee004a8..a646dee 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/saas-login.jsp
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/saas-login.jsp
@@ -67,7 +67,7 @@
                     </section>
                     <section class="info-area">
                         <h3>Info area</h3>
-                        <p>Does not have an account? <a href="saas-register.html">Register</a>.</p>
+                        <p>Does not have an account? <a href="<%=application.getContextPath()%>/saas/saas-register.html">Register</a>.</p>
                         <ul>
                             <li><strong>Domain:</strong> 10.0.0.1</li>
                             <li><strong>Zone:</strong> Live</li>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.jsp b/examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.jsp
index ed61648..b95d171 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.jsp
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/saas-register.jsp
@@ -73,7 +73,7 @@
                     </section>
                     <section class="info-area">
                         <h3>Info area</h3>
-                        <p>Already have an account? <a href="saas-login.html">Log in</a>.</p>
+                        <p>Already have an account? <a href="<%=application.getContextPath()%>/saas/saas-login.jsp">Log in</a>.</p>
                         <ul>
                             <li><strong>Domain:</strong> 10.0.0.1</li>
                             <li><strong>Zone:</strong> Live</li>
diff --git a/sdk-html/src/main/resources/META-INF/resources/sdk/theme/saas/login.xhtml b/sdk-html/src/main/resources/META-INF/resources/sdk/theme/saas/login.xhtml
old mode 100644
new mode 100755
index d9618f0..c1cc362
--- a/sdk-html/src/main/resources/META-INF/resources/sdk/theme/saas/login.xhtml
+++ b/sdk-html/src/main/resources/META-INF/resources/sdk/theme/saas/login.xhtml
@@ -51,7 +51,7 @@
 				<section class="info-area">
 					<h3>Info area</h3>
 					<p>
-						Does not have an account? <a href="saas-register.html">Register</a>.
+						No account? <a href="saas-register.html">Register</a>.
 					</p>
 					<ul>
 						<li><strong>Domain:</strong> 10.0.0.1</li>
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index dc8b79f..02c87eb 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -23,6 +23,7 @@ import javax.ws.rs.core.NewCookie;
 import javax.ws.rs.core.UriInfo;
 import java.net.URI;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -203,7 +204,15 @@ public class AuthenticationManager {
     public boolean authenticateForm(RealmModel realm, UserModel user, MultivaluedMap<String, String> formData) {
         Set<String> types = new HashSet<String>();
 
-        for (RequiredCredentialModel credential : realm.getRequiredCredentials()) {
+        List<RequiredCredentialModel> requiredCredentials = null;
+        if (realm.hasRole(user, RealmManager.RESOURCE_ROLE)) {
+            requiredCredentials = realm.getResourceRequiredCredentials();
+        } else if (realm.hasRole(user, RealmManager.IDENTITY_REQUESTER_ROLE)) {
+            requiredCredentials = realm.getOAuthClientRequiredCredentials();
+        } else {
+            requiredCredentials = realm.getRequiredCredentials();
+        }
+        for (RequiredCredentialModel credential : requiredCredentials) {
             types.add(credential.getType());
         }
 
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index cca1795..56d65ca 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -110,6 +110,20 @@ public class RealmManager {
             }
         }
 
+        if (rep.getRequiredResourceCredentials() != null) {
+            for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
+                addResourceRequiredCredential(newRealm, requiredCred);
+            }
+        }
+
+        if (rep.getRequiredOAuthClientCredentials() != null) {
+            for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
+                addOAuthClientRequiredCredential(newRealm, requiredCred);
+            }
+        }
+
+
+
         if (rep.getUsers() != null) {
             for (UserRepresentation userRep : rep.getUsers()) {
                 UserModel user = createUser(newRealm, userRep);
@@ -180,68 +194,42 @@ public class RealmManager {
     }
 
     public void addRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
+        RequiredCredentialModel credential = initializeCred(requiredCred);
+        newRealm.addRequiredCredential(credential);
+    }
+    public void addResourceRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
+        RequiredCredentialModel credential = initializeCred(requiredCred);
+        newRealm.addResourceRequiredCredential(credential);
+    }
+    public void addOAuthClientRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
+        RequiredCredentialModel credential = initializeCred(requiredCred);
+        newRealm.addOAuthClientRequiredCredential(credential);
+    }
+
+
+
+    private RequiredCredentialModel initializeCred(RequiredCredentialRepresentation requiredCred) {
         RequiredCredentialModel credential = new RequiredCredentialModel();
         credential.setType(requiredCred.getType());
         credential.setInput(requiredCred.isInput());
         credential.setSecret(requiredCred.isSecret());
-        newRealm.addRequiredCredential(credential);
+        return credential;
     }
 
     protected void createResources(RealmRepresentation rep, RealmModel realm) {
         RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
+        ResourceManager manager = new ResourceManager(this);
         for (ResourceRepresentation resourceRep : rep.getResources()) {
-            createResource(realm, loginRole, resourceRep);
+            manager.createResource(realm, loginRole, resourceRep);
         }
     }
 
-    public void createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
-        ResourceModel resource = realm.addResource(resourceRep.getName());
-        resource.setManagementUrl(resourceRep.getAdminUrl());
-        resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
-        resource.updateResource();
-
-        UserModel resourceUser = resource.getResourceUser();
-        if (resourceRep.getCredentials() != null) {
-            for (CredentialRepresentation cred : resourceRep.getCredentials()) {
-                UserCredentialModel credential = new UserCredentialModel();
-                credential.setType(cred.getType());
-                credential.setValue(cred.getValue());
-                realm.updateCredential(resourceUser, credential);
-            }
-        }
-        realm.grantRole(resourceUser, loginRole);
-
-
-        if (resourceRep.getRoles() != null) {
-            for (RoleRepresentation roleRep : resourceRep.getRoles()) {
-                RoleModel role = resource.addRole(roleRep.getName());
-                if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
-            }
-        }
-        if (resourceRep.getRoleMappings() != null) {
-            for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
-                UserModel user = realm.getUser(mapping.getUsername());
-                for (String roleString : mapping.getRoles()) {
-                    RoleModel role = resource.getRole(roleString.trim());
-                    if (role == null) {
-                        role = resource.addRole(roleString.trim());
-                    }
-                    realm.grantRole(user, role);
-                }
-            }
-        }
-        if (resourceRep.getScopeMappings() != null) {
-            for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
-                UserModel user = realm.getUser(mapping.getUsername());
-                for (String roleString : mapping.getRoles()) {
-                    RoleModel role = resource.getRole(roleString.trim());
-                    if (role == null) {
-                        role = resource.addRole(roleString.trim());
-                    }
-                    resource.addScope(user, role.getName());
-                }
-            }
-        }
-        if (resourceRep.isUseRealmMappings()) realm.addScope(resource.getResourceUser(), "*");
+    public RoleRepresentation toRepresentation(RoleModel role) {
+        RoleRepresentation rep = new RoleRepresentation();
+        rep.setId(role.getId());
+        rep.setName(role.getName());
+        rep.setDescription(role.getDescription());
+        return rep;
     }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceManager.java
new file mode 100755
index 0000000..4db5c17
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceManager.java
@@ -0,0 +1,98 @@
+package org.keycloak.services.managers;
+
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.ResourceRepresentation;
+import org.keycloak.representations.idm.RoleMappingRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.keycloak.services.models.RealmModel;
+import org.keycloak.services.models.ResourceModel;
+import org.keycloak.services.models.RoleModel;
+import org.keycloak.services.models.UserCredentialModel;
+import org.keycloak.services.models.UserModel;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ResourceManager {
+
+    protected RealmManager realmManager;
+
+    public ResourceManager(RealmManager realmManager) {
+        this.realmManager = realmManager;
+    }
+
+    public ResourceModel createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
+        ResourceModel resource = realm.addResource(resourceRep.getName());
+        resource.setManagementUrl(resourceRep.getAdminUrl());
+        resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
+        resource.updateResource();
+
+        UserModel resourceUser = resource.getResourceUser();
+        if (resourceRep.getCredentials() != null) {
+            for (CredentialRepresentation cred : resourceRep.getCredentials()) {
+                UserCredentialModel credential = new UserCredentialModel();
+                credential.setType(cred.getType());
+                credential.setValue(cred.getValue());
+                realm.updateCredential(resourceUser, credential);
+            }
+        }
+        realm.grantRole(resourceUser, loginRole);
+
+
+        if (resourceRep.getRoles() != null) {
+            for (RoleRepresentation roleRep : resourceRep.getRoles()) {
+                RoleModel role = resource.addRole(roleRep.getName());
+                if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
+            }
+        }
+        if (resourceRep.getRoleMappings() != null) {
+            for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
+                UserModel user = realm.getUser(mapping.getUsername());
+                for (String roleString : mapping.getRoles()) {
+                    RoleModel role = resource.getRole(roleString.trim());
+                    if (role == null) {
+                        role = resource.addRole(roleString.trim());
+                    }
+                    realm.grantRole(user, role);
+                }
+            }
+        }
+        if (resourceRep.getScopeMappings() != null) {
+            for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
+                UserModel user = realm.getUser(mapping.getUsername());
+                for (String roleString : mapping.getRoles()) {
+                    RoleModel role = resource.getRole(roleString.trim());
+                    if (role == null) {
+                        role = resource.addRole(roleString.trim());
+                    }
+                    resource.addScope(user, role.getName());
+                }
+            }
+        }
+        if (resourceRep.isUseRealmMappings()) realm.addScope(resource.getResourceUser(), "*");
+        return resource;
+    }
+
+    public ResourceModel createResource(RealmModel realm, ResourceRepresentation resourceRep) {
+        RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
+        return createResource(realm, loginRole, resourceRep);
+    }
+
+    public ResourceRepresentation getResource(ResourceModel resourceModel, boolean bulk) {
+        ResourceRepresentation rep = new ResourceRepresentation();
+        rep.setName(resourceModel.getName());
+        rep.setEnabled(resourceModel.isEnabled());
+        rep.setAdminUrl(resourceModel.getManagementUrl());
+        rep.setSurrogateAuthRequired(resourceModel.isSurrogateAuthRequired());
+        List<RoleModel> roles = resourceModel.getRoles();
+        for (RoleModel role : roles) {
+            rep.role(realmManager.toRepresentation(role));
+        }
+        return rep;
+
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
index bb7c2b2..4884a1f 100755
--- a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
+++ b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
@@ -13,9 +13,11 @@ import org.keycloak.services.models.UserCredentialModel;
 import org.keycloak.services.models.UserModel;
 import org.keycloak.services.models.picketlink.mappings.RealmData;
 import org.keycloak.services.models.picketlink.mappings.ResourceData;
+import org.keycloak.services.models.picketlink.relationships.OAuthClientRequiredCredentialRelationship;
 import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
 import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
 import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
+import org.keycloak.services.models.picketlink.relationships.ResourceRequiredCredentialRelationship;
 import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
 import org.picketlink.idm.IdentityManager;
 import org.picketlink.idm.PartitionManager;
@@ -252,6 +254,48 @@ public class RealmAdapter implements RealmModel {
         RelationshipQuery<RequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(RequiredCredentialRelationship.class);
         query.setParameter(RequiredCredentialRelationship.REALM, realm.getName());
         List<RequiredCredentialRelationship> results = query.getResultList();
+        return getRequiredCredentialModels(results);
+    }
+
+
+    @Override
+    public void addResourceRequiredCredential(RequiredCredentialModel cred) {
+        ResourceRequiredCredentialRelationship relationship = new ResourceRequiredCredentialRelationship();
+        addRequiredCredential(cred, relationship);
+    }
+
+    @Override
+    public List<RequiredCredentialModel> getResourceRequiredCredentials() {
+        RelationshipQuery<ResourceRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRequiredCredentialRelationship.class);
+        query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
+        List<ResourceRequiredCredentialRelationship> results = query.getResultList();
+        return getRequiredCredentialModels(results);
+    }
+
+    @Override
+    public void addOAuthClientRequiredCredential(RequiredCredentialModel cred) {
+        OAuthClientRequiredCredentialRelationship relationship = new OAuthClientRequiredCredentialRelationship();
+        addRequiredCredential(cred, relationship);
+    }
+
+    @Override
+    public List<RequiredCredentialModel> getOAuthClientRequiredCredentials() {
+        RelationshipQuery<OAuthClientRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRequiredCredentialRelationship.class);
+        query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
+        List<OAuthClientRequiredCredentialRelationship> results = query.getResultList();
+        return getRequiredCredentialModels(results);
+    }
+
+
+
+    @Override
+    public void addRequiredCredential(RequiredCredentialModel cred) {
+        RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
+        addRequiredCredential(cred, relationship);
+    }
+
+
+    protected List<RequiredCredentialModel> getRequiredCredentialModels(List<? extends RequiredCredentialRelationship> results) {
         List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>();
         for (RequiredCredentialRelationship relationship : results) {
             RequiredCredentialModel model = new RequiredCredentialModel();
@@ -262,10 +306,7 @@ public class RealmAdapter implements RealmModel {
         }
         return rtn;
     }
-
-    @Override
-    public void addRequiredCredential(RequiredCredentialModel cred) {
-        RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
+    protected void addRequiredCredential(RequiredCredentialModel cred, RequiredCredentialRelationship relationship) {
         relationship.setCredentialType(cred.getType());
         relationship.setInput(cred.isInput());
         relationship.setSecret(cred.isSecret());
@@ -423,6 +464,13 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public boolean hasRole(UserModel user, String role) {
+        RoleModel roleModel = getRole(role);
+        return hasRole(user, roleModel);
+    }
+
+
+    @Override
     public void grantRole(UserModel user, RoleModel role) {
         SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
     }
diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/relationships/OAuthClientRequiredCredentialRelationship.java b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/OAuthClientRequiredCredentialRelationship.java
new file mode 100755
index 0000000..f14c808
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/OAuthClientRequiredCredentialRelationship.java
@@ -0,0 +1,8 @@
+package org.keycloak.services.models.picketlink.relationships;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientRequiredCredentialRelationship extends RequiredCredentialRelationship {
+}
diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/relationships/ResourceRequiredCredentialRelationship.java b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/ResourceRequiredCredentialRelationship.java
new file mode 100755
index 0000000..5df352e
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/models/picketlink/relationships/ResourceRequiredCredentialRelationship.java
@@ -0,0 +1,8 @@
+package org.keycloak.services.models.picketlink.relationships;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ResourceRequiredCredentialRelationship extends RequiredCredentialRelationship {
+}
diff --git a/services/src/main/java/org/keycloak/services/models/RealmModel.java b/services/src/main/java/org/keycloak/services/models/RealmModel.java
index abb7e1d..0f7811d 100755
--- a/services/src/main/java/org/keycloak/services/models/RealmModel.java
+++ b/services/src/main/java/org/keycloak/services/models/RealmModel.java
@@ -100,4 +100,14 @@ public interface RealmModel {
     void addRealmAdmin(UserModel agent);
 
     RoleModel getRoleById(String id);
+
+    void addResourceRequiredCredential(RequiredCredentialModel cred);
+
+    List<RequiredCredentialModel> getResourceRequiredCredentials();
+
+    void addOAuthClientRequiredCredential(RequiredCredentialModel cred);
+
+    List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
+
+    boolean hasRole(UserModel user, String role);
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmResourcesResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmResourcesResource.java
new file mode 100755
index 0000000..acb6c55
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmResourcesResource.java
@@ -0,0 +1,32 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.resteasy.logging.Logger;
+import org.keycloak.representations.idm.ResourceRepresentation;
+import org.keycloak.services.models.RealmModel;
+import org.keycloak.services.models.UserModel;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RealmResourcesResource {
+    protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
+    protected UserModel admin;
+    protected RealmModel realm;
+
+    public RealmResourcesResource(UserModel admin, RealmModel realm) {
+        this.admin = admin;
+        this.realm = realm;
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    List<ResourceRepresentation> getResources() {
+        return null;
+    }
+}
diff --git a/services/src/test/resources/testrealm.json b/services/src/test/resources/testrealm.json
index a8d0cbf..c0bf2eb 100755
--- a/services/src/test/resources/testrealm.json
+++ b/services/src/test/resources/testrealm.json
@@ -10,6 +10,20 @@
             "secret" : true
         }
    ],
+    "requiredResourceCredentials" : [
+        {
+            "type" : "Password",
+            "input" : true,
+            "secret" : true
+        }
+    ],
+    "requiredOAuthClientCredentials" : [
+        {
+            "type" : "Password",
+            "input" : true,
+            "secret" : true
+        }
+    ],
    "users" : [
       {
             "username" : "wburke",