OpenID Connect Logout Options with Spring Boot

OpenID Connect Logout Options with Spring Boot

This tutorial demonstrates the logout options you have when developing Spring applications and helps you pick the right one for you!

Soumya D

I am getting below issue with same code, please help:

Field clientRegistrationRepository in com.test.spring.okta.sso.SecurityConfiguration required a bean of type ‘org.springframework.security.oauth2.client.registration.ClientRegistrationRepository’ that could not be found.

The injection point has the following annotations:

- @org.springframework.beans.factory.annotation.Autowired(required=true)

The following candidates were found but could not be injected:

- Bean method ‘clientRegistrationRepository’ in ‘OAuth2ClientRegistrationRepositoryConfiguration’ not loaded because OAuth2 Clients Configured Condition registered clients is not available

I am trying to implement a custom logoutSuccessHandler that logs the logout:

@Component
public class myLogoutHandler extends SimpleUrlLogoutSuccessHandler {
    @Value( "${okta.oauth2.postLogoutRedirectUri}" )
    private String postLogoutRedirectUri;

    @PostConstruct
    public void init() {
        logger.info(postLogoutRedirectUri);
        super.setDefaultTargetUrl(postLogoutRedirectUri);
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        if (authentication != null) {
            logger.info("Logging out user " + authentication.getPrincipal().toString() );
        } else {
            logger.info("Logout after session expiration");
        }
        super.onLogoutSuccess(request, response, authentication);
    }
}

I Autowire this in the SpringSecurityConfig and set it as the logoutSuccessHandler:

    @Autowired
    private myLogoutHandler logoutSuccessHandler;

...

            .and().logout().logoutSuccessHandler(logoutSuccessHandler)

The Component is properly configured with my redirectURL (I see the log entry), and when I submit a form with action “/logout”, I get logged out, but there is no log entry. Several questions:

  1. What am I doing wrong?
  2. Is there an easier way to do this?
  3. Am I breaking my security by not using OidcClientInitiatedLogoutSuccessHandler? I can’t subclass it because it is final, but I can probably figure out a way to get around that.

OK, the correct answer is #2, there is an easier way to do this:

@Component
public class myLogoutHandler implements LogoutHandler {
    private static final Logger log = LogManager.getLogger(myLogoutHandler.class);
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        if (authentication != null) {
            String username = "unknown";
            if (authentication.getPrincipal() instanceof UserDetails) {
                UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
                username = springSecurityUser.getUsername();
            } else if (authentication.getPrincipal() instanceof DefaultOidcUser) {
                DefaultOidcUser user = (DefaultOidcUser) authentication.getPrincipal();
                username = user.getName();
            } else if (authentication.getPrincipal() instanceof String) {
                username =  (String) authentication.getPrincipal();
            }
            log.info("Logging out user " + username );
        } else {
            log.info("Logout after session expiration");
        }        
    }
}

And in SpringSecurityConfig:

           .addLogoutHandler(logoutHandler)

Hi @jeffemandel!

I’m not sure I’m following the question and example correctly, so I’ll try to fill in some background, but if I missed the mark or didn’t answer your question, please let me know.

As mentioned in the blog post there are two different ways to “log out” of an OIDC application.

  1. Log out of just the application (this is the default behavior)
  2. Log out of the application AND from the IdP.

The 2nd option will log out of ALL applications, so if you are doing some sort of SSO, or social login, this might not be what you want.

I like to think about the two options similar to a social auth, think about how you could “Login with GitHub” to a 3rd party application. The 3rd party application wouldn’t be allowed to log you out of GitHub, but you could still log out of that 3rd party application.

If you only have a single application, then you may want to log out of the IdP as well

It’s not clear what your myLogoutHandler does other than ad a log message?

A quick note about logging, Spring Security’s log is sparse by default, if you need more info you would need to turn up the log levels under org.springframework.security.

Can you describe your use case a bit more, maybe I can give more specific advice?