python-keycloak icon indicating copy to clipboard operation
python-keycloak copied to clipboard

Fine Grained Permissions

Open andez2000 opened this issue 1 year ago • 2 comments

I am trying to setup fine grained permissions for authorization in my client. I am not sure if I am doing things right in here - or in the python keycloak api.

I am running keycloak in docker on Windows 10, using FastAPI and Python 3.11.3 to consume it. I have tried to configure a single check which I want to consume in my end point to basically ask the question can Bob perform this action?

The question is how do I ask this question using python-keycloak?

I have some code which I am testing via Postman. The token is retrieved fine and passed to my Fast API end point.

Code

access_token = request.headers.get("Authorization").replace("Bearer ", "")

token_info = keycloak_openid.introspect(access_token)

token_info['realm_access']['roles'] gives me the roles bob is assigned to.

Where do I need to look to verify the fine grained permissions?

Configuration

Realm

Name: AcmeRealm

Realm Roles

Name: bobs role

Realm Groups

Name: Bobs Role Mapping: bobs role Members: Bob

Client

ID: acme.app

Capability Config

Client Authentication: On Authorization: On Authentication Flow: Standard Flow, Direct Access Grants, Service Accounts Roles

Authorization

Resource

Name: bobs.resource Owner: acme.app Authorization Scopes: acme.app.scope

Authorization Scope

Name: acme.app.scope

Policy

Name: bobs policy Roles: bobs role Logic: Positive

Resource Based Permission

Name: some_permission Apply to resource type: No Resources: bobs.resource Policies: bobs policy Decision Strategy: Affirmative

Scope Based Permission

Name: bobs.scopebasedresource.permission Apply to resource type: No Resources: Authorization scopes: acme.app.scope Policies: bobs.policy Decision strategy: Affirmative

What have I tried?

I have had no luck calling these methods below - as I am still new and trying to figure things out - and parameters are unknown as I am unclear.

permissionsxx = keycloak_openid.uma_permissions(
 access_token,
 permissions="bobs.resourceacme.app.scope"
)

rpt = keycloak_openid.entitlement(
 access_token,
 "bobs.resource"
)

policies = keycloak_openid.get_policies(
 access_token,
 method_token_info='decode',
 key="KEYCLOAK_PUBLIC_KEY" # 
)

permissionsxxxx = keycloak_openid.get_permissions(
 access_token,
 method_token_info='introspect'
)

Any help appreciated.

Thanks

andez2000 avatar Apr 26 '23 14:04 andez2000

PS: Not really an answer because I too haven't fully figured this out...

According to the doc, you will need to call keycloak_openid.load_authorization_config("example-authz-config.json") before invoking keycloak_openid.get_permissions or keycloak_openid.get_policies, where the auth config file can be exported via the Keycloak UI (see this issue).

What I don't understand is the reason for loading the auth config in the first place. Intuitively, shouldn't the Client's authorization settings be retrieved via the Keycloak API instead of from a static file?

namoshizun avatar May 11 '23 14:05 namoshizun

I finally got a fully working fine grained (Attribute Based Access Control) up and running with FastAPI/Python. I will try and migrate it to my github.

import os
from fastapi import Request, HTTPException
from keycloak import KeycloakOpenID, KeycloakPostError

KEYCLOAK_URL = "..."
KEYCLOAK_REALM_NAME = "..."
KEYCLOAK_CLIENT_ID = "..."
KEYCLOAK_CLIENT_SECRET = "..."

keycloak_openid = KeycloakOpenID(
    server_url=f"{KEYCLOAK_URL}",
    realm_name=f"{KEYCLOAK_REALM_NAME}",
    client_id=f"{KEYCLOAK_CLIENT_ID}",
    client_secret_key=f"{KEYCLOAK_CLIENT_SECRET}"
)

def authorize_request(
    request: Request,
    permissions: str
):
    access_token = request.headers.get("whatever header you put the token in").split("Bearer ")[1]

    rpt = keycloak_openid.uma_permissions(
            access_token,
            permissions=permissions
        )
    # if you get here your all good.  add exception handling

This will work against the attached realm.json configuration you can import inside the keycloak ui (or during startup). realm.zip

andez2000 avatar Jun 05 '23 08:06 andez2000