Giter VIP home page Giter VIP logo

fastapi-keycloak's Introduction

fastapi-keycloak's People

Contributors

alexbarcelo avatar daguich avatar dependabot[bot] avatar fherrera124 avatar flosckow avatar gitbib avatar jeromecremers avatar jonasscholl avatar jonra1993 avatar laxdog avatar odnobit avatar remicres avatar slavong avatar socar-humphrey avatar stratosgear avatar tchalupnik avatar thomasdarimont avatar twistfire92 avatar valeriiduz avatar yannicschroeer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

fastapi-keycloak's Issues

Question: 2FA support

Does this integration support the KeyCloak 2FA authentication, such as OTP with Authentication Apps?

Required custom roles

In the Quickstart code example we can see that for the admin endpoint, the user needs to have the "admin" role assigned in order to proceed. This is a great feature.

However, from what I noticed, this function checks only the roles that we can find under "realm_access" -> "roles".
There are also other roles that can be found under "resource_access" for each defined client in keycloak.

How can I create this filter based on roles with a custom keycloak client that has its own custom roles?

Thanks in advance for your reply!

Missing token introspection

The library is missing the token introspection as defined in the standard: https://datatracker.ietf.org/doc/html/rfc7662
A consequence of this is that even if a user has been disabled on the keycloak side, if a user still has a valid JWT that was generated before, the library will still consider it to be valid. We'll have to wait until the JWT expiration time (that could last for long..) before a user can be considered as completely blocked.

A very simple piece of code that can handle this:

    from authlib.integrations.requests_client import OAuth2Session
    from fastapi import HTTPException

    oauth = OAuth2Session(client_id=client_id, client_secret=client_secret)
    result = oauth.introspect_token(
        url=f"{keycloak_server}/auth/realms/{realm_name}/protocol/openid-connect/token/introspect",
        token=token,
    )
    content = json.loads(result.content.decode())
    if not content["active"]:
        raise HTTPException(status_code=401, detail="Token expired or invalid")
    else:
        .....

unable to connect to keycloak server

keycloak version :: 19.0.0

requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /realms/RealmOne/.well-known/openid-configuration (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f94efdfe610>: Failed to establish a new connection: [Errno 111] Connection refused'))

(
server_url="http://localhost:8080",
client_id="myApp",
client_secret="Y49wuMTCnLbX2bufuasJ73RSR9ivLWLu",
admin_client_secret="admin-cli-secret",
realm="RealmOne",
callback_uri="http://localhost:8080/callback"
)
I cannot find the admin secret anywhere in keycloak .

Parse token for additional information

I've been using https://github.com/elbernv/fastapi-keycloack to add security to my routes. I was trying to switch to using this library, seeing as though it is getting regular updates. I was wondering if it's currently possible to decode more from the token than what the OIDCUser object currently returns?

For example, I've added the users group memberships to the profile scope, I've also added it as it's own scope, so two questions:

  1. Is it possible to fetch the group memberships from the token when using the profile scope?
  2. Is it possible to add more scopes? It seems like only profile and email are currently available when adding security to the FastAPI application.

Thank you.

Bypass Certificate Verification on Development

Hi

I'm trying to use this package on a local Keycloak instance that uses a self-signed certificate. Since python requests verify the certificate by default, creating a FastAPIKeycloak wrapper to the Keycloak instance always raises an SSLVerificationError.

Is it okay if a verify server certificate parameter will be included to the FastAPIKeycloak wrapper so we can temporarily bypass certificate verification?

Thank you!

Make admin-client configurable

Currently fastapi-keycloak uses the hard-coded client id admin-cli for interacting with keycloaks admin API.

The admin-cli client is usually used for automation and, if configured as a confidential client with a service account, has often a highly provileged account associated with it.

In scenarios where the user wants to reduce the capabilities of what the fastapi-keycloak client is allowed to do it would be helpful to be able to use a dedicated client which for instance has only permission to view-users (dedicated service account with role realm-management.view-users). Therefore it would be helpful to be able to use a custom "admin-client" here.

I think it would be enough to just add an additional parameter admin_client_id to the FastAPIKeycloak init method.
admin_client_id could default to admin-cli and simply use the given admin-client for accesing the Keycloak admin api.

FastAPIKeycloak(
...
	admin_client_id=my-admin-client,
	admin_client_secret=...
...
)

manifest for jboss/keycloak:16.0.1 not found

Hi,

it seems that the keycloak image tag used in the docker-compose file example in doc/getting_started does not exist:
ERROR: manifest for jboss/keycloak:16.0.1 not found
The existing tags are shown here (I used 16.1.1).

Can we pass dynamic realm, client_id and client_secret params to FastAPIKeycloak class

I am looking for a multi-tenant-based solution, where the customer maintains different realms for different vendors. How could we manage the FastAPIKeycloak() creation and .get_current_user() authentication/authorisation?

Based on the URL I am figuring out the tenant and getting the relevant Database details, but now confused about how we could use the
below OIDCUser in the Endpoint definition.

user: OIDCUser = Depends(keycloak_obj.get_current_user())

@yannicschroeer

Validate token in current_user

We figured that current_user(line 220) function when receiving a token, doesn't validate the token like lib does in admin_token(line 141) method.

Is it by design or can I create a fix for that?

password -> tokenUrl none is not an allowed value

I'm trying to set this up for a FastAPI which should authenticate against an existing Keycloak 17.0.1 server which I've customized according to https://fastapi-keycloak.code-specialist.com/keycloak_configuration/

FastAPI 0.95.0, fastapi-keycloak latest

During startup of the FastAPI server I get this stacktrace:

  File "/home/jovyan/app/main.py", line 93, in <module>
    def current_users(user: OIDCUser = Depends(idp.get_current_user())):
                                               ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/fastapi_keycloak/api.py", line 244, in get_current_user
    token: OAuth2PasswordBearer = Depends(self.user_auth_scheme),
                                          ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/functools.py", line 1001, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/fastapi_keycloak/api.py", line 223, in user_auth_scheme
    return OAuth2PasswordBearer(tokenUrl=self.token_uri)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/fastapi/security/oauth2.py", line 151, in __init__
    flows = OAuthFlowsModel(password={"tokenUrl": tokenUrl, "scopes": scopes})
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for OAuthFlows
password -> tokenUrl
  none is not an allowed value (type=type_error.none.not_allowed)

server_url is set to https://<server>:8443/realms/<realm>/protocol/openid-connect/auth

I see no option to configure the tokenUrl, with our keycloak server we configure as https://<server>:8443/realms/<realm>/protocol/openid-connect/token for other clients.

(I've also used the suggestion in #60 to avoid issues with the admin_cli which I don't need in that FastAPI server)

User Logout

Hi,

Cheers to the commendable work that you have done.

Can you shed some light on the "user logout" as well, I do not see a method for that.

Though the token expires after some time from KeyCloak but a user logout would be great.

Also, can you shed some light on maybe your documentation about how the [admin-cli] and [auth-flow] endpoints are supposed to work so that your docs become more powerful and user-friendly.

Looking forward to hear from you.

Cheers,
Kaustuv.

Object non evaluated on getting decoded_token from Keycloak

How to reproduce ?

Env preparation.

pipenv install fastapi fastapi-keycloak

I followed your quickstart and full example instructions then :

pipenv run python main.py

What the result?

pipenv run python main.py 
Traceback (most recent call last):
  File "main.py", line 10, in <module>
    idp = FastAPIKeycloak(
  File "/home/germainlef/.local/share/virtualenvs/auth-keycloak-WIW7vmvr/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 125, in __init__
    self._get_admin_token()  # Requests an admin access token on startup
  File "/home/germainlef/.local/share/virtualenvs/auth-keycloak-WIW7vmvr/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 285, in _get_admin_token
    self.admin_token = response.json()['access_token']
  File "/home/germainlef/.local/share/virtualenvs/auth-keycloak-WIW7vmvr/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 154, in admin_token
    if not decoded_token.get('resource_access').get('realm-management') or not decoded_token.get('resource_access').get('account'):
AttributeError: 'NoneType' object has no attribute 'get'

Unable to pip install from python docker images

Hello,

pip fails to install fastapi_keycloak on the following docker images:

  • python3.8
  • python3.8-slim
  • python3.9-slim
  • python3.10-slim

I have no clue why it fails (tested with pip==22.3, 22.1.2, 22.2)

Obtaining file:///tmp/fastapi-keycloak
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'error'
  error: subprocess-exited-with-error
  
  Γ— Getting requirements to build editable did not run successfully.
  β”‚ exit code: 1
  ╰─> [43 lines of output]
      Traceback (most recent call last):
        File "/usr/local/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 351, in <module>
          main()
        File "/usr/local/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 333, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/usr/local/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 132, in get_requires_for_build_editable
          return hook(config_settings)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 446, in get_requires_for_build_editable
          return self.get_requires_for_build_wheel(config_settings)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 338, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 320, in _get_build_requires
          self.run_setup()
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 483, in run_setup
          super(_BuildMetaLegacyBackend,
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 335, in run_setup
          exec(code, locals())
        File "<string>", line 9, in <module>
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/__init__.py", line 87, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 159, in setup
          dist.parse_config_files()
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 868, in parse_config_files
          pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 62, in apply_configuration
          config = read_configuration(filepath, True, ignore_option_errors, dist)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 140, in read_configuration
          return expand_configuration(asdict, root_dir, ignore_option_errors, dist)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 195, in expand_configuration
          return _ConfigExpander(config, root_dir, ignore_option_errors, dist).expand()
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 242, in expand
          self._expand_all_dynamic(dist, package_dir)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 279, in _expand_all_dynamic
          obtained_dynamic = {
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 280, in <dictcomp>
          field: self._obtain(dist, field, package_dir)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 326, in _obtain
          self._ensure_previously_set(dist, field)
        File "/tmp/pip-build-env-q7yvswdc/overlay/lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py", line 305, in _ensure_previously_set
          raise OptionError(msg)
      distutils.errors.DistutilsOptionError: No configuration found for dynamic 'description'.
      Some dynamic fields need to be specified via `tool.setuptools.dynamic`
      others must be specified via the equivalent attribute in `setup.py`.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

Γ— Getting requirements to build editable did not run successfully.
β”‚ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

Support for OpenID Connect Auto-Discovery

Keycloak supports OpenID Connect Discovery which enables automatic client configuration, like the auth endpoint, token endpoint, userinfo endpoint, JWKS endpoint etc.

Keycloak exposes the openid connect discovery document at
$AUTH_SERVER_URL/auth/realms/$realm/.well-known/openid-configuration
or $ISSUER/.well-known/openid-configuration where issuer is $AUTH_SERVER_URL/auth/realms/$realm.

Here is an example discovery document.

It would be great if this would be supoported. Other oauth/oidc capable libraries like authlib support this feature too (example).

Cannot install from sources: distutils.errors.DistutilsOptionError: No configuration found for dynamic 'description'.

Hi folks! And thank you for this great project.

I have a problem: I wanted to install fastapi-keycloak from sources. I made a virtualenv, activated it, moved into fastapi-keycloak cloned directory and tried to run pip3 install -e .

I got the following error:

(venv_py3.8) ➜  fastapi-keycloak git:(master) pip3 install -e .                                         
Obtaining file:///mnt/dump1/Projects/fastapi-keycloak
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... error
  error: subprocess-exited-with-error
  
  Γ— Getting requirements to build editable did not run successfully.
  β”‚ exit code: 1
  ╰─> [45 lines of output]
      Traceback (most recent call last):
        File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 351, in <module>
          main()
        File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 333, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 132, in get_requires_for_build_editable
          return hook(config_settings)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 447, in get_requires_for_build_editable
          return self.get_requires_for_build_wheel(config_settings)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 338, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 320, in _get_build_requires
          self.run_setup()
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 484, in run_setup
          super(_BuildMetaLegacyBackend,
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 335, in run_setup
          exec(code, locals())
        File "<string>", line 9, in <module>
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/__init__.py", line 87, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 159, in setup
          dist.parse_config_files()
        File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/_virtualenv.py", line 21, in parse_config_files
          result = old_parse_config_files(self, *args, **kwargs)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/dist.py", line 867, in parse_config_files
          pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 62, in apply_configuration
          config = read_configuration(filepath, True, ignore_option_errors, dist)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 140, in read_configuration
          return expand_configuration(asdict, root_dir, ignore_option_errors, dist)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 195, in expand_configuration
          return _ConfigExpander(config, root_dir, ignore_option_errors, dist).expand()
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 242, in expand
          self._expand_all_dynamic(dist, package_dir)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 279, in _expand_all_dynamic
          obtained_dynamic = {
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 280, in <dictcomp>
          field: self._obtain(dist, field, package_dir)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 326, in _obtain
          self._ensure_previously_set(dist, field)
        File "/tmp/pip-build-env-_7z1buyv/overlay/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py", line 305, in _ensure_previously_set
          raise OptionError(msg)
      distutils.errors.DistutilsOptionError: No configuration found for dynamic 'description'.
      Some dynamic fields need to be specified via `tool.setuptools.dynamic`
      others must be specified via the equivalent attribute in `setup.py`.
      [end of output]
 

Can you please tell me, how can I cope with it?

P.S. I have Python 3.8, pip 22.3.1, Ubuntu 22.04

fastapi-keycloak docs outdated?

Hello all,

Are there any plans on updating this library to use the latest version of Keycloak and also update the docs?

I think this library is based on Keycloak version 16.1.0 as seen here: https://fastapi-keycloak.code-specialist.com/quick_start/

 keycloak:
    image: jboss/keycloak:16.1.0   

Also: https://fastapi-keycloak.code-specialist.com/reference/
It should be "FastAPIKeycloak" instead of "KeycloakFastAPI"

Thank you very much for your valuable time.

Best Regards,

koufopoulosf

Error on "get_user" when user doesn't exists

Wen i try to search for a user that doesn't exist, an error occurs:

{
  "detail": "list index out of range"
}

Occurs in the line below, as the API returns a empty array.

return KeycloakUser(**response.json()[0])

A suggestion would be to check before instantiating the object:

response_json = response.json()
return KeycloakUser(**response_json[0]) if len(response_json) else None

This way the API will allow me to check if a user exists in keycloak.
What do you think?

realmRoles Field required

Using the examples provided, I'm unable to get the user's info through the route

http://localhost:8081/user/2b1b34f0-5efb-4cf8-b620-b619fd9b98bc (it's a valid user-id)

due to a pydantic error:

pydantic_core._pydantic_core.ValidationError: 1 validation error for KeycloakUser
realmRoles Field required [type=missing, input_value={'id': '2b1b34f0-5efb-4cf8-b620-b619fd9b98bc'...}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.1/v/missing

This is due to the absence, in the incoming json (Python dict), of the key "realmRoles" which is NOT always returned by the KeyCloak platform.

In your model.py module, class KeycloakUser(BaseModel), the realmRoles field is specified as "Optional" (realmRoles: Optional[List[str]]) but this attribute seems to be ignored by pydantic...

Any suggestion?
Thanks in advance

My requirements.txt:
fastapi==0.100.1
fastapi_keycloak==1.0.10
pydantic==2.2.1
uvicorn==0.23.1

My KeyCloack platform:
docker image of jsboss/keycloak:latest (Server version: 16.1.1) with postgresql 13.0

Error when initializing example project

Hello!

really good project, i love keycloak and fastapi :-). Unfortunately I am not able to get it running and I guess this is due to a bug:

The error happens, when I the token is decoded:

PS C:\Users\User\Desktop\KeyCloakFastAPI> python .\app.py
{'exp': 1649355552, 'iat': 1649355252, 'jti': '51e67522-19f7-45b0-9894-e862b440106b', 'iss': 'http://localhost:8085/auth/realms/Test', 'sub': '33b940e2-0bdb-49a7-9356-e6e230f49619', 'ty
p': 'Bearer', 'azp': 'admin-cli', 'acr': '1', 'scope': 'profile email', 'clientId': 'admin-cli', 'clientHost': '172.23.0.1', 'email_verified': False, 'preferred_username': 'service-acco
unt-admin-cli', 'clientAddress': '172.23.0.1'}

I my token I donΒ΄t have "resource_access, which leads to "None" and to a follow up error:

AttributeError: 'NoneType' object has no attribute 'get'

traceback:

Traceback (most recent call last):
  File ".\app.py", line 7, in <module>
    idp = FastAPIKeycloak(
  File "C:\Users\User\anaconda3\lib\site-packages\fastapi_keycloak\api.py", line 129, in __init__
    self._get_admin_token()  # Requests an admin access token on startup
  File "C:\Users\User\anaconda3\lib\site-packages\fastapi_keycloak\api.py", line 292, in _get_admin_token
    self.admin_token = response.json()['access_token']
  File "C:\Users\User\anaconda3\lib\site-packages\fastapi_keycloak\api.py", line 159, in admin_token
    if not decoded_token.get('resource_access').get('realm-management') or not decoded_token.get('resource_access').get('account'):
AttributeError: 'NoneType' object has no attribute 'get'

Is there something I did wrong or is this an error in the lib?

Issue with Keycloak v20+ 'access required was not contained'

I'm trying to set this up and was following the quick start guide(without the json) and configuration from here https://fastapi-keycloak.code-specialist.com/keycloak_configuration/. I'm testing this locally using the quay.io/keycloak/keycloak:21.0.2 image.

On startup, I immediately get that the admin-cli account is missing some roles. Since this is a test I added all possible roles but the issue still persists.

Is the 'Full Scope Allowed' the authorization toggle in recent Keycloak versions? I couldn't locate this setting to enable it.

    self._get_admin_token()  # Requests an admin access token on startup
  File "/usr/local/lib/python3.9/site-packages/fastapi_keycloak/api.py", line 348, in _get_admin_token
    self.admin_token = response.json()["access_token"]
  File "/usr/local/lib/python3.9/site-packages/fastapi_keycloak/api.py", line 193, in admin_token
    raise AssertionError(
AssertionError: The access required was not contained in the access token for the `admin-cli`.
                Possibly a Keycloak misconfiguration. Check if the admin-cli client has `Full Scope Allowed`
                and that the `Service Account Roles` contain all roles from `account` and `realm_management`

Any help or pointers are appreciated.

Response types

What had been missed was corrected. It remains to solve the problem with the types when working with requests.

@GitBib What kind of problem are you referring to? Do you mean that we don't know about the data structure of responses?

Originally posted by @yannicschroeer in #34 (comment)

/protected return Not authenticated

Hello.

I try to use your lib, but i fased with some problems.

I do login http://127.0.0.1:8000/login?username=test_user&password=1234 and get access tocken
{
"access_token": "eyJhbGci....",
"refresh_token": "eyJhb....."
}

after that try to execute /protected and get 401 status.

Swagger returns users
image

I cant understand that i do wrong. I think problem in keycloak, but i've set it up by https://fastapi-keycloak.code-specialist.com/keycloak_configuration/

Could you take advice where i have to search solution?
Thx

Refresh Token

Hi Guys

Please there's way provided by this module to refresh token??

Thanks in advance.

run locally

I want to use this example locally without docker https://fastapi-keycloak.code-specialist.com/full_example/ but this give me this error message
error at line 7

  • client_secret = client > client_id > credential > Secret
  • admin_client_secret = admin_cli > credential > Secret

and please specify that fastapi_keycloak will work for new keycloak version 17

The error message is

(venv) (base) sana@sana:/office/My Projects/keycloak_implementation$ uvicorn main:app --reload --port 8001
INFO: Will watch for changes in these directories: ['/office/My Projects/keycloak_implementation']
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
INFO: Started reloader process [18160] using watchgod
Process SpawnProcess-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/uvicorn/subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "uvloop/loop.pyx", line 1501, in uvloop.loop.Loop.run_until_complete
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/uvicorn/server.py", line 67, in serve
config.load()
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/uvicorn/config.py", line 458, in load
self.loaded_app = import_from_string(self.app)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/uvicorn/importer.py", line 21, in import_from_string
module = importlib.import_module(module_str)
File "/usr/lib/python3.8/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1014, in _gcd_import
File "", line 991, in _find_and_load
File "", line 975, in _find_and_load_unlocked
File "", line 671, in _load_unlocked
File "", line 848, in exec_module
File "", line 219, in _call_with_frames_removed
File "/office/My Projects/keycloak_implementation/./main.py", line 7, in
idp = FastAPIKeycloak(
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 129, in init
self._get_admin_token() # Requests an admin access token on startup
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 288, in _get_admin_token
response = requests.post(url=self.token_uri, headers=headers, data=data)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/api.py", line 117, in post
return request('post', url, data=data, json=json, **kwargs)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/sessions.py", line 515, in request
prep = self.prepare_request(req)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/sessions.py", line 443, in prepare_request
p.prepare(
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/models.py", line 318, in prepare
self.prepare_url(url, params)
File "/office/My Projects/keycloak_implementation/venv/lib/python3.8/site-packages/requests/models.py", line 392, in prepare_url
raise MissingSchema(error)
requests.exceptions.MissingSchema: Invalid URL 'None': No scheme supplied. Perhaps you meant http://None?

Keycloak 18 incompatibilities

I wanted to use your very interesting package. Unfortunately it is not working for me because it does not find all the API endpoints its requiring.

Some weeks ago I've updated my keycloak deployment from version 17 to 18. Since then the API has changed.

For example https://{host}/auth/realms/{realm}/.well-known/openid-configuration changed to https://{host}/realms/{realm}/.well-known/openid-configuration

This happened also for the admin console. I am not sure why it's changed and why it is not even mentioned in the release notes, as this actually breaking all libraries building on top of keycloak.

If welcome I am happy to help with this issue.

Trying to run quickstart example, got error The 'realm_access' section of the provided access token is missing on /admin method

Hi again!

I've installed fastapi-keycloak 1.0.7 from PyPi and tried to run basic example.

I've started keycloak server via docker-compose with their provided docker-compose.yaml and realm-export.json. Than I've started an example FastAPI app on localhost:8081, created a keycloak user in admin panel (localhost:8085), logged in (http://localhost:8081/login) and obtained access token.

After that I've tried to use this access token in some external request: I ran Postman and created a request http://localhost:8081/admin with Authorization header filled as Bearer {token}. This request should check user roles, but I got the following error:

  File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 867, in run
    result = context.run(func, *args)
  File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/fastapi_keycloak/api.py", line 264, in current_user
    if role not in user.roles:
  File "/mnt/dump1/Projects/fastapi_sandbox/venv_py3.8/lib/python3.8/site-packages/fastapi_keycloak/model.py", line 122, in roles
    raise KeycloakError(
fastapi_keycloak.exceptions.KeycloakError: HTTP 404: The 'realm_access' section of the provided access token is missing

After that I went to keycloak admin panel again and enabled role mapper for this client (Clients --> test-client --> Mappers --> Add builtin --> realm roles), I even enabled "Add to ID token" and "Add to userinfo". Than I got new access token with /login, but nothing changed.

How can it be fixed -- and what am I doing wrong?

P.S. Here's the exact code I'm running: https://github.com/Felix-neko/fastapi_sandbox/tree/main/fastapi_sandbox

Refresh token

Hi, if i'm create pull request for refresh token, how long wait merge it?
First I want to update the schema for KeycloakToken like this acess_token: str, refresh_toke: str = None. Further, it is possible to make a separate handle.

Adde introspect token from server

For now get_current_user just parse current token without update it from keycloak server. It would be good to introspect token data directly from server. This would help deactivate the user or change the list of his roles immediately after his deactivation on the keycloak server.

Why admin_client_secret?

First, thanks for this great project.

I have a question:

In docs you metion:

Modify the admin-cli client

Settings: Service Accounts Enabled
Scope: Full Scope Allowed
Service Account Roles: Select all Client Roles available for the account and realm_management

Why do I need to give admin permissions and realm management to my client API?
If I want only to authenticate users (not create or delete), why cannot I just work with the client_secret?

It just looks like I am giving too much power to my API to just authenticate a user o validate a token.

Create clients from library

Hello there, thank you for this library that looks great.

I haven't found the possibility to create clients programmatically directly from the library, is it something planned? If not, I might open a PR to do so.

Handling Keycloak and Fastapi error messages

I really appreciate that you created this package. it is something I was looking for too much time ago. I have been using it and I face the following problem I see that the Keycloak exception is fired but it is not passed to fast API which shows 500 error. Do you know how can I pass the error message to Swagger?

This is the API I am trying to use:

@app.post("/users2")
def create_user(first_name: str, last_name: str, email: str, password: SecretStr):
    return idp.create_user(first_name=first_name, last_name=last_name, username=email, email=email, password=password.get_secret_value(), send_email_verification=False)

image

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.