[KEYCLOAK-8273] - Failed to evaluate permissions when in permissive mode and using UMA tickets
This commit is contained in:
parent
609c521c17
commit
044d153c37
3 changed files with 67 additions and 36 deletions
|
@ -160,12 +160,22 @@ public class DecisionPermissionCollector extends AbstractDecisionCollector {
|
||||||
metadata = request.getMetadata();
|
metadata = request.getMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Permission permission;
|
||||||
|
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
String resourceName = metadata == null || metadata.getIncludeResourceName() ? resource.getName() : null;
|
String resourceName = metadata == null || metadata.getIncludeResourceName() ? resource.getName() : null;
|
||||||
return new Permission(resource.getId(), resourceName, scopes, claims);
|
permission = new Permission(resource.getId(), resourceName, scopes, claims);
|
||||||
|
} else {
|
||||||
|
permission = new Permission(null, null, scopes, claims);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Permission(null, null, scopes, claims);
|
onGrant(permission);
|
||||||
|
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onGrant(Permission permission) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isResourcePermission(Policy policy) {
|
private static boolean isResourcePermission(Policy policy) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.keycloak.authorization.store.StoreFactory;
|
||||||
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
||||||
import org.keycloak.representations.idm.authorization.Permission;
|
import org.keycloak.representations.idm.authorization.Permission;
|
||||||
import org.keycloak.representations.idm.authorization.PermissionTicketToken;
|
import org.keycloak.representations.idm.authorization.PermissionTicketToken;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
@ -60,45 +61,27 @@ public class PermissionTicketAwareDecisionResultCollector extends DecisionPermis
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDecision(DefaultEvaluation evaluation) {
|
protected void onGrant(Permission grantedPermission) {
|
||||||
super.onDecision(evaluation);
|
// Removes permissions (represented by {@code ticket}) granted by any user-managed policy so we don't create unnecessary permission tickets.
|
||||||
removePermissionsIfGranted(evaluation);
|
List<Permission> permissions = ticket.getPermissions();
|
||||||
}
|
Iterator<Permission> itPermissions = permissions.iterator();
|
||||||
|
|
||||||
/**
|
while (itPermissions.hasNext()) {
|
||||||
* Removes permissions (represented by {@code ticket}) granted by any user-managed policy so we don't create unnecessary permission tickets.
|
Permission permission = itPermissions.next();
|
||||||
*
|
|
||||||
* @param evaluation the evaluation
|
|
||||||
*/
|
|
||||||
private void removePermissionsIfGranted(DefaultEvaluation evaluation) {
|
|
||||||
if (Effect.PERMIT.equals(evaluation.getEffect())) {
|
|
||||||
Policy policy = evaluation.getParentPolicy();
|
|
||||||
|
|
||||||
if ("uma".equals(policy.getType())) {
|
if (permission.getResourceId() == null || permission.getResourceId().equals(grantedPermission.getResourceId())) {
|
||||||
ResourcePermission grantedPermission = evaluation.getPermission();
|
Set<String> scopes = permission.getScopes();
|
||||||
List<Permission> permissions = ticket.getPermissions();
|
Iterator<String> itScopes = scopes.iterator();
|
||||||
|
|
||||||
Iterator<Permission> itPermissions = permissions.iterator();
|
while (itScopes.hasNext()) {
|
||||||
|
if (grantedPermission.getScopes().contains(itScopes.next())) {
|
||||||
while (itPermissions.hasNext()) {
|
itScopes.remove();
|
||||||
Permission permission = itPermissions.next();
|
|
||||||
|
|
||||||
if (permission.getResourceId().equals(grantedPermission.getResource().getId())) {
|
|
||||||
Set<String> scopes = permission.getScopes();
|
|
||||||
Iterator<String> itScopes = scopes.iterator();
|
|
||||||
|
|
||||||
while (itScopes.hasNext()) {
|
|
||||||
Scope scope = authorization.getStoreFactory().getScopeStore().findByName(itScopes.next(), resourceServer.getId());
|
|
||||||
if (policy.getScopes().contains(scope)) {
|
|
||||||
itScopes.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scopes.isEmpty()) {
|
|
||||||
itPermissions.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scopes.isEmpty()) {
|
||||||
|
itPermissions.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,10 @@ import org.keycloak.representations.idm.authorization.AuthorizationResponse;
|
||||||
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.Permission;
|
import org.keycloak.representations.idm.authorization.Permission;
|
||||||
import org.keycloak.representations.idm.authorization.PermissionTicketRepresentation;
|
import org.keycloak.representations.idm.authorization.PermissionTicketRepresentation;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
@ -440,4 +442,40 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
|
||||||
|
|
||||||
assertEquals(1, permissionTickets.size());
|
assertEquals(1, permissionTickets.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPermissiveModePermissions() throws Exception {
|
||||||
|
resource = addResource("Resource A");
|
||||||
|
|
||||||
|
try {
|
||||||
|
authorize("kolo", "password", resource.getId(), null);
|
||||||
|
fail("Access should be denied, server in enforcing mode");
|
||||||
|
} catch (AuthorizationDeniedException ade) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthorizationResource authorizationResource = getClient(getRealm()).authorization();
|
||||||
|
ResourceServerRepresentation settings = authorizationResource.getSettings();
|
||||||
|
|
||||||
|
settings.setPolicyEnforcementMode(PolicyEnforcementMode.PERMISSIVE);
|
||||||
|
|
||||||
|
authorizationResource.update(settings);
|
||||||
|
|
||||||
|
AuthorizationResponse response = authorize("marta", "password", "Resource A", null);
|
||||||
|
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 A");
|
||||||
|
assertTrue(permissions.isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue