Keycloak 18.0.2 problem with post_logout_redirect_url and missing id_token_hint - keycloak

We have a keycloak instance running which received an update from 15 to 18.0.2.
According to the specs
https://openid.net/specs/openid-connect-rpinitiated-1_0.html
There is a RECOMMENDED id_token_hint which should be provided along the post_logout_redirect_uri parameter to avoid unauthorized logout from other sources. But it seems not mandatory.
However, since its complicated in our case to get the token id after application logout, we decided to not provide the id_token_hint but let the user click on the logout form that appears when no id_token_hint is provided and redirect them afterwards.
But it seems not to work with
http://keycloak.host/realms/test_realm/protocol/openid-connect/logout?post_logout_redirect_uri=https%3A%2F%2Ftest.redirect.com%2F&state=123be78239823baa239328ef&scope=profile%20email&response_type=code&approval_prompt=auto&client_id=test-client
The error is
Missing parameters: id_token_hint
Like mentioned, we don't have the id_token here we could provide.
Strange is, that on another keycloak instance, the url is working correctly and the prompt appears. Unfortunately we can't find any difference in config. Is there some config in keycloak which will influence the described behavior somehow?
Any other ideas?

Related

Keycloak 18.0.2 get id_token_hint for logout url by the API call

Is it possible with Keycloak 18 to get id_token_hint value, required for logout url via direct API call to the Keycloak server? If so, could you please show how?
Also, is this safe to keep id_token_hint value on the client side, let's say in JWT claim?
I am not sure if I fully understood your question, nonetheless from the OpenID Connect standard (section 2.RP-Initiated Logout) one can read:
This specification defines the following parameters that are used in
the logout request at the Logout Endpoint:
id_token_hint RECOMMENDED. ID Token previously issued by the OP to the
RP passed to the Logout Endpoint as a hint about the End-User's
current authenticated session with the Client. This is used as an
indication of the identity of the End-User that the RP is requesting
be logged out by the OP.
So you need to pass id_token_hint=<id_token>. You get the id token by calling the token endpoint with the scope=openid. For example, when a user logs in via browser if you request includes the scope=openid you will get (along with the refresh and access tokens) the user id token.
Not the best option, but works, and you dont need id_token_hint
when start keycloak add the following parameter to the command line:
kc.sh start --spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true
Still have to confirm the logout when you call logout page,but you can use redirect_uri in the old way.
https://keycloak.lvh.me/realms/airports/protocol/openid-connect/logout?redirect_uri=https%3A%2F%2Foauth2.lvh.me%2Foauth2%2Fsign_out

SSO authorization in Directus using the keycloak provider

Good afternoon, how can I set up sso authorization from keycloak in my directus application? Below I will give the settings for my directus image. And the error that occurs when trying to log into the account.
So I ran into this the other day and redirect_uri is picked up from the PUBLIC_URL environment variable, which should be set as well. So you may wish to ensure this is set. You may also want to consider making your root url and base url simply http://localhost:8055 and making /* your valid redirect url, and narrow it down from there.

What is the proper way to invoke Keycloak's end_session_endpoint

