I’m trying to get a grasp on how to logout from a java adapter. Currently what I do is to call the endpoint https://localhost:8444/realms/test/protocol/openid-connect/logout and then I get a logout confirmation page.
First question: how can I bypass that? to not be shown and go directly to the logout page?
In my setup I have a client with minimal setup, that all the information are loaded in the application from the well-known endpoint (so no java deployment and I will want to not change that).
— Next part is more fore understanding purpose & hopefully to clarify some stuff for others too—
Secondly when it comes to the documentation I didn’t find very good examples of how to do the frontend logout or backend logout? (I suppose the backend logout makes sense when you write the Java adapter and call the Keycloak class with the logout function. Right?)
And frontend logout is something that you probably have in a React/Angular application as js adapter?
So if that is the case, none of this solutions will fit my use case to just use the openid-connect and not extend the application, right?
Hello,
Keycloak recently changed the logout behavior as documented in this blog post on Keycloak 18.0.0.
You now have to provide additonal URL parameters when you invoke the endsession endpoint:
https://www.keycloak.org/docs/latest/server_admin/#_oidc-logout
-
id_token_hint
= idtoken received by your client
-
post_logout_redirect_uri
= url where you want to go after logout
For example in some SPAs that use keycloak.js I provide the required URL parameters as follows:
// workaround for changes with oidc logout in Keycloak 18.0.0
// See https://www.keycloak.org/docs/latest/upgrading/index.html#openid-connect-logout
keycloak.createLogoutUrl = function(options) {
return keycloak.endpoints.logout()
+ '?id_token_hint=' + keycloak.idToken
+ '&post_logout_redirect_uri=' + encodeURIComponent(window.location.href);
}
Cheers,
Thomas
4 Likes
Thank you for the response. I’ve seen that, but in our case I’m not sure that it will work. We are using Pega and there you have just a configuration where you can put an URL, so the extra data like id_token_hint
we cannot dynamically calculate (I think …or is there a way?).
You have to obtain a token first, but in token request, set “scope” parameter as “openid”.
The token format will be
{
“access_token”: “xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”,
“expires_in”: 600,
“refresh_expires_in”: 0,
“token_type”: “Bearer”,
“id_token”: “xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”,
“not-before-policy”: 1597246820,
“scope”: “openid”
}
Use “id_token” as “id_token-hint” in your logout url parameter.
I got a nice hint from this page: keycloak-documentation/logout.adoc at main · keycloak/keycloak-documentation · GitHub. Instead of using the id_token_hint
and directly getting redirected to the url from post_logout_redirect_uri
. You can also set client_id
. In this case the user has to press the Logout button on the Keycloak page, but you can skip all of that token passing.
1 Like
Hello.
We use the version 18.0.2.
Trying to logout by opening the address (from our NextJS app by router): https://ourkeycloak/realms/myrealm/protocol/openid-connect/logout?id_token_hint=eyJhbG&post_logout_redirect_uri==http%3A%2F%2F127.0.0.1%3A3000%2Flogin%2F
Redirect URI also listed
(the address is unimportant, even if the localhost is any other specified in the list of redirects, the error will be the same)
We get an error: Invalid redirect uri
Can you please tell me, maybe there are some parameters or settings missing?
Thank you in advance
P.S
we have the id_token in the client. therefore we know it and transmit it correctly
In case you are working with Spring boot, here is a snipet that does exactly that:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class KeycloakWebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(
HttpSecurity http,
ClientRegistrationRepository clientRegistrationRepository) throws Exception {
http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated());
http.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()));
return http.build();
}
private LogoutSuccessHandler oidcLogoutSuccessHandler(ClientRegistrationRepository clientRegistrationRepository) {
OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler =
new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
// Sets the location that the End-User's User Agent will be redirected to
// after the logout has been performed at the Provider
oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
return oidcLogoutSuccessHandler;
}
}