[KEYCLOAK-7781] - More validations to authorization requests
This commit is contained in:
parent
3fc6eed1ce
commit
90bfa2bff5
3 changed files with 156 additions and 9 deletions
|
@ -151,7 +151,7 @@ public class AuthorizationRequest {
|
|||
ResourcePermission permission = null;
|
||||
|
||||
for (ResourcePermission resourcePermission : permissions.getResources()) {
|
||||
if (resourcePermission.getResourceId().equals(resourceId)) {
|
||||
if (resourcePermission.getResourceId() != null && resourcePermission.getResourceId().equals(resourceId)) {
|
||||
permission = resourcePermission;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -354,17 +355,21 @@ public class AuthorizationTokenService {
|
|||
}
|
||||
}
|
||||
|
||||
if (existingResources.isEmpty() && (requestedScopes == null || requestedScopes.isEmpty())) {
|
||||
throw new CorsErrorResponseException(cors, "invalid_resource", "Resource with id [" + requestedResource.getResourceId() + "] does not exist.", Status.FORBIDDEN);
|
||||
}
|
||||
|
||||
String clientAdditionalScopes = request.getScope();
|
||||
|
||||
if (clientAdditionalScopes != null) {
|
||||
requestedScopes.addAll(Arrays.asList(clientAdditionalScopes.split(" ")));
|
||||
}
|
||||
|
||||
List<Scope> requestedScopesModel = requestedScopes.stream().map(s -> scopeStore.findByName(s, resourceServer.getId())).collect(Collectors.toList());
|
||||
List<Scope> requestedScopesModel = requestedScopes.stream().map(s -> scopeStore.findByName(s, resourceServer.getId())).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
if (requestedResource.getResourceId() != null && !"".equals(requestedResource.getResourceId().trim()) && existingResources.isEmpty()) {
|
||||
throw new CorsErrorResponseException(cors, "invalid_resource", "Resource with id [" + requestedResource.getResourceId() + "] does not exist.", Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if ((requestedResource.getScopes() != null && !requestedResource.getScopes().isEmpty()) && requestedScopesModel.isEmpty()) {
|
||||
throw new CorsErrorResponseException(cors, "invalid_scope", "One of the given scopes " + requestedResource.getScopes() + " are invalid", Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if (!existingResources.isEmpty()) {
|
||||
for (Resource resource : existingResources) {
|
||||
|
|
|
@ -21,12 +21,15 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -439,7 +442,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
|
||||
authorization.resources().resource(resource.getId()).update(resource);
|
||||
|
||||
// the addition of a new scope invalidates the permission previously grante to the resource
|
||||
// the addition of a new scope invalidates the permission previously granted to the resource
|
||||
assertFalse(hasPermission("kolo", "password", resource.getId()));
|
||||
|
||||
accessToken = new OAuthClient().realm("authz-test").clientId(RESOURCE_SERVER_TEST).doGrantAccessTokenRequest("secret", "kolo", "password").getAccessToken();
|
||||
|
@ -471,6 +474,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
authorization.resources().resource(resource.getId()).update(resource);
|
||||
|
||||
assertTrue(hasPermission("kolo", "password", resource.getId()));
|
||||
assertTrue(hasPermission("kolo", "password", resource.getId(), "Scope A"));
|
||||
assertFalse(hasPermission("kolo", "password", resource.getId(), "Scope B"));
|
||||
|
||||
resource.setScopes(new HashSet<>());
|
||||
|
@ -479,6 +483,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
|
||||
assertTrue(hasPermission("kolo", "password", resource.getId()));
|
||||
assertFalse(hasPermission("kolo", "password", resource.getId(), "Scope A"));
|
||||
assertFalse(hasPermission("kolo", "password", resource.getId(), "Scope B"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -514,9 +519,146 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
|
||||
request.addPermission("Sensortest", "sensors:view");
|
||||
|
||||
AuthorizationResponse response = authzClient.authorization(accessToken).authorize(request);
|
||||
try {
|
||||
authzClient.authorization(accessToken).authorize(request);
|
||||
fail("resource is invalid");
|
||||
} catch (RuntimeException expected) {
|
||||
assertEquals(400, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
|
||||
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("invalid_resource"));
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(response);
|
||||
@Test
|
||||
public void testObtainAllEntitlementsInvalidScope() throws Exception {
|
||||
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
|
||||
AuthorizationResource authorization = client.authorization();
|
||||
|
||||
JSPolicyRepresentation policy = new JSPolicyRepresentation();
|
||||
|
||||
policy.setName(KeycloakModelUtils.generateId());
|
||||
policy.setCode("$evaluation.grant();");
|
||||
|
||||
authorization.policies().js().create(policy).close();
|
||||
|
||||
ResourceRepresentation resource = new ResourceRepresentation();
|
||||
|
||||
resource.setName(KeycloakModelUtils.generateId());
|
||||
resource.addScope("sensors:view", "sensors:update", "sensors:delete");
|
||||
|
||||
resource = authorization.resources().create(resource).readEntity(ResourceRepresentation.class);
|
||||
|
||||
ScopePermissionRepresentation permission = new ScopePermissionRepresentation();
|
||||
|
||||
permission.setName(KeycloakModelUtils.generateId());
|
||||
permission.addScope("sensors:view");
|
||||
permission.addPolicy(policy.getName());
|
||||
|
||||
authorization.permissions().scope().create(permission);
|
||||
|
||||
String accessToken = new OAuthClient().realm("authz-test").clientId(RESOURCE_SERVER_TEST).doGrantAccessTokenRequest("secret", "kolo", "password").getAccessToken();
|
||||
AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
|
||||
AuthorizationRequest request = new AuthorizationRequest();
|
||||
|
||||
request.addPermission(resource.getId(), "sensors:view_invalid");
|
||||
|
||||
try {
|
||||
authzClient.authorization(accessToken).authorize(request);
|
||||
fail("scope is invalid");
|
||||
} catch (RuntimeException expected) {
|
||||
assertEquals(400, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
|
||||
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("invalid_scope"));
|
||||
}
|
||||
|
||||
request = new AuthorizationRequest();
|
||||
|
||||
request.addPermission(null, "sensors:view_invalid");
|
||||
|
||||
try {
|
||||
authzClient.authorization(accessToken).authorize(request);
|
||||
fail("scope is invalid");
|
||||
} catch (RuntimeException expected) {
|
||||
assertEquals(400, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
|
||||
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("invalid_scope"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObtainAllEntitlementsForScope() throws Exception {
|
||||
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
|
||||
AuthorizationResource authorization = client.authorization();
|
||||
|
||||
JSPolicyRepresentation policy = new JSPolicyRepresentation();
|
||||
|
||||
policy.setName(KeycloakModelUtils.generateId());
|
||||
policy.setCode("$evaluation.grant();");
|
||||
|
||||
authorization.policies().js().create(policy).close();
|
||||
|
||||
Set<String> resourceIds = new HashSet<>();
|
||||
ResourceRepresentation resource = new ResourceRepresentation();
|
||||
|
||||
resource.setName(KeycloakModelUtils.generateId());
|
||||
resource.addScope("sensors:view", "sensors:update", "sensors:delete");
|
||||
|
||||
resourceIds.add(authorization.resources().create(resource).readEntity(ResourceRepresentation.class).getId());
|
||||
|
||||
resource = new ResourceRepresentation();
|
||||
|
||||
resource.setName(KeycloakModelUtils.generateId());
|
||||
resource.addScope("sensors:view", "sensors:update", "sensors:delete");
|
||||
|
||||
resourceIds.add(authorization.resources().create(resource).readEntity(ResourceRepresentation.class).getId());
|
||||
|
||||
ScopePermissionRepresentation permission = new ScopePermissionRepresentation();
|
||||
|
||||
permission.setName(KeycloakModelUtils.generateId());
|
||||
permission.addScope("sensors:view", "sensors:update");
|
||||
permission.addPolicy(policy.getName());
|
||||
|
||||
authorization.permissions().scope().create(permission);
|
||||
|
||||
String accessToken = new OAuthClient().realm("authz-test").clientId(RESOURCE_SERVER_TEST).doGrantAccessTokenRequest("secret", "kolo", "password").getAccessToken();
|
||||
AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
|
||||
AuthorizationRequest request = new AuthorizationRequest();
|
||||
|
||||
request.addPermission(null, "sensors:view");
|
||||
|
||||
AuthorizationResponse response = authzClient.authorization(accessToken).authorize(request);
|
||||
assertNotNull(response.getToken());
|
||||
List<Permission> permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
|
||||
assertEquals(2, permissions.size());
|
||||
|
||||
for (Permission grantedPermission : permissions) {
|
||||
assertTrue(resourceIds.containsAll(Arrays.asList(grantedPermission.getResourceId())));
|
||||
assertEquals(1, grantedPermission.getScopes().size());
|
||||
assertTrue(grantedPermission.getScopes().containsAll(Arrays.asList("sensors:view")));
|
||||
}
|
||||
|
||||
request.addPermission(null, "sensors:view", "sensors:update");
|
||||
|
||||
response = authzClient.authorization(accessToken).authorize(request);
|
||||
assertNotNull(response.getToken());
|
||||
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
|
||||
assertEquals(2, permissions.size());
|
||||
|
||||
for (Permission grantedPermission : permissions) {
|
||||
assertTrue(resourceIds.containsAll(Arrays.asList(grantedPermission.getResourceId())));
|
||||
assertEquals(2, grantedPermission.getScopes().size());
|
||||
assertTrue(grantedPermission.getScopes().containsAll(Arrays.asList("sensors:view", "sensors:update")));
|
||||
}
|
||||
|
||||
request.addPermission(null, "sensors:view", "sensors:update", "sensors:delete");
|
||||
|
||||
response = authzClient.authorization(accessToken).authorize(request);
|
||||
assertNotNull(response.getToken());
|
||||
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
|
||||
assertEquals(2, permissions.size());
|
||||
|
||||
for (Permission grantedPermission : permissions) {
|
||||
assertTrue(resourceIds.containsAll(Arrays.asList(grantedPermission.getResourceId())));
|
||||
assertEquals(2, grantedPermission.getScopes().size());
|
||||
assertTrue(grantedPermission.getScopes().containsAll(Arrays.asList("sensors:view", "sensors:update")));
|
||||
}
|
||||
}
|
||||
|
||||
private void testRptRequestWithResourceName(String configFile) {
|
||||
|
|
Loading…
Reference in a new issue