title: Spring SAML - Reading and refreshing IdP metadata at runtime
body: <p>I am using WSO2 and SSOCircle with the Spring-SAML extension.  We are testing configurations at this time and have defined 2 IdP's and 2 SP's within our applicationContext.  So, currently, we have 2 statically defined IdP's within our spring xml config and this is working.  For testing purpose we are using the combination of CachingMetadataManager and ResourceBackedMetadataProvider so the IdP metadata is built inside of our WAR archive.  Sample:</p>
  
  <pre><code>&lt;bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager"&gt;
  &lt;constructor-arg&gt;
    &lt;list&gt;
      &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"&gt;
        &lt;constructor-arg&gt;
          &lt;bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider"&gt;
            &lt;constructor-arg&gt;
              &lt;bean class="java.util.Timer"/&gt;
            &lt;/constructor-arg&gt;
            &lt;constructor-arg&gt;
              &lt;bean class="org.opensaml.util.resource.ClasspathResource"&gt;
                &lt;constructor-arg value="/metadata/wso2idp_metadata.xml"/&gt;
              &lt;/bean&gt;
            &lt;/constructor-arg&gt;
            &lt;property name="parserPool" ref="parserPool"/&gt;
          &lt;/bean&gt;
        &lt;/constructor-arg&gt;
        &lt;constructor-arg&gt;
          &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadata"&gt;
          &lt;/bean&gt;
        &lt;/constructor-arg&gt;
      &lt;/bean&gt;
      &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"&gt;
        &lt;constructor-arg&gt;
          &lt;bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider"&gt;
            &lt;constructor-arg&gt;
              &lt;bean class="java.util.Timer"/&gt;
            &lt;/constructor-arg&gt;
            &lt;constructor-arg&gt;
              &lt;bean class="org.opensaml.util.resource.ClasspathResource"&gt;
                &lt;constructor-arg value="/metadata/ssocircleidp_metadata.xml"/&gt;
              &lt;/bean&gt;
            &lt;/constructor-arg&gt;
            &lt;property name="parserPool" ref="parserPool"/&gt;
          &lt;/bean&gt;
        &lt;/constructor-arg&gt;
        &lt;constructor-arg&gt;
          &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadata"&gt;
          &lt;/bean&gt;
        &lt;/constructor-arg&gt;
      &lt;/bean&gt;
    &lt;/list&gt;
  &lt;/constructor-arg&gt;
  </code></pre>
  
  <p></p>
  
  <p>For production, we want to be able to store our IdP metadata in a database (centrally located).  I  want to be able to add, remove and modify the metadata without redeploying the WAR or restarting the server(s).  Initially, I thought I could override the CachingMetadataManager and define a noarg constructor that could load all Metadata providers dynamically but this is not possible because the CachingMetadataManager only defines a single constructor that must take in a MetadataProvider List.  I ended up doing the following:</p>
  
  <pre><code>&lt;bean id="metadataList" class="org.arbfile.util.security.saml.DBMetadataProviderList"&gt;
    &lt;constructor-arg ref="parserPool" /&gt;
    &lt;constructor-arg&gt;
      &lt;bean class="java.util.Timer"/&gt;
    &lt;/constructor-arg&gt;
  &lt;/bean&gt;
  
  &lt;bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager"&gt;
     &lt;constructor-arg ref="metadataList" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Bean metadataList can be defined simply as:</p>
  
  <pre><code>public final class DBMetadataProviderList extends ArrayList&lt;MetadataProvider&gt;
  {
    private final static Logger log = LoggerFactory.getLogger(DBMetadataProviderList.class);
    private ParserPool parser;
  
    public DBMetadataProviderList(ParserPool _parser, Timer _timer) throws MetadataProviderException
    {
      this.parser = _parser;
  // Lookup metadata from DB
    }
  
  }
  </code></pre>
  
  <p>This does allow me to read in the IdP metadata dynamically.  My logic falls down when it comes to refreshing though.  I found <a href="http://forum.spring.io/forum/spring-projects/security/saml/721995-tenant-isolation-for-dynamic-idp-metadata-in-metadatamanager" rel="nofollow noreferrer">this post on the spring forum</a>, however it is 3 to 4 years old.  What is the best way to dynamically read, add and update IdP metadata, cache it and have the cache refresh at some interval?  In my case 1 row in a DB table would equate to a single IdP metadata definition.</p>