I am building a simple http classic web application (request-response) in Clojure in orden to test the integration with Keycloak identity server.
I am ussing ring-oauth2 library, following the steps described in library documentation.
Here is the initialization of my app
(defn app-routes []
(ring/router
[["/"
{:get {:handler (fn [request]
(response-handler request views/home-page))}}]]))
(defn wrap-site-defaults [handler]
(ring.middleware.session/wrap-defaults handler (-> ring.middleware.defaults/site-defaults (assoc-in [:session :cookie-attrs :same-site] :lax)))
(defn wrap-oauth2-config [handler]
(wrap-oauth2
handler
{:keycloak
{:client-id "my-app"
:client-secret "***********"
:authorize-uri "http://localhost:8080/realms/my-realm/protocol/openid-connect/auth"
:access-token-uri "http://localhost:8080/realms/my-realm/protocol/openid-connect/token"
:redirect-uri "http://localhost:3300/oauth2/callback"
:scopes ["openid" "profile" "email"]
:launch-uri "/login"
:landing-uri "/"}}))
(defn -main []
(let [handler (-> (ring/ring-handler (app-routes))
(wrap-oauth2-config)
(wrap-site-defaults)
(ring.middleware.params/wrap-params))]
(run-jetty handler {:port 3300 :join? false})
(println "Server started on port 3300")))
After run the app and git the endpoint http://localhost:3300/login
the authenticate process is completed in Keycloak but after the redirection to home page the key :oauth2/access-tokens
is not present in the request.
What mistake could I be making? Am I missing some configuration, middleware? Is the order in which I have the middlewares correct?
After a lot of tests and find a great repo as example (Booklog) i fix my problem
First: Use only ["profile" "email"] scopes inside oauth2 configuration
Second: Use "/oauth2/done" as landing-uri instead of "/". With this I have managed to decode the access token and build an identity key (:identity) and associate it with the current session.
Third: correct the order of middlewares
Aquí comparto como ha quedado mi código
(defn app-routes []
(ring/router
[["/"
{:get {:handler (fn [request]
(response-handler request views/home-page))}}]
["/oauth2/done"
{:get {:handler (fn [request]
(let [identity (fetch-identity (get-in request [:oauth2/access-tokens :keycloak :token]))
next-session (assoc (:session request) :identity identity)]
(-> (redirect "/")
(assoc :session next-session))))}}]
["/logout"
{:get {:handler (fn [_]
{:status 302
:headers {"Location" "http://localhost:8080/realms/my-realm/protocol/openid-connect/logout?client_id=my-clientb&post_logout_redirect_uri=http://localhost:3300"}
:session nil})}}]]))
(defn wrap-oauth2-config [handler]
(wrap-oauth2
handler
{:keycloak
{:client-id "my-client"
:client-secret "************"
:authorize-uri "http://localhost:8080/realms/my-realm/protocol/openid-connect/auth"
:access-token-uri "http://localhost:8080/realms/my-realm/protocol/openid-connect/token"
:redirect-uri "http://localhost:3300/oauth2/callback"
:scopes ["profile" "email"]
:basic-auth? true
:launch-uri "/login"
:landing-uri "/oauth2/done"}}))
(defn -main []
(let [handler (-> (ring/ring-handler (app-routes))
(wrap-authentication (backends/session))
(wrap-session)
(auth/wrap-oauth2-config)
(wrap-defaults (-> site-defaults
(assoc-in [:session :cookie-attrs :same-site]
:lax))))]
(run-jetty handler {:port 3300 :join? false})
(println "Server started on port 3300")))