Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to enable fine-grained user permissions results in 404 error #951

Open
taladar opened this issue Nov 27, 2023 · 7 comments
Open

Trying to enable fine-grained user permissions results in 404 error #951

taladar opened this issue Nov 27, 2023 · 7 comments
Assignees
Labels

Comments

@taladar
Copy link

taladar commented Nov 27, 2023

Current Behavior

When I enable fine-grained permissions to allow a client direct naked impersonation manually and compare the realm exports it adds the fields

"authorizationServicesEnabled": true,

and

      "authorizationSettings": { ... }

to the realm export's realm-management client.

When I try to add a realm-management client to my keycloak-config-cli.json with these fields the run (on Kubernetes with the bitnami helm chart) results in a 404 error when it tries to call the /clients/.../authz/resource-server/settings endpoint, presumably because at this time fine-grained permissions are not enabled yet in the existing configuration on the Keycloak.

Expected Behavior

When authorizationServicesEnabled is false on the existing client keycloak-config-cli probably should not try to get the existing settings but just set them or at the very least not consider the 404 fatal.

Steps To Reproduce

1. Create a Keycloak and Realm with the bitnami helm chart using keycloak-config-cli
2. Update the realm realm-management client to include the above settings (easiest to just manually enable fine-grained permissions and export the realm JSON for the full value required)
3. redeploy with the new keycloak-config-cli including the settings
4. watch 404 in job log for keycloak-config-cli job, alternatively watch the whole request with a debug container with tcpdump or something similar

Environment

  • Keycloak Version: 22.0.5
  • Keycloak Bitnami Helm Chart Version> 17.3.3
  • keycloak-config-cli Version: 5.9.0
  • Java Version: whatever the bitnami container uses

Anything else?

No response

@taladar taladar added the bug label Nov 27, 2023
@danm-de
Copy link

danm-de commented Mar 20, 2024

I can confirm this behavior when using:

  • keycloak:23.0.7
  • keycloak-config-cli:5.10.0
    😢
2024-03-20 12:08:52 2024-03-20 11:08:52.623  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : Importing file 'file:/config/20_create_clients.json'
2024-03-20 12:08:53 2024-03-20 11:08:53.333 ERROR 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : HTTP 404 Not Found

@danm-de
Copy link

danm-de commented Mar 20, 2024

I've checked the documentation and the sample files in the testing directory but couldn't get it to work. I always receive a 404 or 400 error.

What I'm trying to do is create a policy over the entire Users resource. A specific client named MyTestClient gets the impersonate scope.

image

image

image

Test-JSON (works when using as initial import file import-realm.json):

{
  "id": "MyTestRealm",
  "realm": "MyTestRealm",
  "clients": [
    {
      "clientId": "realm-management",
      "enabled": true,
      "authorizationServicesEnabled": true,
      "authorizationSettings": {
        "policyEnforcementMode": "ENFORCING",
        "resources": [
          {
            "name": "Users",
            "scopes": [
              {
                "name": "user-impersonated"
              },
              {
                "name": "manage-group-membership"
              },
              {
                "name": "view"
              },
              {
                "name": "impersonate"
              },
              {
                "name": "map-roles"
              },
              {
                "name": "manage"
              }
            ]
          }
        ],
        "policies": [
          {
            "name": "Impersonate-Clients",
            "description": "",
            "type": "client",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "clients": "[\"MyTestClient\"]"
            }
          },
          {
            "name": "manage.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"manage\"]"
            }
          },
          {
            "name": "view.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"view\"]"
            }
          },
          {
            "name": "map-roles.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"map-roles\"]"
            }
          },
          {
            "name": "manage-group-membership.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"manage-group-membership\"]"
            }
          },
          {
            "name": "user-impersonated.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"user-impersonated\"]"
            }
          },
          {
            "name": "admin-impersonating.permission.users",
            "type": "scope",
            "logic": "POSITIVE",
            "decisionStrategy": "UNANIMOUS",
            "config": {
              "resources": "[\"Users\"]",
              "scopes": "[\"impersonate\"]",
              "applyPolicies": "[\"Impersonate-Clients\"]"
            }
          }
        ],
        "scopes": [
          {
            "name": "manage"
          },
          {
            "name": "view"
          },
          {
            "name": "map-roles"
          },
          {
            "name": "impersonate"
          },
          {
            "name": "user-impersonated"
          },
          {
            "name": "manage-group-membership"
          }
        ],
        "decisionStrategy": "UNANIMOUS"
      }
    },
    {
      "clientId": "MyTestClient",
      "enabled": true,
      "clientAuthenticatorType": "client-secret",
      "redirectUris": [
        "*"
      ],
      "webOrigins": [
        "*"
      ],
      "standardFlowEnabled": true,
      "directAccessGrantsEnabled": true,
      "serviceAccountsEnabled": true,
      "frontchannelLogout": true,
      "protocol": "openid-connect",
      "fullScopeAllowed": true
    }
  ]
}

@Sebastian-Gil-wcq
Copy link

Sebastian-Gil-wcq commented May 1, 2024

Had the same issue with:
keycloak: 24.0.2
keycloak-config-cli:5.12.0-24.0.1

By enabling logs with

            - name: LOGGING_LEVEL_HTTP
              value: INFO

I was able to find that

2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "DELETE /admin/realms/api-cli/clients/c98a928a-83d0-471a-bab7-3e93e66775cc/authz/resource-server/scope/f2f40817-b48e-44b5-90f3-40fc11d537d9 HTTP/1.1[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJKeEpSdGdoWmp0R1paRFh4RmVwLW5BRTlqcTZ0UmRmUUZ5Tm9tMGNZOUswIn0.eyJleHAiOjE3MTQ1MzY3NjQsImlhdCI6MTcxNDUzNjcwNCwianRpIjoiNDI4YTU5NzAtMTQ1Ny00NGE4LWIwNTktYTdmMjBlZWNhNjQ2IiwiaXNzIjoiaHR0cDovL2tleWNsb2FrLmtleWNsb2FrLnN2Yy9yZWFsbXMvbWFzdGVyIiwic3ViIjoiZGFhNWEzOGUtNzE4OS00M2Y1LTg0MDgtYzdlNjVmMWZiOTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwic2Vzc2lvbl9zdGF0ZSI6ImExMDlmNTI3LWJmM2MtNGE2Mi1hOTE1LWI0OWI3MjcyOGJkNCIsImFjciI6IjEiLCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiJhMTA5ZjUyNy1iZjNjLTRhNjItYTkxNS1iNDliNzI3MjhiZDQiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImtleWNsb2FrIn0.eQb5DXIxKaaDayXkISp2tnZZ5-ArFPB1nBy7H0MrI7bJ9adGuy9t8bhRu0bLU5OW0Ev27p7gjoq3Se7Q6cXOjLRenZao9yd6DTwd2eofNLNXiISJpSVcizIWtRk7dlEDdHeWI0jzi-dYAbRw0BzsaQi7cdi-358ux6vf4rx9YmREWsGKtMfipU0sCCTsyJe5BzjFxVwYJbfMv88pWEV13rxzUxESDIOqKIhfzyTZQwiUG9uwA-E4l5AIjUZIq-mmQ5qweiN5ah3csDcjYAMnPhgSb8ntPSzCaPZmNZhk00zO4cg9SL1a2CDws2fkr2JmixO1tYOCAziVvl9NJPX5Vw[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "Content-Length: 0[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "Host: keycloak.keycloak.svc[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.10)[\r][\n]"
2024-05-01 04:11:48.370 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 >> "[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "HTTP/1.1 400 Bad Request[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "content-length: 77[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "Content-Type: application/json[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "Referrer-Policy: no-referrer[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "Strict-Transport-Security: max-age=31536000; includeSubDomains[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "X-Content-Type-Options: nosniff[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "X-Frame-Options: SAMEORIGIN[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "X-XSS-Protection: 1; mode=block[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "[\r][\n]"
2024-05-01 04:11:48.386 DEBUG 1 --- [           main] org.apache.http.wire                     : http-outgoing-0 << "{"errorMessage":"Scopes can not be removed while associated with resources."}"
2024-05-01 04:11:48.424 ERROR 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : HTTP 400 Bad Request

which led me to the conclusion that actually keycloak-cli should be more strict in terms of applying changes to realm-management client.
As a workaround you may use:

-Dimport.managed.client-authorization-scopes=no-delete -Dimport.managed.client-authorization-policies=no-delete -Dimport.managed.client-authorization-resources=no-delete

That will prevent keycloak-cli from removing some relevant resources from realm-management client

Probably adding client property authorizationServicesEnabled: true won't harm as well.
Here's a working example:

- clientId: realm-management
  authorizationServicesEnabled: true
  authorizationSettings:
    allowRemoteResourceManagement: false
    policyEnforcementMode: ENFORCING
    resources:
      - name: client.resource.$my-test-client
        type: Client
        ownerManagedAccess: false
        attributes: {}
        uris: []
        scopes:
          - name: view
          - name: map-roles-client-scope
          - name: configure
          - name: map-roles
          - name: manage
          - name: token-exchange
          - name: map-roles-composite
    policies:
      - name: my-test-client-manager-role-policy
        description: 'Manager policy for role: my-test-client-manager'
        type: role
        logic: POSITIVE
        decisionStrategy: UNANIMOUS
        config:
          roles: '[{"id":"my-test-client-manager","required":true}]'
      - name: manage.permission.client.$my-test-client
        description: 'Manager policy for client: my-test-client'
        type: scope
        logic: POSITIVE
        decisionStrategy: UNANIMOUS
        config:
          resources: '["client.resource.$my-test-client"]'
          scopes: '["manage"]'
          applyPolicies: '["my-test-client-manager-role-policy"]'

Please, at least update the documentation. The current version of docs doesn't provide enough context.

@pbromb
Copy link

pbromb commented May 27, 2024

@danm-de, were you able to solve the problem? I have the same issue with token impersonation configuration.

@danm-de
Copy link

danm-de commented May 27, 2024

@danm-de, were you able to solve the problem? I have the same issue with token impersonation configuration.

Nope 😞

@tangkevkev
Copy link

@danm-de experiencing the same issue with creating a new policy over the User Resource. Did you find a workaround?

@danm-de
Copy link

danm-de commented Aug 6, 2024

@danm-de experiencing the same issue with creating a new policy over the User Resource. Did you find a workaround?

Nope. We use an import-realm.json file as an initial import that contains the required realm configuration (with all clients, users and policies) that cannot be set using keycloak-config-cli.

The docker-compose.yml references the bitnami version, it looks like this:

keycloak:
    image: docker.io/bitnami/keycloak:$KEYCLOAK_VERSION
    restart: always
    depends_on:
      - postgresql ## replace with your database / storage ##
    environment:
      KEYCLOAK_ADMIN_USER: "admin"
      KEYCLOAK_ADMIN_PASSWORD: "...."
      KEYCLOAK_MANAGEMENT_USER: "manager"
      KEYCLOAK_MANAGEMENT_PASSWORD: "...."
      KEYCLOAK_ENABLE_HEALTH_ENDPOINTS: "true"
      KC_METRICS_ENABLED: "true"
      KC_FEATURES: "token-exchange,admin-fine-grained-authz"
      KEYCLOAK_EXTRA_ARGS: "--import-realm"
    volumes:
      - ./path/to/your/import-realm.json:/opt/bitnami/keycloak/data/import/import-realm.json
    ports:
      - "8081:8080"

The CONFIG-CLI entry looks like this:

  keycloak-config-cli:
    image: docker.io/bitnami/keycloak-config-cli:$KEYCLOAK_CONFIG_CLI_VERSION
    restart: no
    depends_on: 
      - keycloak
    environment:
      KEYCLOAK_URL: "http://keycloak:8080/"
      KEYCLOAK_USER: "admin"
      KEYCLOAK_PASSWORD: "...."
      KEYCLOAK_AVAILABILITYCHECK_ENABLED: "true"
      KEYCLOAK_AVAILABILITYCHECK_TIMEOUT: "120s"
      IMPORT_FILES_LOCATIONS: "/config/*"
      IMPORT_VARSUBSTITUTION_ENABLED: "true"
      IMPORT_MANAGED_CLIENTAUTHORIZATIONPOLICIES: "full"
      IMPORT_MANAGED_CLIENTAUTHORIZATIONSCOPES: "full"
      IMPORT_MANAGED_CLIENTAUTHORIZATIONRESOURCES: "full"
    volumes:
      - ./path/to/your/config:/config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: In Progress
Development

No branches or pull requests

6 participants