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

Fine Grained Permissions #436

Open
andez2000 opened this issue Apr 26, 2023 · 2 comments
Open

Fine Grained Permissions #436

andez2000 opened this issue Apr 26, 2023 · 2 comments

Comments

@andez2000
Copy link

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

@namoshizun
Copy link

namoshizun commented May 11, 2023

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?

@andez2000
Copy link
Author

andez2000 commented Jun 5, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants