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

keycloak api questions #4

Open
ivanstefko opened this issue Sep 27, 2018 · 1 comment
Open

keycloak api questions #4

ivanstefko opened this issue Sep 27, 2018 · 1 comment

Comments

@ivanstefko
Copy link

ivanstefko commented Sep 27, 2018

Hi Peter,
thanks for your project python-keycloak-client. I would like to ask a few questions... .

  • in your documentation I can see only a few methods/apis which can I use for Keycloak. I'm looking for some way how can I create e.g. new 'realm', 'component - like LDAP provider' .. is there some generic for it?

  • some methods in your project have as parameter 'token' ... Could you please explain why it's necessary to pass client into the methods? I thought that token is obtained/refreshed by default according the settings/credentials for realms object / oaidc_client. Why is necessary put token directly into method?

  • how can I obtain the token .. there is 'client_credentials' method but returns more than access_token. ... so I would like to know what is correct way for using e.g. 'userinfo(token)' ...

  • should I call 'client_credentials' first and parse 'access_token' from respnose... and than use this 'access_token' as token for userinfo method? Am I right or is there better/straightforward way how to do it?

Thanks Peter!

Ivan

@Peter-Slump
Copy link
Owner

in your documentation I can see only a few methods/apis which can I use for Keycloak. I'm looking for some way how can I create e.g. new 'realm', 'component - like LDAP provider' .. is there some generic for it?

As also stated in issue #5 there is currently no support in the library to create a new REALM using the API. However you can for now create one using the Keycloak Admin (https://www.keycloak.org/docs/latest/server_admin/index.html#_create-realm). Support for REALM creation can be build in the Realms client (keycloak.admin.realm.Realms).

some methods in your project have as parameter 'token' ... Could you please explain why it's necessary to pass client into the methods? I thought that token is obtained/refreshed by default according the settings/credentials for realms object / oaidc_client. Why is necessary put token directly into method?

I am not entirely sure about your question but I think you mean: why do you have to supply a token when the library has all the tools to authenticate and refresh a given Access token?
I've chosen to create a set_token method in order to be able to keep the token storage in your own implementation. In most of the cases an access_token get stored in a database and need a refresh now and then, this new access_token need to get updated in the database. To support this you are able to pass a callable to the this set_token method. You can find an implementation in my Django Keycloak app (https://github.com/Peter-Slump/django-keycloak/blob/master/src/django_keycloak/services/client.py#L54) which does exactly this.
In that app I've created a function which returns an active access_token once the access_token is expired a fresh token get retrieved, stored in the database and returned. It looks something like this:

def get_access_token(client):
    """
    Get access token from client's service account.
    :param django_keycloak.models.Client client:
    :rtype: str
    """

    oidc_profile = get_service_account_profile(client=client)

    try:
        return django_keycloak.services.oidc_profile.get_active_access_token(
            oidc_profile=oidc_profile)
    except TokensExpired:
        token_reponse, initiate_time = get_new_access_token(client=client)
        oidc_profile = django_keycloak.services.oidc_profile.update_tokens(
            token_model=oidc_profile,
            token_response=token_reponse,
            initiate_time=initiate_time
        )
        return oidc_profile.access_token

And the client get authenticated by passing this method using the functools.partial:

def get_admin_client(client):
    """
    Get the Keycloak admin client configured for given realm.

    :param django_keycloak.models.Client client:
    :rtype: keycloak.admin.KeycloakAdmin
    """
    token = partial(get_access_token, client)
    return client.realm.realm_api_client.admin.set_token(token=token)

In that way you always have a fresh access_token which get stored in the database of the implementing application.

If you don't need al this fancy stuff you can also pass an active access_token as string to the set_token method.

how can I obtain the token .. there is 'client_credentials' method but returns more than access_token. ... so I would like to know what is correct way for using e.g. 'userinfo(token)' ...

Next to the access_token the client_credentials method returns a refresh-, identity token and also details about the expiration of the acces token. The refresh token can be used to get a new access token once the previous one is expired. Please read more about the OIDC authentication flows here: https://www.keycloak.org/docs/latest/server_admin/index.html#_oidc-auth-flows and here: https://openid.net/connect/

should I call 'client_credentials' first and parse 'access_token' from respnose... and than use this 'access_token' as token for userinfo method? Am I right or is there better/straightforward way how to do it?

Yes that's the way to do it :) To make it even better, you have to refresh the access_token now and then using the refresh token.

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