[KEYCLOAK-8445] - Owner not granted with permissions when using only scope-based permissions

This commit is contained in:
Pedro Igor 2018-09-28 14:17:58 -03:00
parent 7f1c03a122
commit 8e57cee30f
2 changed files with 99 additions and 8 deletions

View file

@ -16,9 +16,30 @@
*/ */
package org.keycloak.authorization.policy.provider.permission; package org.keycloak.authorization.policy.provider.permission;
import org.keycloak.authorization.identity.Identity;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.permission.ResourcePermission;
import org.keycloak.authorization.policy.evaluation.Evaluation;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
public class UMAPolicyProvider extends AbstractPermissionProvider { public class UMAPolicyProvider extends AbstractPermissionProvider {
@Override
public void evaluate(Evaluation evaluation) {
ResourcePermission permission = evaluation.getPermission();
Resource resource = permission.getResource();
if (resource != null) {
Identity identity = evaluation.getContext().getIdentity();
// no need to evaluate UMA permissions to resource owner resources
if (resource.getOwner().equals(identity.getId())) {
return;
}
}
super.evaluate(evaluation);
}
} }

View file

@ -43,6 +43,7 @@ import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation; import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -101,6 +102,82 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
} }
} }
@Test
public void testOnlyOwnerCanAccessPermissionsToScope() throws Exception {
resource = addResource("Resource A", "marta", true, "ScopeA", "ScopeB");
ScopePermissionRepresentation permission = new ScopePermissionRepresentation();
permission.setName(resource.getName() + " Scope A Permission");
permission.addScope("ScopeA");
permission.addPolicy("Only Owner Policy");
getClient(getRealm()).authorization().permissions().scope().create(permission).close();
permission = new ScopePermissionRepresentation();
permission.setName(resource.getName() + " Scope B Permission");
permission.addScope("ScopeB");
permission.addPolicy("Only Owner Policy");
getClient(getRealm()).authorization().permissions().scope().create(permission).close();
AuthorizationResponse response = authorize("marta", "password", resource.getName(), new String[] {"ScopeA", "ScopeB"});
String rpt = response.getToken();
assertNotNull(rpt);
assertFalse(response.isUpgraded());
AccessToken accessToken = toAccessToken(rpt);
AccessToken.Authorization authorization = accessToken.getAuthorization();
assertNotNull(authorization);
Collection<Permission> permissions = authorization.getPermissions();
assertNotNull(permissions);
assertPermissions(permissions, resource.getName(), "ScopeA", "ScopeB");
assertTrue(permissions.isEmpty());
try {
response = authorize("kolo", "password", resource.getId(), new String[] {"ScopeA", "ScopeB"});
fail("User should not have access to resource from another user");
} catch (AuthorizationDeniedException ade) {
}
List<PermissionTicketRepresentation> tickets = getAuthzClient().protection().permission().find(resource.getId(), null, null, null, null, null, null, null);
for (PermissionTicketRepresentation ticket : tickets) {
ticket.setGranted(true);
getAuthzClient().protection().permission().update(ticket);
}
try {
response = authorize("kolo", "password", resource.getId(), new String[] {"ScopeA", "ScopeB"});
} catch (AuthorizationDeniedException ade) {
fail("User should have access to resource from another user");
}
rpt = response.getToken();
accessToken = toAccessToken(rpt);
authorization = accessToken.getAuthorization();
permissions = authorization.getPermissions();
assertPermissions(permissions, resource.getName(), "ScopeA", "ScopeB");
assertTrue(permissions.isEmpty());
try {
response = authorize("marta", "password", resource.getId(), new String[] {"ScopeB"});
} catch (AuthorizationDeniedException ade) {
fail("User should have access to his own resources");
}
rpt = response.getToken();
accessToken = toAccessToken(rpt);
authorization = accessToken.getAuthorization();
permissions = authorization.getPermissions();
assertPermissions(permissions, resource.getName(), "ScopeB");
assertTrue(permissions.isEmpty());
}
/** /**
* Makes sure permissions granted to a typed resource instance does not grant access to resource instances with the same type. * Makes sure permissions granted to a typed resource instance does not grant access to resource instances with the same type.
* *
@ -176,13 +253,6 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
assertNotNull(permissions); assertNotNull(permissions);
assertPermissions(permissions, resource.getName(), "ScopeA", "ScopeB"); assertPermissions(permissions, resource.getName(), "ScopeA", "ScopeB");
assertTrue(permissions.isEmpty()); assertTrue(permissions.isEmpty());
try {
response = authorize("kolo", "password", resourceB.getId(), new String[] {"ScopeA", "ScopeB"});
fail("User should not have access to resource from another user");
} catch (AuthorizationDeniedException ade) {
}
} }
@Test @Test
@ -364,7 +434,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
} }
@Test @Test
public void testUserGrantsAccessToScope() throws Exception { public void testScopePermissionsToScopeOnly() throws Exception {
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation(); ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
resource = addResource("Resource A", "marta", true, "ScopeA", "ScopeB"); resource = addResource("Resource A", "marta", true, "ScopeA", "ScopeB");