package org.apereo.cas.support.saml.mdui; import org.apache.commons.io.input.ClosedInputStream; import org.apereo.cas.util.EncodingUtils; import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain; import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; /** * A metadata adapter {@link DynamicMetadataResolverAdapter} * that queries a metadata server on demand following * the metadata query protocol. * * @author Misagh Moayyed * @since 4.1.0 */ public class DynamicMetadataResolverAdapter extends AbstractMetadataResolverAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicMetadataResolverAdapter.class); /** * Instantiates a new static metadata resolver adapter. * * @param metadataResources the metadata resources */ public DynamicMetadataResolverAdapter(final Map<Resource, MetadataFilterChain> metadataResources) { super(metadataResources); } public DynamicMetadataResolverAdapter() { } @Override public EntityDescriptor getEntityDescriptorForEntityId(final String entityId) { buildMetadataResolverAggregate(entityId); return super.getEntityDescriptorForEntityId(entityId); } @Override protected InputStream getResourceInputStream(final Resource resource, final String entityId) throws IOException { if (resource instanceof UrlResource && resource.getURL().toExternalForm().toLowerCase().endsWith("/entities/")) { final String encodedId = EncodingUtils.urlEncode(entityId); final URL url = new URL(resource.getURL().toExternalForm().concat(encodedId)); LOGGER.debug("Locating metadata input stream for [{}] via [{}]", encodedId, url); final HttpURLConnection httpcon = (HttpURLConnection) url.openConnection(); httpcon.setDoOutput(true); httpcon.addRequestProperty("Accept", "*/*"); httpcon.setRequestMethod("GET"); httpcon.connect(); return httpcon.getInputStream(); } return ClosedInputStream.CLOSED_INPUT_STREAM; } }