I have an spring boot application in which i have integrated with spring-security-saml2-core for sso authetication and i am trying to put the identity provider xml config files externally.
I have uploaded the file in a s3 bucket and trying to download and load them at the application startup.
The files gets downloaded but the context for the classpath is not updated and resource loader is failing while initialising
Code Snippet For Saml File loading :
@Bean
@DependsOn("idpFileDownloader")
BeanFactoryPostProcessor idpMetadataLoader() throws ConfigurationException {
return beanFactory -> {
PathMatchingResourcePatternResolver metadataFilesResolver = new PathMatchingResourcePatternResolver();
try {
Resource[] idpMetadataFiles = metadataFilesResolver.getResources("classpath:/idp-xml-directory/idp-*.xml");
Stream.of(idpMetadataFiles).forEach(idpMetadataFile -> {
try {
Timer refreshTimer = new Timer(true);
ResourceBackedMetadataProvider delegate = null;
delegate = new ResourceBackedMetadataProvider(refreshTimer, new SpringResourceWrapperOpenSAMLResource(idpMetadataFile));
delegate.setParserPool(parserPool());
ExtendedMetadata extendedMetadata = extendedMetadata().clone();
ExtendedMetadataDelegate provider = new ExtendedMetadataDelegate(delegate, extendedMetadata);
provider.setMetadataTrustCheck(false);
provider.setMetadataRequireSignature(false);
String idpFileName = idpMetadataFile.getFilename();
String idpName = idpFileName.substring(idpFileName.lastIndexOf("idp-") + 4, idpFileName.lastIndexOf(".xml"));
extendedMetadata.setAlias(idpName);
beanFactory.registerSingleton(idpName, provider);
//todo: log.info("Loaded Idp Metadata bean {}: {}", idpName, idpMetadataFile);
} catch (Exception e) {
throw new IllegalStateException("Unable to initialize IDP Metadata", e);
}
});
} catch (Exception e) {
throw new IllegalStateException("Unable to initialize IDP Metadata", e);
}
};
}
S3 file download logic :
private void downloadFileFromS3(final String key) {
final long startTime = System.currentTimeMillis();
log.info("Starting Time {} for Downloading The file with the Key is {}",startTime/1000 ,key);
try {
/* final DirectoryDownload directoryDownload =
transferManager.downloadDirectory(DownloadDirectoryRequest.builder()
.destination(Paths.get(s3IdpFilesDirectoryPath))
.bucket(s3BucketName)
.build());
final CompletedDirectoryDownload completedDirectoryDownload = directoryDownload.completionFuture().join();
completedDirectoryDownload.failedTransfers().forEach(fail ->
log.warn("Object [{}] failed to transfer", fail.toString()));
log.info("Content length [{}]", completedDirectoryDownload);*/
final DownloadFileRequest downloadFileRequest =
DownloadFileRequest.builder()
.getObjectRequest(b -> b.bucket(s3BucketName).key(key))
.addTransferListener(LoggingTransferListener.create())
.destination(Paths.get(s3IdpFilesDirectoryPath + key))
.build();
log.info("Download path for key {} is {}", key, Paths.get(s3IdpFilesDirectoryPath + key));
final FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest);
final CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
log.info("Content length [{}]", downloadResult.response().contentLength());
} catch (Exception e) {
log.error("Exception while Downloading file {} is {}",key ,e);
throw e;
}
final long endTime = System.currentTimeMillis();
log.info("Total Time {} for Downloading The file with the Key is {}",(endTime-startTime)/1000 ,key);
return;
}
I have tried downloading them at extern I have tried to load resources as file by given path instead of the resource load.
Can you please suggest a way where i can store saml conf externally and load them at the application startup.