Search in sources :

Example 6 with Authorization

use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.

the class PermissionClaimTest method testClaimsFromDifferentResourcePermissions.

@Test
public void testClaimsFromDifferentResourcePermissions() throws Exception {
    ClientResource client = getClient(getRealm());
    AuthorizationResource authorization = client.authorization();
    ResourceRepresentation resourceA = new ResourceRepresentation(KeycloakModelUtils.generateId());
    resourceA.setType("typed-resource");
    authorization.resources().create(resourceA).close();
    ResourcePermissionRepresentation allScopesPermission = new ResourcePermissionRepresentation();
    allScopesPermission.setName(KeycloakModelUtils.generateId());
    allScopesPermission.addResource(resourceA.getName());
    allScopesPermission.addPolicy(claimAPolicy.getName(), claimBPolicy.getName());
    authorization.permissions().resource().create(allScopesPermission).close();
    ResourcePermissionRepresentation updatePermission = new ResourcePermissionRepresentation();
    updatePermission.setName(KeycloakModelUtils.generateId());
    updatePermission.addResource(resourceA.getName());
    updatePermission.addPolicy(claimCPolicy.getName());
    try (Response response = authorization.permissions().resource().create(updatePermission)) {
        updatePermission = response.readEntity(ResourcePermissionRepresentation.class);
    }
    AuthzClient authzClient = getAuthzClient();
    AuthorizationResponse response = authzClient.authorization("marta", "password").authorize();
    assertNotNull(response.getToken());
    AccessToken rpt = toAccessToken(response.getToken());
    Authorization authorizationClaim = rpt.getAuthorization();
    List<Permission> permissions = new ArrayList<>(authorizationClaim.getPermissions());
    assertEquals(1, permissions.size());
    for (Permission permission : permissions) {
        Map<String, Set<String>> claims = permission.getClaims();
        assertNotNull(claims);
        assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
        assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
        assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
    }
    updatePermission.addPolicy(denyPolicy.getName());
    authorization.permissions().resource().findById(updatePermission.getId()).update(updatePermission);
    try {
        authzClient.authorization("marta", "password").authorize();
        fail("can not access resource");
    } catch (RuntimeException expected) {
        assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
        assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
    }
    ResourceRepresentation resourceInstance = new ResourceRepresentation(KeycloakModelUtils.generateId(), "create", "update");
    resourceInstance.setType(resourceA.getType());
    resourceInstance.setOwner("marta");
    try (Response response1 = authorization.resources().create(resourceInstance)) {
        resourceInstance = response1.readEntity(ResourceRepresentation.class);
    }
    AuthorizationRequest request = new AuthorizationRequest();
    request.addPermission(null, "create", "update");
    try {
        authzClient.authorization("marta", "password").authorize(request);
        fail("can not access resource");
    } catch (RuntimeException expected) {
        assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
        assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
    }
    ResourcePermissionRepresentation resourceInstancePermission = new ResourcePermissionRepresentation();
    resourceInstancePermission.setName(KeycloakModelUtils.generateId());
    resourceInstancePermission.addResource(resourceInstance.getId());
    resourceInstancePermission.addPolicy(claimCPolicy.getName());
    try (Response response1 = authorization.permissions().resource().create(resourceInstancePermission)) {
        resourceInstancePermission = response1.readEntity(ResourcePermissionRepresentation.class);
    }
    response = authzClient.authorization("marta", "password").authorize(request);
    assertNotNull(response.getToken());
    rpt = toAccessToken(response.getToken());
    authorizationClaim = rpt.getAuthorization();
    permissions = new ArrayList<>(authorizationClaim.getPermissions());
    assertEquals(1, permissions.size());
    for (Permission permission : permissions) {
        Map<String, Set<String>> claims = permission.getClaims();
        assertNotNull(claims);
        assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
        assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
        assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
        assertThat(claims.get("deny-policy"), Matchers.containsInAnyOrder("deny-policy"));
    }
    response = authzClient.authorization("marta", "password").authorize();
    assertNotNull(response.getToken());
    rpt = toAccessToken(response.getToken());
    authorizationClaim = rpt.getAuthorization();
    permissions = new ArrayList<>(authorizationClaim.getPermissions());
    assertEquals(1, permissions.size());
    for (Permission permission : permissions) {
        Map<String, Set<String>> claims = permission.getClaims();
        assertNotNull(claims);
        assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
        assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
        assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
        assertThat(claims.get("deny-policy"), Matchers.containsInAnyOrder("deny-policy"));
        assertThat(permission.getScopes(), Matchers.containsInAnyOrder("create", "update"));
    }
    updatePermission.setPolicies(new HashSet<>());
    updatePermission.addPolicy(claimCPolicy.getName());
    authorization.permissions().resource().findById(updatePermission.getId()).update(updatePermission);
    response = authzClient.authorization("marta", "password").authorize();
    assertNotNull(response.getToken());
    rpt = toAccessToken(response.getToken());
    authorizationClaim = rpt.getAuthorization();
    permissions = new ArrayList<>(authorizationClaim.getPermissions());
    assertEquals(2, permissions.size());
    for (Permission permission : permissions) {
        Map<String, Set<String>> claims = permission.getClaims();
        assertNotNull(claims);
        assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
        assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
        assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) AuthorizationRequest(org.keycloak.representations.idm.authorization.AuthorizationRequest) ArrayList(java.util.ArrayList) HttpResponseException(org.keycloak.authorization.client.util.HttpResponseException) AuthorizationResource(org.keycloak.admin.client.resource.AuthorizationResource) ResourceRepresentation(org.keycloak.representations.idm.authorization.ResourceRepresentation) ResourcePermissionRepresentation(org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) Response(javax.ws.rs.core.Response) Authorization(org.keycloak.representations.AccessToken.Authorization) AuthzClient(org.keycloak.authorization.client.AuthzClient) AccessToken(org.keycloak.representations.AccessToken) Permission(org.keycloak.representations.idm.authorization.Permission) ClientResource(org.keycloak.admin.client.resource.ClientResource) Test(org.junit.Test)

Example 7 with Authorization

use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.

the class AuthorizationTest method authorize.

private List<Permission> authorize(String userName, String password, AuthorizationRequest request) {
    AuthorizationResponse response = getAuthzClient().authorization(userName, password).authorize(request);
    AccessToken token = toAccessToken(response.getToken());
    Authorization authorization = token.getAuthorization();
    return new ArrayList<>(authorization.getPermissions());
}
Also used : Authorization(org.keycloak.representations.AccessToken.Authorization) AccessToken(org.keycloak.representations.AccessToken) ArrayList(java.util.ArrayList) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse)

