All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.c4_soft.springaddons.security.oidc.starter.SpringAddonsOAuth2LogoutRequestUriBuilder Maven / Gradle / Ivy

There is a newer version: 8.0-RC1
Show newest version
package com.c4_soft.springaddons.security.oidc.starter;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;

import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcClientProperties;
import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcClientProperties.OAuth2LogoutProperties;

import lombok.Data;
import lombok.RequiredArgsConstructor;

/**
 * @author Jerome Wacongne ch4mp@c4-soft.com
 */
@Data
@RequiredArgsConstructor
public class SpringAddonsOAuth2LogoutRequestUriBuilder implements LogoutRequestUriBuilder {
    private static final String OIDC_RP_INITIATED_LOGOUT_CONFIGURATION_ENTRY = "end_session_endpoint";
    private static final String OIDC_RP_INITIATED_LOGOUT_CLIENT_ID_REQUEST_PARAM = "client_id";
    private static final String OIDC_RP_INITIATED_LOGOUT_ID_TOKEN_HINT_REQUEST_PARAM = "id_token_hint";
    private static final String OIDC_RP_INITIATED_LOGOUT_POST_LOGOUT_URI_REQUEST_PARAM = "post_logout_redirect_uri";

    private final SpringAddonsOidcClientProperties clientProperties;

    @Override
    public Optional getLogoutRequestUri(ClientRegistration clientRegistration, String idToken, Optional postLogoutUri) {
        final var logoutProps = clientProperties.getLogoutProperties(clientRegistration.getRegistrationId());
        if (!logoutProps.map(OAuth2LogoutProperties::isEnabled).orElse(true)) {
            return postLogoutUri.map(URI::toString).filter(StringUtils::hasText);
        }

        final var logoutEndpointUri = getLogoutEndpointUri(logoutProps, clientRegistration)
            .orElseThrow(() -> new MisconfiguredProviderException(clientRegistration.getRegistrationId()));

        final var builder = UriComponentsBuilder.fromUri(logoutEndpointUri);

        getIdTokenHintRequestParam(logoutProps).ifPresent(idTokenHintParamName -> {
            if (StringUtils.hasText(idToken)) {
                builder.queryParam(idTokenHintParamName, idToken);
            }
        });

        getClientIdRequestParam(logoutProps).ifPresent(clientIdParamName -> {
            if (StringUtils.hasText(clientRegistration.getClientId())) {
                builder.queryParam(clientIdParamName, clientRegistration.getClientId());
            }
        });

        getPostLogoutUriRequestParam(logoutProps).ifPresent(postLogoutUriParamName -> {
            postLogoutUri.map(URI::toString).filter(StringUtils::hasText).ifPresent(uri -> {
                builder.queryParam(postLogoutUriParamName, postLogoutUri);
            });
        });
        return Optional.of(builder.encode(StandardCharsets.UTF_8).build().toUriString());
    }

    @Override
    public Optional getLogoutRequestUri(ClientRegistration clientRegistration, String idToken) {
        return getLogoutRequestUri(clientRegistration, idToken, Optional.of(clientProperties.getPostLogoutRedirectUri()));
    }

    public Optional getLogoutEndpointUri(Optional logoutProps, ClientRegistration clientRegistration) {
        if (logoutProps.isPresent()) {
            return logoutProps.flatMap(props -> props.isEnabled() ? Optional.ofNullable(logoutProps.get().getUri()) : Optional.empty());
        }
        final var oidcConfig = clientRegistration.getProviderDetails().getConfigurationMetadata();
        return Optional.ofNullable(oidcConfig.get(OIDC_RP_INITIATED_LOGOUT_CONFIGURATION_ENTRY)).map(Object::toString).map(URI::create);
    }

    public Optional getIdTokenHintRequestParam(Optional logoutProps) {
        if (logoutProps.isEmpty()) {
            return Optional.of(OIDC_RP_INITIATED_LOGOUT_ID_TOKEN_HINT_REQUEST_PARAM);
        }
        return logoutProps.get().getIdTokenHintRequestParam();
    }

    public Optional getClientIdRequestParam(Optional logoutProps) {
        if (logoutProps.isEmpty()) {
            return Optional.of(OIDC_RP_INITIATED_LOGOUT_CLIENT_ID_REQUEST_PARAM);
        }
        return logoutProps.get().getClientIdRequestParam();
    }

    public Optional getPostLogoutUriRequestParam(Optional logoutProps) {
        if (logoutProps.isEmpty()) {
            return Optional.of(OIDC_RP_INITIATED_LOGOUT_POST_LOGOUT_URI_REQUEST_PARAM);
        }
        return logoutProps.get().getPostLogoutUriRequestParam();
    }

    static final class MisconfiguredProviderException extends RuntimeException {
        private static final long serialVersionUID = -7076019485141231080L;

        public MisconfiguredProviderException(String clientRegistrationId) {
            super(
                "OAuth2 client registration for %s RP-Initiated Logout is missconfigured: it is neither OIDC complient nor difiend in spring-addons properties"
                    .formatted(clientRegistrationId));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy