I have a Spring SAML project using java configurations where I am loading IDP metadata in from a file using a FilesystemMetadataProvider
. I would like to be able to load IDPs from a database on start up. If I need to change the configuration, I don't want to have to restart the app to load in the changes. There is a reloading HTTPMetadataProvider
, is there one for databases? Is this possible?
There is not an implementation of the AbstractReloadingMetadataProvider that does what you're looking for natively, however, it's not difficult to implement your own.
The SSOProfile contains the XML of the IDP. The AbstractReloadingMetadataProvider
will use the overridden methods to periodically go to the database and reload any changes to the metadata.
public class DatabaseMetadataProvider extends AbstractReloadingMetadataProvider {
private final Logger log = LoggerFactory.getLogger(DatabaseMetadataProvider.class);
private SSOProfileService samlService;
private String entityId;
public DatabaseMetadataProvider(Timer backgroundTaskTimer, String entityId, SSOProfileService samlService) throws MetadataProviderException {
super(backgroundTaskTimer);
if (entityId == null) {
throw new MetadataProviderException("EntityId may not be null");
}
this.entityId = entityId;
if (samlService == null) {
throw new MetadataProviderException("Saml Service must not be null");
}
this.samlService = samlService;
}
@Override
protected String getMetadataIdentifier() {
return entityId;
}
@Override
protected byte[] fetchMetadata() throws MetadataProviderException {
SSOProfile ssoSaml = samlService.getSSOSamlProfileByEntityID(entityId);
if (ssoSaml == null) {
log.error("Could not find a valid entity in the DB for " + entityId + " to refresh from. ");
return null;
} else {
log.trace("Found idp metadata for " + ssoSaml.getEntityID() + ": " + ssoSaml.getIdpMetaData());
return ssoSaml.getIdpMetaData().getBytes(StandardCharsets.UTF_8);
}
}
/** {@inheritDoc} */
@Override
public synchronized void destroy() {
samlService = null;
entityId = null;
super.destroy();
}
}
The next thing you will need is a service that on start up can return a list of these MetadataProviders and load them in to your MetadataManager.