org.gluu.oxtrust.ldap.service.AppInitializer.java Source code

Java tutorial

Introduction

Here is the source code for org.gluu.oxtrust.ldap.service.AppInitializer.java

Source

/*
 * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.gluu.oxtrust.ldap.service;

import java.net.URISyntaxException;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

import org.apache.commons.configuration.ConfigurationException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.codehaus.jackson.map.ObjectMapper;
import org.gluu.oxtrust.config.OxTrustConfiguration;
import org.gluu.oxtrust.ldap.cache.service.CacheRefreshConfiguration;
import org.gluu.oxtrust.model.GluuAppliance;
import org.gluu.oxtrust.model.GluuOrganization;
import org.gluu.oxtrust.model.GluuSAMLTrustRelationship;
import org.gluu.oxtrust.model.OxIDPAuthConf;
import org.gluu.oxtrust.model.RegistrationConfiguration;
import org.gluu.oxtrust.model.scim.ScimCustomAttributes;
import org.gluu.oxtrust.util.OxTrustConstants;
import org.gluu.oxtrust.util.Version;
import org.gluu.site.ldap.OperationsFacade;
import org.gluu.site.ldap.persistence.LdapEntryManager;
import org.gluu.site.ldap.persistence.exception.EntryPersistenceException;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
import org.jboss.seam.log.Log;
import org.xdi.config.oxtrust.ApplicationConfiguration;
import org.xdi.exception.OxIntializationException;
import org.xdi.model.SimpleProperty;
import org.xdi.model.ldap.GluuLdapConfiguration;
import org.xdi.oxauth.client.OpenIdConfigurationClient;
import org.xdi.oxauth.client.OpenIdConfigurationResponse;
import org.xdi.oxauth.client.OpenIdConnectDiscoveryClient;
import org.xdi.oxauth.client.OpenIdConnectDiscoveryResponse;
import org.xdi.oxauth.client.uma.MetaDataConfigurationService;
import org.xdi.oxauth.client.uma.UmaClientFactory;
import org.xdi.oxauth.model.uma.MetadataConfiguration;
import org.xdi.service.PythonService;
import org.xdi.service.ldap.LdapConnectionService;
import org.xdi.util.StringHelper;
import org.xdi.util.properties.FileConfiguration;
import org.xdi.util.security.PropertiesDecrypter;

/**
 * Perform startup time initialization. Provides factory methods for non Seam
 * components.
 * 
 * @author Yuriy Movchan
 */
@Startup(depends = "oxTrustConfiguration")
@AutoCreate
@Scope(ScopeType.APPLICATION)
@Name("appInitializer")
public class AppInitializer {

    // We are going to start connection checker every 120 seconds
    public static final long CONNECTION_CHECKER_INTERVAL = (long) (1000L * 60 * 2);
    // We are going to start status checker every 60 seconds
    public static final long STATUS_CHECKER_INTERVAL = (long) (1000L * 61 * 1);
    // We are going to start svn synchronization every 5 minutes
    public static final long SVN_SYNC_INTERVAL = (long) (1000L * 62 * 5);

    private static final long VALIDATION_INTERVAL = (long) (1000L * 63 * 1);
    private static final long LOG_MONITOR_INTERVAL = (long) (1000L * 60 * 64 * 24);

    // Group count and person count will now be checked daily
    public static final long STATUS_CHECKER_DAILY = (long) (1000L * 60 * 65 * 24);

    @Logger
    private Log log;

    @In
    private SvnSyncTimer svnSyncTimer;

    @In
    private StatusCheckerTimer statusCheckerTimer;

    @In
    private StatusCheckerDaily statusCheckerDaily;

    @In
    private MetadataValidationTimer metadataValidationTimer;

    @In
    private LogFileSizeChecker logFileSizeChecker;

    @In
    private OxTrustConfiguration oxTrustConfiguration;

    private GluuLdapConfiguration ldapConfig;

    /**
     * Initialize components and schedule DS connection time checker
     */
    @Create
    public void createApplicationComponents() throws ConfigurationException {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }

        log.debug("Creating application components");
        showBuildInfo();

        // Initialize local LDAP connection provider
        createConnectionProvider(oxTrustConfiguration.getLdapConfiguration(), "localLdapConfiguration",
                "connectionProvider");

        Events.instance().raiseEvent(OxTrustConfiguration.EVENT_INIT_CONFIGURATION);

        // Initialize central LDAP connection provider

        if (oxTrustConfiguration.getApplicationConfiguration().isUpdateApplianceStatus()) {
            createConnectionProvider(oxTrustConfiguration.getLdapCentralConfiguration(), "centralLdapConfiguration",
                    "centralConnectionProvider");
        }
        initializeLdifArchiver();
        initiateLDAPAuthConf();

        // Initialize template engine
        TemplateService.instance().initTemplateEngine();

        // Initialize SubversionService
        SubversionService.instance().initSubversionService();

        // Initialize python interpreter
        PythonService.instance().initPythonInterpreter();

        //      checkAndUpdateLdapbaseConfiguration(); // We do not need to create ldapbase configuration any more because we 
        //supply working ldap data with either dashboard or python setup sript.

        startInviteCodesExpirationService();

        startStatusChecker();
        startDailyStatusChecker();
        startSvnSync();
        // Asynchronous metadata validation service
        startMetadataValidator();

        createShibbolethConfiguration();

        prepareConfigurations();