Example 8 with Authorization

use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.

the class AbstractPolicyEnforcer method isAuthorized.

protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade, Map<String, List<String>> claims) {
    Request request = httpFacade.getRequest();
    if (isDefaultAccessDeniedUri(request)) {
        return true;
    }
    Authorization authorization = accessToken.getAuthorization();
    if (authorization == null) {
        return false;
    }
    boolean hasPermission = false;
    Collection<Permission> grantedPermissions = authorization.getPermissions();
    for (Permission permission : grantedPermissions) {
        if (permission.getResourceId() != null) {
            if (isResourcePermission(actualPathConfig, permission)) {
                hasPermission = true;
                if (actualPathConfig.isInstance() && !matchResourcePermission(actualPathConfig, permission)) {
                    continue;
                }
                if (hasResourceScopePermission(methodConfig, permission)) {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, grantedPermissions);
                    }
                    if (HTTP_METHOD_DELETE.equalsIgnoreCase(request.getMethod()) && actualPathConfig.isInstance()) {
                        policyEnforcer.getPathMatcher().removeFromCache(getPath(request));
                    }
                    return hasValidClaims(permission, claims);
                }
            }
        } else {
            if (hasResourceScopePermission(methodConfig, permission)) {
                hasPermission = true;
                return true;
            }
        }
    }
    if (!hasPermission && EnforcementMode.PERMISSIVE.equals(actualPathConfig.getEnforcementMode())) {
        return true;
    }
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debugf("Authorization FAILED for path [%s]. Not enough permissions [%s].", actualPathConfig, grantedPermissions);
    }
    return false;
}
Also used : Authorization(org.keycloak.representations.AccessToken.Authorization) Request(org.keycloak.adapters.spi.HttpFacade.Request) Permission(org.keycloak.representations.idm.authorization.Permission)

Example 9 with Authorization

use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.

the class AuthorizationTokenService method isUpgraded.

private boolean isUpgraded(AuthorizationRequest request, Authorization authorization) {
    AccessToken previousRpt = request.getRpt();
    if (previousRpt == null) {
        return false;
    }
    Authorization previousAuthorization = previousRpt.getAuthorization();
    if (previousAuthorization != null) {
        Collection<Permission> previousPermissions = previousAuthorization.getPermissions();
        if (previousPermissions != null) {
            for (Permission previousPermission : previousPermissions) {
                if (!authorization.getPermissions().contains(previousPermission)) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : Authorization(org.keycloak.representations.AccessToken.Authorization) AccessToken(org.keycloak.representations.AccessToken) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Permission(org.keycloak.representations.idm.authorization.Permission)

Example 10 with Authorization

use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.

the class AuthorizationTokenService method resolveResourcePermission.

private void resolveResourcePermission(KeycloakAuthorizationRequest request, ResourceServer resourceServer, KeycloakIdentity identity, AuthorizationProvider authorization, StoreFactory storeFactory, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, AtomicInteger limit, Permission permission, Set<Scope> requestedScopesModel, String resourceId) {
    Resource resource;
    if (resourceId.indexOf('-') != -1) {
        resource = resourceStore.findById(resourceId, resourceServer.getId());
    } else {
        resource = null;
    }
    if (resource != null) {
        addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource);
    } else if (resourceId.startsWith("resource-type:")) {
        // only resource types, no resource instances. resource types are owned by the resource server
        String resourceType = resourceId.substring("resource-type:".length());
        resourceStore.findByType(resourceType, resourceServer.getId(), resourceServer.getId(), resource1 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource1));
    } else if (resourceId.startsWith("resource-type-any:")) {
        // any resource with a given type
        String resourceType = resourceId.substring("resource-type-any:".length());
        resourceStore.findByType(resourceType, null, resourceServer.getId(), resource12 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource12));
    } else if (resourceId.startsWith("resource-type-instance:")) {
        // only resource instances with a given type
        String resourceType = resourceId.substring("resource-type-instance:".length());
        resourceStore.findByTypeInstance(resourceType, resourceServer.getId(), resource13 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource13));
    } else if (resourceId.startsWith("resource-type-owner:")) {
        // only resources where the current identity is the owner
        String resourceType = resourceId.substring("resource-type-owner:".length());
        resourceStore.findByType(resourceType, identity.getId(), resourceServer.getId(), resource14 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource14));
    } else {
        Resource ownerResource = resourceStore.findByName(resourceId, identity.getId(), resourceServer.getId());
        if (ownerResource != null) {
            permission.setResourceId(ownerResource.getId());
            addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, ownerResource);
        }
        if (!identity.isResourceServer() || !identity.getId().equals(resourceServer.getId())) {
            List<PermissionTicket> tickets = storeFactory.getPermissionTicketStore().findGranted(resourceId, identity.getId(), resourceServer.getId());
            if (!tickets.isEmpty()) {
                List<Scope> scopes = new ArrayList<>();
                Resource grantedResource = null;
                for (PermissionTicket permissionTicket : tickets) {
                    if (grantedResource == null) {
                        grantedResource = permissionTicket.getResource();
                    }
                    scopes.add(permissionTicket.getScope());
                }
                requestedScopesModel.retainAll(scopes);
                ResourcePermission resourcePermission = addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, grantedResource);
                // the permission is explicitly granted by the owner, mark this permission as granted so that we don't run the evaluation engine on it
                resourcePermission.setGranted(true);
            }
            Resource serverResource = resourceStore.findByName(resourceId, resourceServer.getId());
            if (serverResource != null) {
                permission.setResourceId(serverResource.getId());
                addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, serverResource);
            }
        }
    }
    if (permissionsToEvaluate.isEmpty()) {
        CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(request.getCors(), "invalid_resource", "Resource with id [" + resourceId + "] does not exist.", Status.BAD_REQUEST);
        fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
        throw invalidResourceException;
    }
}
Also used : ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Arrays(java.util.Arrays) Tokens(org.keycloak.authorization.util.Tokens) UserSessionProvider(org.keycloak.models.UserSessionProvider) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) BiFunction(java.util.function.BiFunction) Permissions(org.keycloak.authorization.permission.Permissions) PermissionTicketAwareDecisionResultCollector(org.keycloak.authorization.policy.evaluation.PermissionTicketAwareDecisionResultCollector) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Metadata(org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata) MediaType(javax.ws.rs.core.MediaType) OAuthErrorException(org.keycloak.OAuthErrorException) AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AccessToken(org.keycloak.representations.AccessToken) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) Map(java.util.Map) ClientConnection(org.keycloak.common.ClientConnection) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) Collection(java.util.Collection) AuthorizationRequest(org.keycloak.representations.idm.authorization.AuthorizationRequest) Set(java.util.Set) ResourceStore(org.keycloak.authorization.store.ResourceStore) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) Collectors(java.util.stream.Collectors) IDToken(org.keycloak.representations.IDToken) KeycloakIdentity(org.keycloak.authorization.common.KeycloakIdentity) Objects(java.util.Objects) List(java.util.List) ScopeStore(org.keycloak.authorization.store.ScopeStore) ServiceAccountConstants(org.keycloak.common.constants.ServiceAccountConstants) Response(javax.ws.rs.core.Response) Details(org.keycloak.events.Details) DefaultEvaluationContext(org.keycloak.authorization.common.DefaultEvaluationContext) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) Entry(java.util.Map.Entry) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) ClientModel(org.keycloak.models.ClientModel) Scope(org.keycloak.authorization.model.Scope) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Permission(org.keycloak.representations.idm.authorization.Permission) Logger(org.jboss.logging.Logger) StoreFactory(org.keycloak.authorization.store.StoreFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) RefreshToken(org.keycloak.representations.RefreshToken) TokenManager(org.keycloak.protocol.oidc.TokenManager) HttpMethod(javax.ws.rs.HttpMethod) ArrayList(java.util.ArrayList) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) UserModel(org.keycloak.models.UserModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) EventBuilder(org.keycloak.events.EventBuilder) OIDCAdvancedConfigWrapper(org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper) PermissionTicketToken(org.keycloak.representations.idm.authorization.PermissionTicketToken) Cors(org.keycloak.services.resources.Cors) Status(javax.ws.rs.core.Response.Status) Base64Url(org.keycloak.common.util.Base64Url) ResourceServer(org.keycloak.authorization.model.ResourceServer) Errors(org.keycloak.events.Errors) Authorization(org.keycloak.representations.AccessToken.Authorization) KeycloakSession(org.keycloak.models.KeycloakSession) HttpRequest(org.jboss.resteasy.spi.HttpRequest) UserSessionModel(org.keycloak.models.UserSessionModel) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) JsonSerialization(org.keycloak.util.JsonSerialization) EvaluationContext(org.keycloak.authorization.policy.evaluation.EvaluationContext) ResourceServerStore(org.keycloak.authorization.store.ResourceServerStore) Urls(org.keycloak.services.Urls) AccessTokenResponseBuilder(org.keycloak.protocol.oidc.TokenManager.AccessTokenResponseBuilder) Resource(org.keycloak.authorization.model.Resource) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) Scope(org.keycloak.authorization.model.Scope) Resource(org.keycloak.authorization.model.Resource) ArrayList(java.util.ArrayList) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Aggregations

Authorization (org.keycloak.representations.AccessToken.Authorization)15 AccessToken (org.keycloak.representations.AccessToken)14 Permission (org.keycloak.representations.idm.authorization.Permission)11 AuthorizationResponse (org.keycloak.representations.idm.authorization.AuthorizationResponse)10 ArrayList (java.util.ArrayList)8 AuthorizationRequest (org.keycloak.representations.idm.authorization.AuthorizationRequest)8 HashSet (java.util.HashSet)6 Set (java.util.Set)6 Test (org.junit.Test)6 AuthorizationResource (org.keycloak.admin.client.resource.AuthorizationResource)5 ClientResource (org.keycloak.admin.client.resource.ClientResource)5 AuthzClient (org.keycloak.authorization.client.AuthzClient)5 ResourceRepresentation (org.keycloak.representations.idm.authorization.ResourceRepresentation)5 Response (javax.ws.rs.core.Response)4 ResourcePermissionRepresentation (org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation)4 Collection (java.util.Collection)3 OAuthClient (org.keycloak.testsuite.util.OAuthClient)3 Arrays (java.util.Arrays)2 HashMap (java.util.HashMap)2 List (java.util.List)2