p2-inc / keycloak-events

Useful Keycloak event listener implementations and utilities.
https://phasetwo.io
Other
194 stars 37 forks source link

Simple tutorial to start p2-inc/keycloak-events with http sender #70

Closed adrian-moisa closed 2 months ago

adrian-moisa commented 2 months ago

I'm trying to use the official phasetwo keycloak docker image. Sadly the main readme is really terse and hard to figure out. Also could not find any tutorial online. Tried to look trough all the issues of the repo to find code samples.

What I understand so far:

Start p2 KC:

docker run -dt --name sys-auth-events \
-p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=“1234” \
-e KC_DB=postgres \
-e KC_DB_URL_HOST=host.docker.internal \
-e KC_DB_URL_PORT=5432 \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_USERNAME=postgres \
-e KC_DB_PASSWORD="1234" \
-e KC_HEALTH_ENABLED=true \
-e KC_METRICS_ENABLED=true \
-e QUARKUS_HTTP_ACCESS_LOG_ENABLED=true \
quay.io/phasetwo/phasetwo-keycloak:latest start-dev
image

I saw the readme there. However I assume since I'm not changing anything except config there's no need for me to upload custom jars.

image

I understand that the next step would be to create a new realm and provide the following json as config.

{
  "id": "demo",
  "realm": "demo",
  "attributes": {
    "_providerConfig.ext-event-http": "{\"targetUri\": \"https://demo.api/endpoint-to-be-called-by-kc\"}"
  }
}

Also in realm settings / events / i need to enable ext-event-http

image

I also saw in one of the repo issues mention about this URLs: (note I've installed KC at 8081 and at root level, I don't need -e KC_HTTP_RELATIVE_PATH=/auth)

http://localhost:8081/realms/demo/events
http://localhost:8081/realms/demo/attributes

Not sure what these do. Or if I need them for http sender. So far this is what I see when visiting them. Which is not the same as "not found"

image

I'm not interested in webhooks. Though probably for people interested in webhooks a beginner level tutorial would make much difference.

Given all the above, am I missing smth out? Any help will be appreciated. Thank you!

xgp commented 2 months ago

@adrian-moisa You've figured most of it out. You just need to store your configuration as a Realm attribute. This can be done using the Keycloak API to get the realm, and then put an update that includes your new attribute as part of the array. The "key" for that attribute is _providerConfig.ext-event-http and the value is the configuration object, e.g. {"targetUri":"https://demo.api/endpoint-to-be-called-by-kc"}

Keycloak doesn't make it easy to CRUD individual attributes, so the endpoint you found (http://localhost:8081/realms/demo/attributes) is a convenience we built for managing individual attributes. More documentation is here https://phasetwo.io/api/category/attributes/

adrian-moisa commented 2 months ago

Thanks @xgp for the quick answer! Looks like KC folks had a discussion about adding an admin GUI for realm attributes. Too bad nothing was released yet. https://github.com/keycloak/keycloak/discussions/23678 . I'll see what I can achieve this evening and update you if anything clicks.

adrian-moisa commented 2 months ago

Will renaming a test account in admin trigger an event that will be relayed by the http sender?

Edit To get the token you need to create a backend client in kc (took inspiration from #5 )

image

Calling the token EP will generate an user event

adrian-moisa commented 2 months ago

Following advice from here https://github.com/p2-inc/keycloak-events/issues/5 I was able to get the access token and run the attributes GET endpoint. However the events is a POST and I have no idea what to use for body. I cheked the attributes property and it looks ok afaik.

image

Still not able to see any calls from KC to my users api. There were plenty of login events to be relayed to my custom endpoint.

image

Edit Think I found the problem: I configured https instead of http. I designed the ep as http because it's internal in the k8s cluster. Not public.

image

Edit2 I think I still have a kc pod to localhost api connectivity issue (some wrong address or smth)

adrian-moisa commented 2 months ago

There we go! Party time! 🎉🥳 This did the trick http://host.docker.internal:12100/v1/users/events. Had to contact localhost from within docker.

image

Damn that took some wrestling to get it done :D

xgp commented 2 months ago

Thank you for your persistence! If you have the time to write up the steps you took, I’d be pleased to put it in the README.

Also, if you are using the Phase Two docker image, and have turned on the phasetwo.v2 admin theme, there is an “Attributes” tab in the “Realm Settings” that you can use to view and set Realm attributes.

adrian-moisa commented 2 months ago

I tried enabling it, but I don't see this Attributes tab. I even tried restarting the container in docker to make sure the theme is selected. Maybe I'm doing smth wrong.

image

I'll try to find some time to cleanup the findings and improve the readme with a PR. Running a bit heavy now, but I'm willing to help as soon as I get some spare time.

xgp commented 2 months ago

You have to log out and log back in. Also, if you are logging into master and then switching to another realm, you need to set it as the "Admin theme" for master.

adrian-moisa commented 2 months ago

Indeed it works, I see the tab. Thanks for the hint! Though I have some reservation over the idea of overriding all realms at once. I use a separate realm from master for my app. And potentially will have more realms later. I'd prefer to customise one by one.

xgp commented 2 months ago

overriding all realms at once

What I suggested doesn't override all realms. This is how themeing works in Keycloak. It activates the admin theme for the realm user you are logged in as. If you create an account with admin roles in your target realm and log in to that console (e.g. https://myauth.com/auth/admin/some-other-realm/console/, it will use whatever admin theme you have set up for that realm.

IMHO, it is a bad practice to use the master for anything other than creating new realms and admin accounts. Using the master realm is a big security problem, and it leads to lots of confusion like this.

adrian-moisa commented 2 months ago

Oh I see, it makes sense!

adrian-moisa commented 2 months ago

Tbh, I'm still having a little bit of trouble understanding what exactly is different between http sender and webhooks. They both seem to use http and seem to be initiated by the server, targeting an API provider by the user. I'm finding contradicting bits and pieces of info. All I can say as a diff is that webhooks are more flexible as they allow multiple systems to receive events without changing the sender's configuration.

xgp commented 2 months ago

They are similar. Webhooks gives you the ability to filter by type of event, and there is an API to create webhooks. You can give a user or service account the view-events and manage-events roles, which will give them the ability to create webhooks, where a user must have manage-realm role to set Realm Attributes.

All I can say as a diff is that webhooks are more flexible as they allow multiple systems to receive events without changing the sender's configuration.

Yes!

adrian-moisa commented 2 months ago

Was wondering, is there a way to subscribe the http sender only to certain types of events? For example right now I want only the type: REGISTER. I see token introspection as well and that one could flood my target endpoint. Thanks for the support so far!

xgp commented 2 months ago

Webhooks allow filtering by type, but the standard HTTP sender does not.