        logSizeChecker();
    }

    private void startInviteCodesExpirationService() {
        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 60);
        GluuOrganization org = OrganizationService.instance().getOrganization();
        RegistrationConfiguration config = org.getOxRegistrationConfiguration();
        boolean accountsTimeLimited;
        long linksExpirationFrequency;
        long accountsExpirationServiceFrequency;
        if (config != null) {
            log.debug("OxRegistrationConfiguration found. Trying to get the custom expiration configuration");
            try {
                linksExpirationFrequency = Long.parseLong(config.getLinksExpirationFrequency());
                accountsExpirationServiceFrequency = Long.parseLong(config.getAccountsExpirationServiceFrequency());
                accountsTimeLimited = config.isAccountsTimeLimited();
            } catch (NumberFormatException e) {
                log.debug("OxRegistrationConfiguration malformed. Resorting to the default values");

                linksExpirationFrequency = RegistrationsExpirationService.instance()
                        .getDefaultLinksExpirationFrequency();
                accountsExpirationServiceFrequency = RegistrationsExpirationService.instance()
                        .getDefaultAccountsExpirationServiceFrequency();
                accountsTimeLimited = false;
            }
        } else {
            log.debug("OxRegistrationConfiguration missing. Resorting to the default values");
            linksExpirationFrequency = RegistrationsExpirationService.instance()
                    .getDefaultLinksExpirationFrequency();
            accountsExpirationServiceFrequency = RegistrationsExpirationService.instance()
                    .getDefaultAccountsExpirationServiceFrequency();
            accountsTimeLimited = false;
        }
        log.debug("OxRegistrationConfiguration parsed: linksExpirationFrequency: " + linksExpirationFrequency
                + ", accountsExpirationServiceFrequency: " + accountsExpirationServiceFrequency
                + ", accountsTimeLimited: " + accountsTimeLimited);

        RegistrationsExpirationService.instance().expireLinks(calendar.getTime(), linksExpirationFrequency);
        if (accountsTimeLimited) {
            RegistrationsExpirationService.instance().expireUsers(calendar.getTime(),
                    accountsExpirationServiceFrequency);
        }

    }

    private void createConnectionAuthProvider(String configurationLdapConfigComponentName, String fileName,
            String configurationComponentName, String connectionProviderComponentName) {
        FileConfiguration configuration = new FileConfiguration(fileName);
        Contexts.getApplicationContext().set(configurationComponentName, configuration);

        //
        Properties properties = configuration.getProperties();
        if (this.ldapConfig != null) {
            Contexts.getApplicationContext().set(configurationLdapConfigComponentName, this.ldapConfig);

            properties.setProperty("servers", buildServersString(this.ldapConfig.getServers()));
            properties.setProperty("bindDN", this.ldapConfig.getBindDN());
            properties.setProperty("bindPassword", this.ldapConfig.getBindPassword());
            properties.setProperty("useSSL", Boolean.toString(this.ldapConfig.isUseSSL()));
        }
        //

        LdapConnectionService connectionProvider = new LdapConnectionService(PropertiesDecrypter
                .decryptProperties(properties, oxTrustConfiguration.getCryptoConfiguration().getEncodeSalt()));
        Contexts.getApplicationContext().set(connectionProviderComponentName, connectionProvider);
    }

    private String buildServersString(List<SimpleProperty> servers) {
        StringBuilder sb = new StringBuilder();

        if (servers == null) {
            return sb.toString();
        }

        boolean first = true;
        for (SimpleProperty server : servers) {
            if (first) {
                first = false;
            } else {
                sb.append(",");
            }

            sb.append(server.getValue());
        }

        return sb.toString();
    }

    private void startMetadataValidator() {

        // Schedule first check after 60 seconds
        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 60);
        metadataValidationTimer.scheduleValidation(calendar.getTime(), VALIDATION_INTERVAL);

    }

    private void prepareConfigurations() {
        CacheRefreshConfiguration cacheRefreshConfiguration = new CacheRefreshConfiguration();
        Contexts.getApplicationContext().set("cacheRefreshConfiguration", cacheRefreshConfiguration);
    }

    private boolean createShibbolethConfiguration() {
        ApplicationConfiguration applicationConfiguration = oxTrustConfiguration.getApplicationConfiguration();
        boolean createConfig = applicationConfiguration.isConfigGeneration();
        log.info("IDP config generation is set to " + createConfig);
        if (createConfig) {
            String gluuSPInum = null;
            GluuSAMLTrustRelationship gluuSP;
            try {
                gluuSPInum = ApplianceService.instance().getAppliance().getGluuSPTR();
                gluuSP = new GluuSAMLTrustRelationship();
                gluuSP.setDn(TrustService.instance().getDnForTrustRelationShip(gluuSPInum));
            } catch (EntryPersistenceException ex) {
                log.error("Failed to determine SP inum", ex);
                return false;
            }

            boolean servicesNeedRestarting = false;
            if (gluuSPInum == null || gluuSP == null
                    || !TrustService.instance().containsTrustRelationship(gluuSP)) {
                log.info("No trust relationships exist in LDAP. Adding gluuSP");
                GluuAppliance appliance = ApplianceService.instance().getAppliance();
                appliance.setGluuSPTR(null);
                ApplianceService.instance().updateAppliance(appliance);
                TrustService.instance().addGluuSP();
                servicesNeedRestarting = true;
            }
            gluuSP = TrustService.instance()
                    .getRelationshipByInum(ApplianceService.instance().getAppliance().getGluuSPTR());

            List<GluuSAMLTrustRelationship> trustRelationships = TrustService.instance()
                    .getAllActiveTrustRelationships();
            Shibboleth2ConfService.instance().generateIdpConfigurationFiles();
            Shibboleth2ConfService.instance().generateConfigurationFiles(trustRelationships);
            Shibboleth2ConfService.instance().generateMetadataFiles(gluuSP);

            Shibboleth2ConfService.instance().removeUnusedCredentials();
            Shibboleth2ConfService.instance().removeUnusedMetadata();
            if (servicesNeedRestarting) {
                ApplianceService.instance().restartServices();
            }

        }

        return true;
    }

    private void showBuildInfo() {
        log.info("Build date {0}. Code revision {1} on {2}. Build {3}", OxTrustConstants.getGluuBuildDate(),
                OxTrustConstants.getGluuSvnRevisionVersion(), OxTrustConstants.getGluuSvnRevisionDate(),
                Version.GLUU_HUDSON_BUILDNO);
    }

    private void createConnectionProvider(FileConfiguration configuration, String configurationComponentName,
            String connectionProviderComponentName) throws ConfigurationException {
        Contexts.getApplicationContext().set(configurationComponentName, configuration);

        LdapConnectionService connectionProvider = null;
        if (configuration != null) {
            connectionProvider = new LdapConnectionService(PropertiesDecrypter.decryptProperties(
                    configuration.getProperties(), oxTrustConfiguration.getCryptoConfiguration().getEncodeSalt()));
        }
        Contexts.getApplicationContext().set(connectionProviderComponentName, connectionProvider);
    }

    /**
     * Schedule status checker
     */
    private void startStatusChecker() {
        // Schedule first check after 60 seconds
        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 60);

        statusCheckerTimer.scheduleStatusChecking(calendar.getTime(), STATUS_CHECKER_INTERVAL);
    }

    private void startDailyStatusChecker() {
        // Schedule first check after 60 seconds
        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10 * 60);

        statusCheckerDaily.scheduleStatusChecking(calendar.getTime(), STATUS_CHECKER_DAILY);
    }

    private void startSvnSync() {
        ApplicationConfiguration applicationConfiguration = oxTrustConfiguration.getApplicationConfiguration();
        if (applicationConfiguration.isPersistSVN()) {
            // Schedule first check after 60 seconds
            final Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, 60);

            svnSyncTimer.scheduleSvnSync(calendar.getTime(), SVN_SYNC_INTERVAL);
        }
    }

    /**
     * When application undeploy we need to close LDAP Connections
     * 
     * @throws org.apache.commons.configuration.ConfigurationException
     */
    @Destroy
    public void destroyApplicationComponents() throws ConfigurationException {
        log.debug("Destroying application components");
        LdapConnectionService connectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("connectionProvider");
        connectionProvider.closeConnectionPool();

        LdapConnectionService authConnectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("authConnectionProvider");
        authConnectionProvider.closeConnectionPool();

        LdapConnectionService centralConnectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("centralConnectionProvider");
        if (centralConnectionProvider != null) {
            centralConnectionProvider.closeConnectionPool();
        }
    }

    @Factory(value = "ldapEntryManager", scope = ScopeType.APPLICATION, autoCreate = true)
    public LdapEntryManager createLdapEntryManager() {
        LdapConnectionService connectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("connectionProvider");
        LdapEntryManager ldapEntryManager = new LdapEntryManager(new OperationsFacade(connectionProvider));
        log.debug("Created site LdapEntryManager: " + ldapEntryManager);

        // Initialize local LDAP Authentication connection provider
        createConnectionAuthProvider("ldapAuthConfig",
                OxTrustConstants.CONFIGURATION_FILE_LOCAL_LDAP_PROPERTIES_FILE, "localLdapAuthConfiguration",
                "authConnectionProvider");

        return ldapEntryManager;
    }

    @Factory(value = "centralLdapEntryManager", scope = ScopeType.APPLICATION, autoCreate = true)
    public LdapEntryManager createCentralLdapEntryManager() {
        LdapConnectionService centralConnectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("centralConnectionProvider");
        if (centralConnectionProvider == null) {
            return null;
        }

        LdapEntryManager centralLdapEntryManager = new LdapEntryManager(
                new OperationsFacade(centralConnectionProvider));
        log.debug("Created central LdapEntryManager: " + centralLdapEntryManager);

        return centralLdapEntryManager;
    }

    @Factory(value = "ldapAuthEntryManager", scope = ScopeType.APPLICATION, autoCreate = true)
    public LdapEntryManager createLdapAuthEntryManager() {
        LdapConnectionService connectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                .get("authConnectionProvider");
        LdapEntryManager ldapEntryManager = new LdapEntryManager(new OperationsFacade(connectionProvider, null));
        // ldapEntryManager.addDeleteSubscriber(new
        // LdifArchiver(ldapEntryManager));
        log.debug("Created site LdapAuthEntryManager: " + ldapEntryManager);

        return ldapEntryManager;
    }

    private void initializeLdifArchiver() {
        LdapEntryManager ldapEntryManager = (LdapEntryManager) Component.getInstance("ldapEntryManager");
        ldapEntryManager.addDeleteSubscriber(new LdifArchiver(ldapEntryManager));
    }

    private void logSizeChecker() {
        final Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 60);
        logFileSizeChecker.scheduleSizeChecking(calendar.getTime(), LOG_MONITOR_INTERVAL);
    }

    private Object jsonToObject(String json, Class<?> clazz) throws Exception {

        ObjectMapper mapper = new ObjectMapper();
        Object clazzObject = mapper.readValue(json, clazz);
        return clazzObject;
    }

    @Deprecated
    // Remove it after 2013/10/01
    private GluuLdapConfiguration mapLdapOldConfig(OxIDPAuthConf oneConf) {
        GluuLdapConfiguration ldapConfig = new GluuLdapConfiguration();
        ldapConfig.setServers(Arrays.asList(new SimpleProperty(oneConf.getFields().get(0).getValues().get(0) + ":"
                + oneConf.getFields().get(1).getValues().get(0))));
        ldapConfig.setBindDN(oneConf.getFields().get(2).getValues().get(0));
        ldapConfig.setBindPassword(oneConf.getFields().get(3).getValues().get(0));
        ldapConfig.setUseSSL(Boolean.valueOf(oneConf.getFields().get(4).getValues().get(0)));
        ldapConfig.setMaxConnections(3);
        ldapConfig.setConfigId("auth_ldap_server");
        ldapConfig.setEnabled(oneConf.getEnabled());
        return ldapConfig;
    }

    private GluuLdapConfiguration mapLdapConfig(String config) throws Exception {
        return (GluuLdapConfiguration) jsonToObject(config, GluuLdapConfiguration.class);
    }

    public void initiateLDAPAuthConf() {
        GluuAppliance appliance = null;

        appliance = ApplianceService.instance().getAppliance();

        if (appliance == null) {
            return;
        }

        List<OxIDPAuthConf> idpConfs = appliance.getOxIDPAuthentication();
        if (idpConfs == null) {
            log.warn(
                    "Appliance entry in database does not contain authentication configuration. Guessing local ldap.");
            idpConfs = new ArrayList<OxIDPAuthConf>();
            OxIDPAuthConf oxIDPAuthentication = new OxIDPAuthConf();
            oxIDPAuthentication.setType("ldap");
            oxIDPAuthentication.setName("Ldap authentication");
            oxIDPAuthentication.setLevel(0);
            oxIDPAuthentication.setPriority(1);
            oxIDPAuthentication.setEnabled(true);
            oxIDPAuthentication.setVersion(0);
            List<ScimCustomAttributes> fields = new ArrayList<ScimCustomAttributes>();
            ScimCustomAttributes attribute = null;
            List<String> values = null;

            LdapConnectionService connectionProvider = (LdapConnectionService) Contexts.getApplicationContext()
                    .get("connectionProvider");

            attribute = new ScimCustomAttributes();
            attribute.setName("ldapHost");
            values = Arrays.asList(connectionProvider.getServers());
            attribute.setValues(values);
            fields.add(attribute);

            attribute = new ScimCustomAttributes();
            attribute.setName("ldapPort");
            values = new ArrayList<String>();
            for (int i : connectionProvider.getPorts()) {
                values.add(Integer.toString(i));
            }
            attribute.setValues(values);
            fields.add(attribute);

            attribute = new ScimCustomAttributes();
            attribute.setName("ldapBindDn");
            values = new ArrayList<String>();
            values.add(connectionProvider.getBindDn());
            attribute.setValues(values);
            fields.add(attribute);

            attribute = new ScimCustomAttributes();
            attribute.setName("ldapBindPw");
            values = new ArrayList<String>();
            values.add(connectionProvider.getBindPassword());
            attribute.setValues(values);
            fields.add(attribute);

            attribute = new ScimCustomAttributes();
            attribute.setName("ldapUseSSL");
            values = new ArrayList<String>();
            values.add(Boolean.toString(connectionProvider.isUseSSL()));
            attribute.setValues(values);
            fields.add(attribute);

            oxIDPAuthentication.setFields(fields);
            idpConfs.add(oxIDPAuthentication);
        }

        for (OxIDPAuthConf oneConf : idpConfs) {
            if (oneConf.getType().equalsIgnoreCase("ldap")) {
                try {
                    this.ldapConfig = mapLdapOldConfig(oneConf);
                } catch (Exception ex) {
                    log.error("Failed to load LDAP authentication server connection details", ex);
                }
            } else if (oneConf.getType().equalsIgnoreCase("auth")) {
                try {
                    this.ldapConfig = mapLdapConfig(oneConf.getConfig());
                } catch (Exception ex) {
                    log.error("Failed to load LDAP authentication server connection details", ex);
                }
            }
        }
    }

    @Factory(value = "openIdConfiguration", scope = ScopeType.APPLICATION, autoCreate = true)
    public OpenIdConfigurationResponse initOpenIdConfiguration() throws OxIntializationException {
        String oxAuthIssuer = this.oxTrustConfiguration.getApplicationConfiguration().getOxAuthIssuer();
        if (StringHelper.isEmpty(oxAuthIssuer)) {
            log.info("oxAuth issuer isn't specified");
            return null;
        }

        log.debug("Attempting to determine configuration endpoint URL");
        OpenIdConnectDiscoveryClient openIdConnectDiscoveryClient;
        try {
            openIdConnectDiscoveryClient = new OpenIdConnectDiscoveryClient(oxAuthIssuer);
        } catch (URISyntaxException ex) {
            throw new OxIntializationException("OpenId discovery response is invalid!", ex);
        }

        OpenIdConnectDiscoveryResponse openIdConnectDiscoveryResponse = openIdConnectDiscoveryClient.exec();
        if ((openIdConnectDiscoveryResponse.getStatus() != 200)
                || (openIdConnectDiscoveryResponse.getSubject() == null)
                || (openIdConnectDiscoveryResponse.getLinks().size() == 0)) {
            throw new OxIntializationException("OpenId discovery response is invalid!");
        }

        log.debug("Attempting to load OpenID configuration");
        String configurationEndpoint = openIdConnectDiscoveryResponse.getLinks().get(0).getHref()
                + "/.well-known/openid-configuration";

        OpenIdConfigurationClient client = new OpenIdConfigurationClient(configurationEndpoint);

        OpenIdConfigurationResponse openIdConfiguration = client.execOpenIdConfiguration();

        if (openIdConfiguration.getStatus() != 200) {
            throw new OxIntializationException("OpenId configuration response is invalid!");
        }

        return openIdConfiguration;
    }

    @Factory(value = "umaMetadataConfiguration", scope = ScopeType.APPLICATION, autoCreate = true)
    public MetadataConfiguration initUmaMetadataConfiguration() throws OxIntializationException {
        String umaConfigurationEndpoint = getUmaConfigurationEndpoint();
        if (StringHelper.isEmpty(umaConfigurationEndpoint)) {
            return null;
        }

        MetaDataConfigurationService metaDataConfigurationService = UmaClientFactory.instance()
                .createMetaDataConfigurationService(umaConfigurationEndpoint);
        MetadataConfiguration metadataConfiguration = metaDataConfigurationService.getMetadataConfiguration();

        if (metadataConfiguration == null) {
            throw new OxIntializationException("UMA meta data configuration is invalid!");
        }

        return metadataConfiguration;
    }

    public String getUmaConfigurationEndpoint() {
        String umaIssuer = this.oxTrustConfiguration.getApplicationConfiguration().getUmaIssuer();
        if (StringHelper.isEmpty(umaIssuer)) {
            log.info("oxAuth UMA issuer isn't specified");
            return null;
        }

        String umaConfigurationEndpoint = umaIssuer;
        if (!umaConfigurationEndpoint.endsWith("uma-configuration")) {
            umaConfigurationEndpoint += "/.well-known/uma-configuration";
        }

        return umaConfigurationEndpoint;
    }

}