private OpenIdConfigurationResponse parseConfigurationResponse(final String configurationEndpoint,
                                                                   final String msg) {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        final OpenIdConfigurationResponse openIdConfigurationResponse;
        try {
            openIdConfigurationResponse = mapper.readValue(
                    msg,
                    OpenIdConfigurationResponse.class);
        } catch (JsonProcessingException e) {
            throw new AuthenticationException(LogUtil.message("Unable to parse open ID configuration " +
                                                              "from {}. {}", configurationEndpoint, e.getMessage()), e);
        }
        final AbstractOpenIdConfig localConfig = localOpenIdConfigProvider.get();
        final String responseIssuer = openIdConfigurationResponse.getIssuer();
        final Set<String> validIssuers = getValidIssuers(localConfig);
        if (!validIssuers.isEmpty()) {
            // Allow local config to define a set of issuers that we expect to see
            if (!validIssuers.contains(responseIssuer)) {
                throw new AuthenticationException(LogUtil.message(
                        "Issuer '{}' obtained from configuration endpoint {} " +
                        "does not match those in the 'issuer' or validIssuers' properties.",
                        openIdConfigurationResponse.getIssuer(), configurationEndpoint));
            }
        } else if (!configurationEndpoint.startsWith(responseIssuer)) {
            // Spec says issuer in config response must match the config endpoint base URL
            // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
            // Some IDPs don't seem to follow the spec.
            throw new AuthenticationException(LogUtil.message("Issuer '{}' obtained from configuration endpoint {} " +
                                                              "does not share the same base URI. If this is valid " +
                                                              "consider adding the non-standard " +
                                                              "issuer to the 'validIssuers' property.",
                    openIdConfigurationResponse.getIssuer(), configurationEndpoint));
        }
        return openIdConfigurationResponse;
    }
Combines the values from {@link AbstractOpenIdConfig} with values obtained from the external
Open ID Connect IDP server.
stroom-security/stroom-security-common-impl/src/main/java/stroom/security/common/impl/ExternalIdpConfigurationProvider.java