diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-06-21 11:23:31 +0200 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-06-21 11:23:31 +0200 |
commit | 8778f159556fab8853eac6e9c97e659973be0d78 (patch) | |
tree | 7fe3ad6ab08734b2a72495d3d0754013d4a03ddc | |
parent | f66d793ba9562ffa96103ff69cee441754c3bb7c (diff) | |
download | moa-id-spss-8778f159556fab8853eac6e9c97e659973be0d78.tar.gz moa-id-spss-8778f159556fab8853eac6e9c97e659973be0d78.tar.bz2 moa-id-spss-8778f159556fab8853eac6e9c97e659973be0d78.zip |
refactor metadataprovider to Spring implementation
41 files changed, 602 insertions, 228 deletions
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java index ab6c22858..41a82fe1e 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java @@ -22,8 +22,6 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.configuration.config; -import iaik.x509.X509Certificate; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -65,6 +63,7 @@ import at.gv.egovernment.moa.id.configuration.config.usermanagement.FileBasedUse import at.gv.egovernment.moa.id.configuration.utils.UserRequestCleaner; import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.MiscUtil; +import iaik.x509.X509Certificate; public class ConfigurationProvider { @@ -590,7 +589,7 @@ public class ConfigurationProvider { } } - idpMetadataProvider = new HTTPMetadataProvider(new Timer(), httpClient, metadataurl); + idpMetadataProvider = new HTTPMetadataProvider(new Timer(true), httpClient, metadataurl); idpMetadataProvider.setRequireValidMetadata(true); idpMetadataProvider.setParserPool(new BasicParserPool()); idpMetadataProvider.setMetadataFilter(new MetaDataVerificationFilter(idpCredential)); diff --git a/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/ServicesProtocolPVP2XTask.java b/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/ServicesProtocolPVP2XTask.java index c55c35da0..d69157553 100644 --- a/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/ServicesProtocolPVP2XTask.java +++ b/id/moa-id-webgui/src/main/java/at/gv/egovernment/moa/id/config/webgui/validation/task/impl/ServicesProtocolPVP2XTask.java @@ -186,7 +186,7 @@ public class ServicesProtocolPVP2XTask extends AbstractTaskValidator implements BasicX509Credential credential = new BasicX509Credential(); credential.setEntityCertificate(cert); - timer = new Timer(); + timer = new Timer(true); httpClient = new MOAHttpClient(); if (metadataURL.startsWith("https:")) diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java index 85f16e11f..9be73b3f1 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java @@ -255,7 +255,9 @@ public class Configuration { } //load IDP metadata into metadataprovider - idpMetadataProvider = new HTTPMetadataProvider(new Timer(), new HttpClient(), metadataurl); + idpMetadataProvider = new HTTPMetadataProvider( + new Timer("demoOA", true), + new HttpClient(), metadataurl); idpMetadataProvider.setRequireValidMetadata(true); idpMetadataProvider.setParserPool(new BasicParserPool()); idpMetadataProvider.setMetadataFilter(new MetaDataVerificationFilter(idpCredential)); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IDestroyableObject.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IDestroyableObject.java new file mode 100644 index 000000000..6f98357e2 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IDestroyableObject.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth; + +/** + * @author tlenz + * + */ +public interface IDestroyableObject { + /** + * Manually deep destroy a Java object with all child objects like timers and threads + * + */ + public void fullyDestroy(); + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IGarbageCollectorProcessing.java index a1008e883..27d142f2c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IGarbageCollectorProcessing.java @@ -20,7 +20,7 @@ * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ -package at.gv.egovernment.moa.id.config.auth; +package at.gv.egovernment.moa.id.auth; /** * @author tlenz diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java new file mode 100644 index 000000000..52e30a2f0 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.auth; + + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import at.gv.egovernment.moa.logging.Logger; + +@Service("MOAGarbageCollector") +@EnableScheduling +public class MOAGarbageCollector implements Runnable { + + @Autowired ApplicationContext context; + + private static final long INTERVAL = 24 * 60 * 60 * 1000; // 24 hours + //private static final long INITAL_DELAY = 12 * 60 * 60 * 1000; // 12 hours + + private static final long INITAL_DELAY = 2 * 60 * 1000; // 12 hours + +// private static final List<IGarbageCollectorProcessing> processModules = +// new ArrayList<IGarbageCollectorProcessing>(); + + + @Scheduled(fixedRate = INTERVAL, initialDelay = INITAL_DELAY) + public void run() { + + Map<String, IGarbageCollectorProcessing> processModules = + context.getBeansOfType(IGarbageCollectorProcessing.class); + + if (processModules != null) { + Iterator<Entry<String, IGarbageCollectorProcessing>> interator = processModules.entrySet().iterator(); + while (interator.hasNext()) { + try { + interator.next().getValue().runGarbageCollector(); + + } catch (Throwable e1) { + Logger.warn("Garbage collection FAILED in some module.", e1); + + } + + } + } + } + +// /** +// * Add a module to MOA internal garbage collector. Every module is executed once a day +// * +// * @param modul Module which should be executed by the garbage collector. +// */ +// public static void addModulForGarbageCollection(IGarbageCollectorProcessing modul) { +// processModules.add(modul); +// +// } + +// public static void start() { +// // start the session cleanup thread +// Thread configLoader = new Thread(new MOAGarbageCollector(), "MOAGarbageCollector"); +// configLoader.setName("MOAGarbageCollectorr"); +// configLoader.setDaemon(true); +// configLoader.setPriority(Thread.MIN_PRIORITY); +// configLoader.start(); +// } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java index 8de283c9a..11f47052e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java @@ -36,13 +36,11 @@ import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SSLUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; -import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moaspss.logging.LoggingContext; import at.gv.egovernment.moaspss.logging.LoggingContextManager; @@ -155,7 +153,5 @@ public class MOAIDAuthInitializer { Logger.debug(i + ": " + providerList[i].getName() + " Version " + providerList[i].getVersion()); } - - MOAGarbageCollector.start(); } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index 908c7e7b6..f980f299c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -106,6 +106,7 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { @Autowired protected AuthConfiguration authConfig; @Autowired private AttributQueryBuilder attributQueryBuilder; @Autowired private SAMLVerificationEngineSP samlVerificationEngine; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public IAuthData buildAuthenticationData(IRequest pendingReq, @@ -222,7 +223,7 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { try { samlVerificationEngine.verifyIDPResponse(intfResp, TrustEngineFactory.getSignatureKnownKeysTrustEngine( - MOAMetadataProvider.getInstance())); + metadataProvider)); //create assertion attribute extractor from AttributeQuery response return new AssertionAttributeExtractor(intfResp); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java deleted file mode 100644 index 1072bec5c..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -package at.gv.egovernment.moa.id.config.auth; - - -import java.util.ArrayList; -import java.util.List; - -import at.gv.egovernment.moa.logging.Logger; - -public class MOAGarbageCollector implements Runnable { - - private static final long INTERVAL = 24 * 60 * 60; // 24 hours - private static final List<IGarbageCollectorProcessing> processModules = - new ArrayList<IGarbageCollectorProcessing>(); - - public void run() { - while (true) { - try { - Thread.sleep(INTERVAL * 1000); - - try { - for (IGarbageCollectorProcessing element : processModules) - element.runGarbageCollector(); - - } catch (Throwable e1) { - Logger.warn("Garbage collection FAILED in some module.", e1); - } - - } catch (Throwable e) { - Logger.warn("MOA-ID garbage collection is not possible, actually.", e); - - } finally { - - } - } - } - - /** - * Add a module to MOA internal garbage collector. Every module is executed once a day - * - * @param modul Module which should be executed by the garbage collector. - */ - public static void addModulForGarbageCollection(IGarbageCollectorProcessing modul) { - processModules.add(modul); - - } - - public static void start() { - // start the session cleanup thread - Thread configLoader = new Thread(new MOAGarbageCollector(), "MOAGarbageCollector"); - configLoader.setName("MOAGarbageCollectorr"); - configLoader.setDaemon(true); - configLoader.setPriority(Thread.MIN_PRIORITY); - configLoader.start(); - } -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index 3c6042b51..34b250bf0 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -104,7 +104,8 @@ public class AuthenticationManager extends MOAIDAuthConstants { @Autowired private SingleLogOutBuilder sloBuilder; @Autowired private SAMLVerificationEngineSP samlVerificationEngine; @Autowired private IGUIFormBuilder guiBuilder; - + @Autowired(required=true) private MOAMetadataProvider metadataProvider; + public void performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq) throws MOAIDException { performSingleLogOut(httpReq, httpResp, session, pvpReq, null); @@ -527,7 +528,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { } else { samlVerificationEngine.verifySLOResponse(sloResp, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java index 85e4dc99b..91ba49fe8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java @@ -32,6 +32,8 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils; import at.gv.egovernment.moa.id.commons.MOAIDConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; @@ -174,7 +176,7 @@ public abstract class RequestImpl implements IRequest, Serializable{ * * @return List of PVP 2.1 attribute names with maps all protocol specific attributes */ - public abstract Collection<String> getRequestedAttributes(); + public abstract Collection<String> getRequestedAttributes(MetadataProvider metadataProvider); public void setOAURL(String value) { oaURL = value; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java index 98c6632f1..6375f26a3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -81,6 +81,7 @@ public class AttributQueryAction implements IAction { @Autowired private IDPCredentialProvider pvpCredentials; @Autowired private AuthConfiguration authConfig; @Autowired private MOASessionDBUtils moaSessionDBUtils; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList( new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); @@ -140,7 +141,7 @@ public class AttributQueryAction implements IAction { //build PVP 2.1 response Response authResponse = AuthResponseBuilder.buildResponse( - MOAMetadataProvider.getInstance(), issuerEntityID, attrQuery, date, + metadataProvider, issuerEntityID, attrQuery, date, assertion, authConfig.isPVP2AssertionEncryptionActive()); SoapBinding decoder = new SoapBinding(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java index 8de44a2e8..aac49844e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java @@ -61,6 +61,7 @@ import at.gv.egovernment.moa.logging.Logger; public class AuthenticationAction implements IAction { @Autowired IDPCredentialProvider pvpCredentials; @Autowired AuthConfiguration authConfig; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { @@ -70,7 +71,7 @@ public class AuthenticationAction implements IAction { //get basic information MOARequest moaRequest = (MOARequest) pvpRequest.getRequest(); AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest(); - EntityDescriptor peerEntity = moaRequest.getEntityMetadata(); + EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider); AssertionConsumerService consumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class); @@ -94,7 +95,7 @@ public class AuthenticationAction implements IAction { peerEntity, date, consumerService, sloInformation); Response authResponse = AuthResponseBuilder.buildResponse( - MOAMetadataProvider.getInstance(), issuerEntityID, authnRequest, + metadataProvider, issuerEntityID, authnRequest, date, assertion, authConfig.isPVP2AssertionEncryptionActive()); IEncoder binding = null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java index 82e46b6ce..127284ae0 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java @@ -104,6 +104,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { @Autowired IDPCredentialProvider pvpCredentials; @Autowired SAMLVerificationEngineSP samlVerificationEngine; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public static final String NAME = PVP2XProtocol.class.getName(); public static final String PATH = "id_pvp2x"; @@ -187,7 +188,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new PostBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -240,7 +241,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new RedirectBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSORedirectService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -294,7 +295,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new SoapBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -336,7 +337,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { if(!msg.isVerified()) { samlVerificationEngine.verify(msg, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); msg.setVerified(true); } @@ -493,7 +494,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { msg = (MOARequest) inMsg; - EntityDescriptor metadata = msg.getEntityMetadata(); + EntityDescriptor metadata = msg.getEntityMetadata(metadataProvider); if(metadata == null) { throw new NoMetadataInformationException(); } @@ -643,7 +644,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { throw new MOAIDException("Unsupported request", new Object[] {}); } - EntityDescriptor metadata = moaRequest.getEntityMetadata(); + EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider); if(metadata == null) { throw new NoMetadataInformationException(); } @@ -735,7 +736,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { } } - String oaURL = moaRequest.getEntityMetadata().getEntityID(); + String oaURL = moaRequest.getEntityMetadata(metadataProvider).getEntityID(); oaURL = StringEscapeUtils.escapeHtml(oaURL); IOAAuthParameters oa = authConfig.getOnlineApplicationParameter(oaURL); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java index e7f2a7d4b..caf66942e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java @@ -32,6 +32,7 @@ import org.opensaml.saml2.core.impl.AuthnRequestImpl; import org.opensaml.saml2.metadata.AttributeConsumingService; import org.opensaml.saml2.metadata.RequestedAttribute; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -54,7 +55,6 @@ public class PVPTargetConfiguration extends RequestImpl { private static final long serialVersionUID = 4889919265919638188L; - InboundMessage request; String binding; String consumerURL; @@ -88,14 +88,14 @@ public class PVPTargetConfiguration extends RequestImpl { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { Map<String, String> reqAttr = new HashMap<String, String>(); for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) reqAttr.put(el, ""); try { - SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata().getSPSSODescriptor(SAMLConstants.SAML20P_NS); + SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata(metadataProvider).getSPSSODescriptor(SAMLConstants.SAML20P_NS); if (spSSODescriptor.getAttributeConsumingServices() != null && spSSODescriptor.getAttributeConsumingServices().size() > 0) { @@ -139,5 +139,6 @@ public class PVPTargetConfiguration extends RequestImpl { } - } + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java index 25b22f0ad..94d91694a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java @@ -62,6 +62,7 @@ import at.gv.egovernment.moa.util.MiscUtil; public class SoapBinding implements IDecoder, IEncoder { + @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired private IDPCredentialProvider credentialProvider; public InboundMessageInterface decode(HttpServletRequest req, @@ -109,7 +110,7 @@ public class SoapBinding implements IDecoder, IEncoder { RequestAbstractType attributeRequest = (RequestAbstractType) attrReq; try { if (MiscUtil.isNotEmpty(attributeRequest.getIssuer().getValue()) && - MOAMetadataProvider.getInstance().getRole( + metadataProvider.getRole( attributeRequest.getIssuer().getValue(), SPSSODescriptor.DEFAULT_ELEMENT_NAME) != null) request.setEntityID(attributeRequest.getIssuer().getValue()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java index e5c897aa6..de59e6055 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java @@ -94,8 +94,9 @@ import at.gv.egovernment.moa.logging.Logger; @Service("PVP_SingleLogOutBuilder") public class SingleLogOutBuilder { + @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired private IDPCredentialProvider credentialProvider; - + public void checkStatusCode(ISLOInformationContainer sloContainer, LogoutResponse logOutResp) { Status status = logOutResp.getStatus(); if (!status.getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { @@ -353,7 +354,7 @@ public class SingleLogOutBuilder { public SingleLogoutService getRequestSLODescriptor(String entityID) throws NOSLOServiceDescriptorException { try { - EntityDescriptor entity = MOAMetadataProvider.getInstance().getEntityDescriptor(entityID); + EntityDescriptor entity = metadataProvider.getEntityDescriptor(entityID); SSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); SingleLogoutService sloService = null; @@ -394,7 +395,7 @@ public class SingleLogOutBuilder { public SingleLogoutService getResponseSLODescriptor(PVPTargetConfiguration spRequest) throws NoMetadataInformationException, NOSLOServiceDescriptorException { MOARequest moaReq = (MOARequest) spRequest.getRequest(); - EntityDescriptor metadata = moaReq.getEntityMetadata(); + EntityDescriptor metadata = moaReq.getEntityMetadata(metadataProvider); SSODescriptor ssodesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); if (ssodesc == null) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java index 332caf967..8c8345bbf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java @@ -25,11 +25,11 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.messages; import java.io.Serializable; import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.logging.Logger; /** @@ -46,10 +46,12 @@ public class InboundMessage implements InboundMessageInterface, Serializable{ private String relayState = null; - public EntityDescriptor getEntityMetadata() throws NoMetadataInformationException { - + public EntityDescriptor getEntityMetadata(MetadataProvider metadataProvider) throws NoMetadataInformationException { try { - return MOAMetadataProvider.getInstance().getEntityDescriptor(this.entityID); + if (metadataProvider == null) + throw new NullPointerException("No PVP MetadataProvider found."); + + return metadataProvider.getEntityDescriptor(this.entityID); } catch (MetadataProviderException e) { Logger.warn("No Metadata for EntitiyID " + entityID); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java index 3002ca179..19adfe4c4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java @@ -44,13 +44,14 @@ import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; +import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; +import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.InterfederatedIDPPublicServiceFilter; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.PVPMetadataFilterChain; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter; @@ -58,65 +59,85 @@ import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.MiscUtil; +@Service("PVPMetadataProvider") public class MOAMetadataProvider extends SimpleMOAMetadataProvider - implements ObservableMetadataProvider, IGarbageCollectorProcessing, IMOARefreshableMetadataProvider { + implements ObservableMetadataProvider, IGarbageCollectorProcessing, + IMOARefreshableMetadataProvider, IDestroyableObject { - private static MOAMetadataProvider instance = null; + //private static final int METADATA_GARBAGE_TIMEOUT_SEC = 604800; //7 days + +// private static MOAMetadataProvider instance = null; + MetadataProvider internalProvider = null; private static Object mutex = new Object(); + //private Map<String, Date> lastAccess = null; - public static MOAMetadataProvider getInstance() { - if (instance == null) { - synchronized (mutex) { - if (instance == null) { - instance = new MOAMetadataProvider(); - - //add this to MOA garbage collector - MOAGarbageCollector.addModulForGarbageCollection(instance); - - } - } - } - return instance; + public MOAMetadataProvider() { + internalProvider = new ChainingMetadataProvider(); + //lastAccess = new HashMap<String, Date>(); + } +// public static MOAMetadataProvider getInstance() { +// if (instance == null) { +// synchronized (mutex) { +// if (instance == null) { +// instance = new MOAMetadataProvider(); +// +// //add this to MOA garbage collector +// MOAGarbageCollector.addModulForGarbageCollection(instance); +// +// } +// } +// } +// return instance; +// } + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() */ @Override public void runGarbageCollector() { - reInitialize(); - - } - - private static void reInitialize() { synchronized (mutex) { /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ - if (instance != null) - try { - Logger.trace("Check consistence of PVP2X metadata"); - instance.addAndRemoveMetadataProvider(); + try { + Logger.trace("Check consistence of PVP2X metadata"); + addAndRemoveMetadataProvider(); - } catch (ConfigurationException e) { - Logger.error("Access to MOA-ID configuration FAILED.", e); + } catch (ConfigurationException e) { + Logger.error("Access to MOA-ID configuration FAILED.", e); - } - else - Logger.info("MOAMetadataProvider is not loaded."); + } } + } - public static void destroy() { - if (instance != null) { - instance.internalDestroy(); + +// private static void reInitialize() { +// synchronized (mutex) { +// +// /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ +// if (instance != null) +// try { +// Logger.trace("Check consistence of PVP2X metadata"); +// instance.addAndRemoveMetadataProvider(); +// +// } catch (ConfigurationException e) { +// Logger.error("Access to MOA-ID configuration FAILED.", e); +// +// } +// else +// Logger.info("MOAMetadataProvider is not loaded."); +// } +// } + + public void fullyDestroy() { + internalDestroy(); - } else { - Logger.info("MOAMetadataProvider is not loaded. Accordingly it can not be destroyed"); - } } - MetadataProvider internalProvider; + @Override public boolean refreshMetadataProvider(String entityID) { @@ -208,7 +229,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider private void addAndRemoveMetadataProvider() throws ConfigurationException { if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - Logger.info("Relaod MOAMetaDataProvider."); + Logger.info("Reload MOAMetaDataProvider."); /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ @@ -217,7 +238,19 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider //get all actually loaded metadata providers Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); - + + /* TODO: maybe add metadata provider destroy after timeout. + * But could be a problem if one Metadataprovider load an EntitiesDescriptor + * with more the multiple EntityDescriptors. If one of this EntityDesciptors + * are expired the full EntitiesDescriptor is removed. + * + * Timeout requires a better solution in this case! + */ +// Date now = new Date(); +// Date expioredate = new Date(now.getTime() - (METADATA_GARBAGE_TIMEOUT_SEC * 1000)); +// Logger.debug("Starting PVP Metadata garbag collection (Expioredate:" +// + expioredate + ")"); + //load all PVP2 OAs form ConfigurationDatabase and //compare actually loaded Providers with configured PVP2 OAs Map<String, String> allOAs = AuthConfigurationProviderFactory.getInstance().getConfigurationWithWildCard( @@ -238,30 +271,31 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider HTTPMetadataProvider httpProvider = null; try { if (MiscUtil.isNotEmpty(metadataurl)) { - if (loadedproviders.containsKey(metadataurl)) { + if (loadedproviders.containsKey(metadataurl)) { // PVP2 OA is actually loaded, to nothing providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); loadedproviders.remove(metadataurl); - } else if ( MiscUtil.isNotEmpty(metadataurl) && - !providersinuse.containsKey(metadataurl) ) { - //PVP2 OA is new, add it to MOAMetadataProvider - String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); - if (MiscUtil.isNotEmpty(certBase64)) { - byte[] cert = Base64Utils.decode(certBase64, false); - String oaFriendlyName = oaParam.getFriendlyName(); - - - Logger.info("Loading metadata for: " + oaFriendlyName); - httpProvider = createNewHTTPMetaDataProvider( - metadataurl, - buildMetadataFilterChain(oaParam, metadataurl, cert), - oaFriendlyName); - - if (httpProvider != null) - providersinuse.put(metadataurl, httpProvider); - } + //INFO: load metadata dynamically if they are requested +// } else if ( MiscUtil.isNotEmpty(metadataurl) && +// !providersinuse.containsKey(metadataurl) ) { +// //PVP2 OA is new, add it to MOAMetadataProvider +// String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); +// if (MiscUtil.isNotEmpty(certBase64)) { +// byte[] cert = Base64Utils.decode(certBase64, false); +// String oaFriendlyName = oaParam.getFriendlyName(); +// +// +// Logger.info("Loading metadata for: " + oaFriendlyName); +// httpProvider = createNewHTTPMetaDataProvider( +// metadataurl, +// buildMetadataFilterChain(oaParam, metadataurl, cert), +// oaFriendlyName); +// +// if (httpProvider != null) +// providersinuse.put(metadataurl, httpProvider); +// } } } @@ -339,15 +373,21 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider } } - instance = null; + internalProvider = new ChainingMetadataProvider(); } else { Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); } } - private MOAMetadataProvider() { + @Deprecated + /** + * Load all PVP metadata from OA configuration + * + * This method is deprecated because OA metadata should be loaded dynamically + * if the corresponding OA is requested. + */ + private void loadAllPVPMetadataFromKonfiguration() { ChainingMetadataProvider chainProvider = new ChainingMetadataProvider(); - Logger.info("Loading metadata"); Map<String, MetadataProvider> providersinuse = new HashMap<String, MetadataProvider>(); try { @@ -417,14 +457,15 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider + e.getMessage(), e); } + internalProvider = chainProvider; + } catch (ConfigurationException e) { Logger.error("Access MOA-ID configuration FAILED.", e); } - - internalProvider = chainProvider; + } - + private PVPMetadataFilterChain buildMetadataFilterChain(IOAAuthParameters oaParam, String metadataURL, byte[] certificate) throws CertificateException { PVPMetadataFilterChain filterChain = new PVPMetadataFilterChain(metadataURL, certificate); filterChain.getFilters().add(new SchemaValidationFilter()); @@ -505,17 +546,30 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider } +// if (entityDesc != null) +// lastAccess.put(entityID, new Date()); + return entityDesc; } public List<RoleDescriptor> getRole(String entityID, QName roleName) - throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName); + throws MetadataProviderException { + List<RoleDescriptor> result = internalProvider.getRole(entityID, roleName); + +// if (result != null) +// lastAccess.put(entityID, new Date()); + + return result; } public RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol) throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName, supportedProtocol); + RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); + +// if (result != null) +// lastAccess.put(entityID, new Date()); + + return result; } /* (non-Javadoc) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java index 442455d4b..8261a86c1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java @@ -81,7 +81,7 @@ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ } } - timer = new Timer(); + timer = new Timer(true); httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataURL); httpProvider.setParserPool(new BasicParserPool()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java index f384dd511..f6104bdeb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java @@ -41,6 +41,7 @@ import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.criteria.UsageCriteria; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.validation.ValidationException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -56,6 +57,8 @@ import at.gv.egovernment.moa.util.MiscUtil; @Service("SAMLVerificationEngine") public class SAMLVerificationEngine { + + @Autowired(required=true) MOAMetadataProvider metadataProvider; public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { try { @@ -72,7 +75,8 @@ public class SAMLVerificationEngine { } Logger.debug("PVP2X message validation FAILED. Relead metadata for entityID: " + msg.getEntityID()); - if (!MOAMetadataProvider.getInstance().refreshMetadataProvider(msg.getEntityID())) + + if (metadataProvider == null || !metadataProvider.refreshMetadataProvider(msg.getEntityID())) throw e; else { diff --git a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml index cd5fe6acf..4201d31b1 100644 --- a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml +++ b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml @@ -5,10 +5,16 @@ xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" + xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd - http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> + + <task:annotation-driven executor="MOA-ID-Auth_TaskExecutor" scheduler="MOA-ID-Auth_Scheduler"/> + <task:executor id="MOA-ID-Auth_TaskExecutor" pool-size="5"/> + <task:scheduler id="MOA-ID-Auth_Scheduler" pool-size="10"/> <bean id="processEngine" class="at.gv.egovernment.moa.id.process.ProcessEngineImpl"> <property name="transitionConditionExpressionEvaluator"> @@ -54,7 +60,16 @@ class="at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger"/> <bean id="AuthenticationSessionCleaner" - class="at.gv.egovernment.moa.id.auth.AuthenticationSessionCleaner"/> + class="at.gv.egovernment.moa.id.auth.AuthenticationSessionCleaner"/> + + <bean id="MOAGarbageCollector" + class="at.gv.egovernment.moa.id.auth.MOAGarbageCollector"/> + +<!-- <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> + <property name="corePoolSize" value="5" /> + <property name="maxPoolSize" value="10" /> + <property name="queueCapacity" value="25" /> + </bean> --> <!-- Authentication Process Tasks --> <bean id="GenerateBKUSelectionFrameTask" diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java index 66dffe311..0b5128c8b 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.module.test; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.SessionDataStorageException; @@ -254,7 +256,7 @@ public class TestRequestImpl implements IRequest { * @see at.gv.egovernment.moa.id.moduls.IRequest#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { // TODO Auto-generated method stub return null; } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java index b23b4474b..25919a937 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.commons.api; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + import at.gv.egovernment.moa.id.commons.api.exceptions.SessionDataStorageException; public interface IRequest { @@ -193,9 +195,10 @@ public interface IRequest { /** * This method get a Set of PVP 2.1 attribute, which are request by this pending-request. + * @param metadataProvider SAML2 Metadata Provider, or null if no metadata provider is required * * @return A set of PVP attribute names or null if no attributes are requested * or the Service Provider, which sends this request needs no attributes */ - public Collection<String> getRequestedAttributes(); + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider); } diff --git a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java new file mode 100644 index 000000000..f99013082 --- /dev/null +++ b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java @@ -0,0 +1,166 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.stereotype.Component; + +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@Component +public class MOAContextCloseHandler implements ApplicationListener<ContextClosedEvent>, ApplicationContextAware, BeanPostProcessor { + + private ApplicationContext context; + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ContextClosedEvent arg0) { + Logger.info("MOA-ID-Auth shutdown process started ..."); + + try { + Logger.debug("CleanUp objects with implements the IDestroyable interface ... "); + Map<String, IDestroyableObject> objectsToDestroy = context.getBeansOfType(IDestroyableObject.class); + if (objectsToDestroy != null) { + Iterator<Entry<String, IDestroyableObject>> interator = + objectsToDestroy.entrySet().iterator(); + while (interator.hasNext()) { + Entry<String, IDestroyableObject> object = interator.next(); + try { + object.getValue().fullyDestroy(); + Logger.debug("Object with ID:" + object.getKey() + " is destroyed"); + + } catch (Exception e) { + Logger.warn("Destroing object with ID:" + object.getKey() + " FAILED!", e); + + } + } + } + Logger.info("Object cleanUp complete"); + + Logger.debug("Stopping Spring Thread-Pools ... "); + //shut-down task schedulers + Map<String, ThreadPoolTaskScheduler> schedulers = context.getBeansOfType(ThreadPoolTaskScheduler.class); + for (ThreadPoolTaskScheduler scheduler : schedulers.values()) { + scheduler.getScheduledExecutor().shutdown(); + try { + scheduler.getScheduledExecutor().awaitTermination(20000, TimeUnit.MILLISECONDS); + if(scheduler.getScheduledExecutor().isTerminated() || scheduler.getScheduledExecutor().isShutdown()) + Logger.debug("Scheduler "+scheduler.getThreadNamePrefix() + " has stoped"); + else{ + Logger.debug("Scheduler "+scheduler.getThreadNamePrefix() + " has not stoped normally and will be shut down immediately"); + scheduler.getScheduledExecutor().shutdownNow(); + Logger.info("Scheduler "+scheduler.getThreadNamePrefix() + " has shut down immediately"); + } + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + + } finally { + scheduler.shutdown(); + + } + } + + //shut-down task executors + Map<String, ThreadPoolTaskExecutor> executers = context.getBeansOfType(ThreadPoolTaskExecutor.class); + for (ThreadPoolTaskExecutor executor: executers.values()) { + int retryCount = 0; + while(executor.getActiveCount()>0 && ++retryCount<51){ + try { + Logger.debug("Executer "+executor.getThreadNamePrefix()+" is still working with active " + executor.getActiveCount()+" work. Retry count is "+retryCount); + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(!(retryCount<51)) + Logger.debug("Executer "+executor.getThreadNamePrefix()+" is still working.Since Retry count exceeded max value "+retryCount+", will be killed immediately"); + executor.shutdown(); + Logger.debug("Executer "+executor.getThreadNamePrefix()+" with active " + executor.getActiveCount()+" work has killed"); + } + + Logger.debug("Spring Thread-Pools stopped"); + + Logger.info("MOA-ID-Auth shutdown process finished"); + + } catch (Exception e) { + Logger.warn("MOA-ID-Auth shutdown process has an error.", e); + + } + + //System.exit(0); + //Thread.currentThread().interrupt(); + + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + @Override + public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException { + if(arg0 instanceof ThreadPoolTaskScheduler) + ((ThreadPoolTaskScheduler)arg0).setWaitForTasksToCompleteOnShutdown(true); + if(arg0 instanceof ThreadPoolTaskExecutor) + ((ThreadPoolTaskExecutor)arg0).setWaitForTasksToCompleteOnShutdown(true); + return arg0; + + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + @Override + public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException { + return arg0; + + } + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext arg0) throws BeansException { + this.context = arg0; + + } + +} diff --git a/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml b/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml index ae38c836e..2c53d55b9 100644 --- a/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml +++ b/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml @@ -27,5 +27,8 @@ <bean class="at.gv.egovernment.moa.id.auth.servlet.interceptor.UniqueSessionIdentifierInterceptor" /> </mvc:interceptors> + <bean id="MOAIDContextCloseHandler" + class="at.gv.egovernment.moa.id.auth.MOAContextCloseHandler"/> + </beans> diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java index 80a2734f2..f062ad3c2 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java @@ -25,14 +25,15 @@ import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; +import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; +import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MOASPMetadataSignatureFilter; @@ -41,35 +42,57 @@ import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.eidas.auth.engine.AbstractSAMLEngine; -public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider, IGarbageCollectorProcessing { +@Service("eIDASMetadataProvider") +public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider, + IGarbageCollectorProcessing, IDestroyableObject { - private static MOAeIDASChainingMetadataProvider instance = null; +// private static MOAeIDASChainingMetadataProvider instance = null; private static Object mutex = new Object(); private MetadataProvider internalProvider; private Map<String, Date> lastAccess = null; - public static MOAeIDASChainingMetadataProvider getInstance() { - if (instance == null) { - synchronized (mutex) { - if (instance == null) { - instance = new MOAeIDASChainingMetadataProvider(); - MOAGarbageCollector.addModulForGarbageCollection(instance); - } - } - } - return instance; - } +// public static MOAeIDASChainingMetadataProvider getInstance() { +// if (instance == null) { +// synchronized (mutex) { +// if (instance == null) { +// instance = new MOAeIDASChainingMetadataProvider(); +// MOAGarbageCollector.addModulForGarbageCollection(instance); +// } +// } +// } +// return instance; +// } - private MOAeIDASChainingMetadataProvider() { + public MOAeIDASChainingMetadataProvider() { internalProvider = new ChainingMetadataProvider(); lastAccess = new HashMap<String, Date>(); } /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.IDestroyableObject#fullyDestroy() + */ + @Override + public void fullyDestroy() { + Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); + if (loadedproviders != null) { + for (Entry<String, HTTPMetadataProvider> el : loadedproviders.entrySet()) { + try { + el.getValue().destroy(); + Logger.debug("Destroy eIDAS Matadataprovider: " + el.getKey() + " finished"); + + } catch (Exception e) { + Logger.warn("Destroy eIDAS Matadataprovider: " + el.getKey() + " FAILED"); + + } + } + } + } + + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() */ @Override @@ -196,7 +219,7 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi } } - timer = new Timer(); + timer = new Timer(true); httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataURL); httpProvider.setParserPool(AbstractSAMLEngine.getNewBasicSecuredParserPool()); @@ -405,5 +428,4 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi if (observer != null) observer.onEvent(this); } - } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java index 30c206025..2f10df540 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.google.common.net.MediaType; @@ -43,6 +44,7 @@ import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; @@ -70,6 +72,8 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException; @Component("GenerateAuthnRequestTask") public class GenerateAuthnRequestTask extends AbstractAuthServletTask { + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @@ -127,7 +131,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { pAttList.add(newAttribute); } - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); //build eIDAS AuthnRequest EIDASAuthnRequest authnRequest = new EIDASAuthnRequest(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java index fae06031a..daa4d8b02 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java @@ -4,6 +4,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.opensaml.saml2.core.StatusCode; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; @@ -11,6 +12,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASResponseNotSuccessException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; @@ -29,6 +31,8 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException; @Component("ReceiveAuthnResponseTask") public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + @Override public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { @@ -48,7 +52,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { byte[] decSamlToken = EIDASUtil.decodeSAMLToken(base64SamlToken); //get eIDAS SAML-engine - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); //validate SAML token EIDASAuthnResponse samlResp = engine.validateEIDASAuthnResponse(decSamlToken, diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java index eeb8305cf..68640caf7 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java @@ -42,7 +42,7 @@ public class SAMLEngineUtils { private static EIDASSAMLEngine eIDASEngine = null; - public static synchronized EIDASSAMLEngine createSAMLEngine() throws EIDASEngineException{ + public static synchronized EIDASSAMLEngine createSAMLEngine(MOAeIDASChainingMetadataProvider moaeIDASMetadataProvider) throws EIDASEngineException{ if (eIDASEngine == null) { try { @@ -56,7 +56,7 @@ public class SAMLEngineUtils { //set metadata management to eIDAS SAMLengine engine.setMetadataProcessor( new MOAeIDASMetadataProviderDecorator( - MOAeIDASChainingMetadataProvider.getInstance())); + moaeIDASMetadataProvider)); //set MOA specific extension processor ExtensionProcessorI extensionProcessor = new MOAeIDAsExtensionProcessor(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java index 563c3a18c..4dffba575 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java @@ -2,6 +2,7 @@ package at.gv.egovernment.moa.id.protocols.eidas; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -29,7 +30,7 @@ public class EIDASData extends RequestImpl { private String remoteRelayState; @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { // TODO Auto-generated method stub return null; } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java index 24134f1d9..379a16a96 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -34,6 +34,7 @@ import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -74,6 +75,8 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { public static final String NAME = EIDASProtocol.class.getName(); public static final String PATH = "eidas"; + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + public EIDASProtocol() { super(); Logger.debug("Registering servlet " + getClass().getName() + @@ -170,7 +173,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { try { //get eIDAS SAML-engine - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); //validate SAML token EIDASAuthnRequest samlReq = engine.validateEIDASAuthnRequest(decSamlToken); @@ -197,7 +200,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { String reqDestination = samlReq.getDestination(); if (MiscUtil.isNotEmpty(reqDestination)) { boolean isValid = false; - List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()) + List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider) .getSPSSODescriptor(samlReq.getIssuer()).getAssertionConsumerServices(); for (AssertionConsumerService el : allowedAssertionConsumerUrl) { @@ -279,11 +282,11 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { } - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); if(null == eidasReq.getEidasRequest().getAssertionConsumerServiceURL()) { String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( - new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), + new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider), engine, eidasReq.getEidasRequest()); eidasReq.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java index b4db5c83d..3fc13406c 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java @@ -23,10 +23,12 @@ import javax.servlet.http.HttpServletResponse; import org.opensaml.saml2.metadata.ContactPerson; import org.opensaml.saml2.metadata.Organization; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.commons.api.IRequest; @@ -50,6 +52,8 @@ import eu.eidas.engine.exceptions.SAMLEngineException; @Service("EidasMetaDataRequest") public class EidasMetaDataRequest implements IAction { + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @@ -103,7 +107,7 @@ public class EidasMetaDataRequest implements IAction { public String generateMetadata(String metadata_url, String sp_return_url) throws SAMLEngineException, EIDASEngineException{ String metadata="invalid metadata"; - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); MetadataGenerator generator = new MetadataGenerator(); MetadataConfigParams mcp=new MetadataConfigParams(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index 9943cc5fb..8289e18d2 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -68,6 +68,7 @@ import eu.eidas.auth.engine.metadata.MetadataUtil; public class eIDASAuthenticationRequest implements IAction { @Autowired protected MOAReversionLogger revisionsLogger; + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; @Override public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { @@ -116,7 +117,7 @@ public class eIDASAuthenticationRequest implements IAction { String token = null; try { - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); // encryption is done by the SamlEngine, i.e. by the module we provide in the config // but we need to set the appropriate request issuer @@ -125,7 +126,7 @@ public class eIDASAuthenticationRequest implements IAction { if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( - new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), + new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider), engine, eidasRequest.getEidasRequest()); eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml index 5d79d082a..20395f210 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml @@ -14,6 +14,9 @@ <bean id="EIDASProtocol" class="at.gv.egovernment.moa.id.protocols.eidas.EIDASProtocol"/> + + <bean id="eIDASMetadataProvider" + class="at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider"/> <!-- Authentication Process Tasks --> <bean id="GenerateAuthnRequestTask" diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java index c9485104b..36cd2c7e7 100644 --- a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java +++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java @@ -36,6 +36,7 @@ import org.opensaml.xml.XMLObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.SimpleMOAMetadataProvider; @@ -51,7 +52,8 @@ import at.gv.egovernment.moa.util.MiscUtil; */ @Service("ELGAMandate_MetadataProvider") -public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvider { +public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvider + implements IDestroyableObject { @Autowired AuthConfiguration authConfig; @@ -69,6 +71,13 @@ public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvide } + public void destroy() { + if (metadataProvider != null) + metadataProvider.destroy(); + + } + + /* (non-Javadoc) * @see org.opensaml.saml2.metadata.provider.MetadataProvider#requireValidMetadata() @@ -220,4 +229,16 @@ public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvide metadataProvider.setRequireValidMetadata(true); } } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.IDestroyableObject#fullyDestroy() + */ + @Override + public void fullyDestroy() { + if (metadataProvider != null) { + metadataProvider.destroy(); + + } + + } } diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java index 98fcdc8dc..258b77b98 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java @@ -28,6 +28,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -209,7 +210,7 @@ public class OAuth20AuthRequest extends OAuth20BaseRequest { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { Map<String, String> reqAttr = new HashMap<String, String>(); for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) reqAttr.put(el, ""); diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java index f35de9c58..50638ebf8 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java @@ -26,6 +26,7 @@ import java.util.Collection; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -168,7 +169,7 @@ class OAuth20TokenRequest extends OAuth20BaseRequest { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { return null; } } diff --git a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java index d581e7e75..f5896bc25 100644 --- a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java +++ b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java @@ -62,7 +62,7 @@ public class CreateAuthnRequestTask extends AbstractAuthServletTask { @Autowired PVPAuthnRequestBuilder authnReqBuilder; @Autowired FederatedAuthCredentialProvider credential; - + @Autowired(required=true) MOAMetadataProvider metadataProvider; /* (non-Javadoc) * @see at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) @@ -95,7 +95,7 @@ public class CreateAuthnRequestTask extends AbstractAuthServletTask { } //load IDP SAML2 entitydescriptor - EntityDescriptor idpEntity = MOAMetadataProvider.getInstance(). + EntityDescriptor idpEntity = metadataProvider. getEntityDescriptor(idpEntityID); if (idpEntity == null) { Logger.warn("Requested IDP " + idpEntityID diff --git a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java index 1c3134b77..f739940c8 100644 --- a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java @@ -90,7 +90,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { @Autowired private SSOManager ssoManager; @Autowired private AttributQueryBuilder attributQueryBuilder; @Autowired private AuthenticationDataBuilder authDataBuilder; - + @Autowired(required=true) MOAMetadataProvider metadataProvider; /* (non-Javadoc) @@ -125,7 +125,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //decode PVP response object msg = (InboundMessage) decoder.decode( - request, response, MOAMetadataProvider.getInstance(), true, + request, response, metadataProvider, true, comperator); if (MiscUtil.isEmpty(msg.getEntityID())) { @@ -135,7 +135,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //validate response signature if(!msg.isVerified()) { - samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); msg.setVerified(true); } @@ -247,7 +247,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { try { Logger.debug("Service Provider is no federated IDP --> start Attribute validation or requesting ... "); - Collection<String> requestedAttr = pendingReq.getRequestedAttributes(); + Collection<String> requestedAttr = pendingReq.getRequestedAttributes(metadataProvider); //check if SAML2 Assertion contains a minimal set of attributes if (!extractor.containsAllRequiredAttributes()) { @@ -267,7 +267,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //check if all attributes are include if (!extractor.containsAllRequiredAttributes( - pendingReq.getRequestedAttributes())) { + pendingReq.getRequestedAttributes(metadataProvider))) { Logger.warn("PVP Response from federated IDP contains not all requested attributes."); throw new AssertionValidationExeption("sp.pvp2.06", new Object[]{FederatedAuthConstants.MODULE_NAME_FOR_LOGGING}); diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java index 42fafc01e..1d3525626 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -81,7 +82,7 @@ public class SAML1RequestImpl extends RequestImpl { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { List<String> reqAttr = new ArrayList<String>(); reqAttr.addAll(SAML1Protocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION); |