Environment: Keycloak 12.0.4
We plan to allow various OpenIDC-protected applications to initiate a "single sign-out" using Keycloak's end_session_endpoint. In our case, we'd like to provide our own URL that applications will hit when they want to sign-out. That URL will either programmatically invoke the end_session_endpoint or simply redirect the user's browser to that endpoint.
The Keycloak documentation and examples I've seen so far are a bit confusing regarding how to invoke this endpoint. For example, do I need to add a query parameter with the id token as a value? (I noticed, for example, that mod_auth_openidc includes an id_token_hint query param.) I assume this call has to be authenticated, so do I include the client id/secret as the credentials?
Thanks!
You have standard how to call RP-Initiated Logout:
https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout
An RP requests that the OP log out the End-User by redirecting the End-User's User Agent to the OP's Logout Endpoint.
It is a redirect, not API call, because you very likely wants to delete also IDP session (cookies on used Keycloak domain in your case).
Here's some additional information from the keycloak-user group which I think completely answers the question:
You can look at
https://openid.net/specs/openid-connect-session-1_0-17.html#RPLogout.
From our implementation, we rely on either cookies or the
id_token_hint to identify the user and logout sessions. So you don't
necessarily need to send id_token_hint if cookies are sent when
redirecting the user from your application to Keycloak. You can also
send a state param to match if the logout action sent to your
application originated from a valid logout request.
Note, however, that we don't force the id_token_hint and do not ask
the user for confirmation, as per spec. But there are discussions to
introduce a consent page.
In regards to logout, messages are sent to clients through the
backchannel.
Edit: Here's the actual (latest) RP-initated logout spec: https://openid.net/specs/openid-connect-rpinitiated-1_0.html.
The logout URL needs to be build from
the OpenID Connect end session endpoint
a target redirect URI where the user should be sent after logout, provided as query param post_logout_redirect_uri
The encoded ID token as query param id_token_hint
In Spring it can be built like this:
String logoutLink = UriComponentsBuilder.fromUri(endSessionEndpoint)
.queryParam("post_logout_redirect_uri", logoutUrlEncoded)
.queryParam("id_token_hint",
((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue())
.build().toUriString();

Keycloak Silent Authentication

I have a react app that uses Keycloak endpoint token_endpoint to authenticate the user. The problem I'm facing now is how to update/refresh this token. I know I could use a refresh token but that's a bad practice since has security issue when it comes to a web application. It seems to me that the best approach would be to use Silent Authentication.
Unfortunately, I couldn't find any example or documentation that allows me to achieve this. In case you guys have another approach I'm open to suggestions.
Tks
It would consist just of providing the prompt=none parameter on the authentication request as stated in the OpenID Connect 1.0 Core spec:
https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
prompt OPTIONAL.
Space delimited, case sensitive list of ASCII string
values that specifies whether the Authorization Server prompts the
End-User for reauthentication and consent. The defined values are:
none
The Authorization Server MUST NOT display any authentication or
consent user interface pages. An error is returned if an End-User is
not already authenticated or the Client does not have pre-configured
consent for the requested Claims or does not fulfill other conditions
for processing the request. The error code will typically be
login_required, interaction_required, or another code defined in
Section 3.1.2.6. This can be used as a method to check for existing
authentication and/or consent.
Authenticate to obtain an access_token with /auth (prompt=login).
Just call OIDC /token with grant_type=refresh_token to refresh token with the access_token. the new response include access_token, refresh_token and so.
After that you must update them for the new api calls.

Jasig CAS: Remember Me

I've a strange problem with with my installation of CAS.
Recently we activated the RememberMe functionality with a 3-Month validity of the ticket on RememberMe.
When the session of my client application expires I got sent back to CAS at
https://urlOfmyCas/login?service=urlOfClient
Even though the CASTGC cookie is there and valid CAS is showing me again the login page.
If I invoke the URL above without service parameter I get redirected to the "Login-Success" page, so CAS knows that I'm logged in.
I would expect CAS to check the cookie log me in and send me back to my client application unless i send the renew parameter.
Did I mess up something in my CAS installation or is this an expected behaviour
Today finally it seems like I found the answer.
CAS is creating a long-term-ticket with validity 3 months (no matter what you specify as expiration timeout in your ticketExpirationPolicies.xml). The value specified in the documentation for rememberMeExpirationPolicy is for the ticketCleaner only. So even if the cookie is still there the cleaner could potentially already have dismissed the TGT in the ticket registry.
If you call /login without service parameter, the system only checks if there is a TGTid in the cookie without checking the ticket registry, so thats why it shows the success-login page, which confused me a bit.
What put me into trouble is that I assumed that the expiration values used in org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy are in SECONDS too (like it is in the default configuration), however this class needs the values as MILLISECONDS.
I should have checked that, but as I tried to set it to 3 months and the ticket has a 3 month validity (so I thought to get what I want), together with the strange behaviour mentioned in the paragraph above... My mistake in the end.