From e443168b481bb88fecbad73084147e7e8c882908 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 10 Dec 2019 07:39:27 +0100 Subject: refactoring to new EGIZ code requirements --- .../MSSpecificeIDASNodeSpringResourceProvider.java | 51 --- .../MsSpecificEidasNodeSpringResourceProvider.java | 52 +++ .../specific/connector/SpringInitializer.java | 272 ++++++------- .../connector/auth/AuthenticationManager.java | 42 +- .../builder/AuthenticationDataBuilder.java | 141 ++++--- .../connector/builder/PvpSubjectNameGenerator.java | 18 +- .../connector/config/PVPEndPointConfiguration.java | 90 ----- .../connector/config/PVPMetadataConfiguration.java | 262 ------------ .../connector/config/PvpEndPointConfiguration.java | 91 +++++ .../connector/config/PvpMetadataConfiguration.java | 269 +++++++++++++ .../config/StaticResourceConfiguration.java | 268 +++++++------ .../connector/controller/MonitoringController.java | 423 ++++++++++--------- .../connector/controller/PVP2SProfileEndpoint.java | 81 ---- .../controller/ProcessEngineSignalController.java | 30 +- .../connector/controller/Pvp2SProfileEndpoint.java | 80 ++++ .../WebFrontEndSecurityInterceptor.java | 83 ++-- .../specific/connector/logger/RevisionLogger.java | 140 +++---- .../specific/connector/logger/StatisticLogger.java | 211 +++++----- .../specific/connector/mapper/LoALevelMapper.java | 59 ++- .../processes/CountrySelectionProcessImpl.java | 59 +-- .../tasks/EvaluateCountrySelectionTask.java | 75 ++-- .../tasks/GenerateCountrySelectionFrameTask.java | 82 ++-- .../provider/PVPEndPointCredentialProvider.java | 116 ------ .../provider/PVPMetadataConfigurationFactory.java | 50 --- .../connector/provider/PVPMetadataProvider.java | 146 ------- .../provider/PvpEndPointCredentialProvider.java | 119 ++++++ .../provider/PvpMetadataConfigurationFactory.java | 51 +++ .../connector/provider/PvpMetadataProvider.java | 155 +++++++ .../connector/provider/StatusMessageProvider.java | 191 ++++----- .../connector/storage/CacheWithEidasBackend.java | 35 ++ .../connector/storage/CacheWitheIDASBackend.java | 50 --- .../EidasCacheTransactionStoreDecorator.java | 152 +++++++ .../storage/SimpleInMemoryTransactionStorage.java | 256 ++++++------ .../connector/storage/TransactionStoreElement.java | 78 ++-- .../eIDASCacheTransactionStoreDecorator.java | 143 ------- .../verification/AuthnRequestValidator.java | 446 +++++++++++---------- .../MetadataSignatureVerificationFilter.java | 243 +++++------ 37 files changed, 2634 insertions(+), 2476 deletions(-) delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPEndPointConfiguration.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPMetadataConfiguration.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpEndPointConfiguration.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpMetadataConfiguration.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/controller/PVP2SProfileEndpoint.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/controller/Pvp2SProfileEndpoint.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataProvider.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpEndPointCredentialProvider.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataConfigurationFactory.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataProvider.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWithEidasBackend.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java create mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java delete mode 100644 connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java (limited to 'connector/src/main/java') diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java deleted file mode 100644 index 346c4fd7..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -public class MSSpecificeIDASNodeSpringResourceProvider implements SpringResourceProvider { - - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource mseIDASNode = new ClassPathResource("/specific_eIDAS_connector.beans.xml", MSSpecificeIDASNodeSpringResourceProvider.class); - ClassPathResource mseIDASNodeStorage = new ClassPathResource("/specific_eIDAS_connector.storage.beans.xml", MSSpecificeIDASNodeSpringResourceProvider.class); - return new Resource[] {mseIDASNode, mseIDASNodeStorage}; - } - - @Override - public String[] getPackagesToScan() { - return null; - } - - @Override - public String getName() { - return "MS-specific eIDAS Node SpringResourceProvider"; - } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java new file mode 100644 index 00000000..6e8e06ef --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java @@ -0,0 +1,52 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class MsSpecificEidasNodeSpringResourceProvider implements SpringResourceProvider { + + @Override + public Resource[] getResourcesToLoad() { + final ClassPathResource msEidasNode = new ClassPathResource("/specific_eIDAS_connector.beans.xml", + MsSpecificEidasNodeSpringResourceProvider.class); + final ClassPathResource msEidasNodeStorage = new ClassPathResource( + "/specific_eIDAS_connector.storage.beans.xml", MsSpecificEidasNodeSpringResourceProvider.class); + return new Resource[] { msEidasNode, msEidasNodeStorage }; + } + + @Override + public String[] getPackagesToScan() { + return null; + } + + @Override + public String getName() { + return "MS-specific eIDAS Node SpringResourceProvider"; + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java index 083b668c..76802825 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector; import java.util.Arrays; @@ -33,7 +32,6 @@ import javax.servlet.ServletRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -53,142 +51,136 @@ import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafDefaultSaml2Bootstrap; /** - * Web application initializer - * + * Web application initializer. + * * @author Thomas Lenz */ public class SpringInitializer implements WebApplicationInitializer { - private static final Logger log = LoggerFactory.getLogger(SpringInitializer.class); - - private String[] rootServletContexts = null; - private String[] servletContexts = null; - private String[] activeProfiles = null; - - public SpringInitializer() { - this.rootServletContexts = null; - this.servletContexts = new String[] { - "/applicationContext.xml", - - }; - this.activeProfiles = null; - } - - - /* (non-Javadoc) - * @see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext) - */ - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - try { - log.info("=============== Loading Config Root Context! ==============="); - ApplicationContext cfgRootContext = - new ClassPathXmlApplicationContext(new String[] { - "/applicationContext.xml" - }); - - - log.info("=============== Loading Root Context! ==============="); - GenericWebApplicationContext rootContext = new GenericWebApplicationContext(); - rootContext.setServletContext(servletContext); - rootContext.setParent(cfgRootContext); - -// log.info("=============== Setting active profiles! ==============="); -// if (this.activeProfiles != null) { -// for (String profile : this.activeProfiles) { -// rootContext.getEnvironment().addActiveProfile(profile); -// } -// } - - log.info("Spring-context was initialized with active profiles: " + - Arrays.asList(rootContext.getEnvironment().getActiveProfiles())); - - log.info("=============== Loading Local Contexts! ==============="); - XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( - rootContext); - if (rootServletContexts != null) { - for (String rootServletContext : rootServletContexts) { - log.debug("Loading: "+ rootServletContext); - xmlReader.loadBeanDefinitions(new ServletContextResource( - servletContext, rootServletContext)); - } - } - // Manage the lifecycle of the root application context - servletContext.addListener(new ContextLoaderListener(rootContext)); - - // log.debug("Beans after logAMQP in {}", rootContext); - // dumpBeanDefinitions(rootContext); - - log.info("=============== Loading SPI Context! ==============="); - if (rootContext instanceof BeanDefinitionRegistry) { - log.debug("Loading modules and components"); - SpringLoader.loadSpringServices(rootContext); - - } else - log.warn("Failed to load external Spring since no BeanDefinitionRegistry"); - - log.trace("Beans after SPI in "+ rootContext); - dumpBeanDefinitions(rootContext); - - log.debug("Loading servlet config in "+ rootContext); - if (servletContexts != null) { - for (String servletContextString : servletContexts) - xmlReader.loadBeanDefinitions(new ClassPathResource(servletContextString, SpringInitializer.class)); - - } - - log.debug("Refreshing context "+ rootContext); - rootContext.refresh(); - - log.info("=============== Register Dispatcher Servlet! ==============="); - - log.trace("Final Beans in "+ rootContext); - dumpBeanDefinitions(rootContext); - - log.info("Registering dispatcher configuration"); - ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext)); - if (dispatcher != null) { - dispatcher.setLoadOnStartup(1); - dispatcher.addMapping("/"); - dispatcher.setAsyncSupported(true); - - } else - log.error("Failed to register dispatcher server in servlet context!"); - - - log.info("=============== Register RequestContextListener! ==============="); - servletContext.addListener(new RequestContextListener()); - - //initialize status messenger - LogMessageProviderFactory.setStatusMessager(rootContext.getBean(IStatusMessenger.class)); - - log.info("Bootstrap openSAML .... "); - EaafDefaultSaml2Bootstrap.bootstrap(); - - log.info("Seed random number generator ... "); - Random.seedRandom(); - - log.info("Initialization of MS-specific eIDAS-connector finished."); - - - } catch (Throwable e) { - log.error("MS-specific eIDAS-connector initialization FAILED!", e); - - } - - } - - private void dumpBeanDefinitions(GenericApplicationContext context) { - log.trace("Registered Bean in context " + context.toString()); - - String[] registeredBeans = context.getBeanDefinitionNames(); - for (String registeredBean : registeredBeans) { - BeanDefinition beanDefinition = context - .getBeanDefinition(registeredBean); - log.trace(registeredBean + " -> " + beanDefinition.getBeanClassName()); - - } - - log.trace("Registered Bean in context --"+ context); - } + private static final Logger log = LoggerFactory.getLogger(SpringInitializer.class); + + private String[] rootServletContexts = null; + private String[] servletContexts = null; + + /** + * Application specific Spring initializer. + * + */ + public SpringInitializer() { + this.rootServletContexts = null; + this.servletContexts = new String[] { + "/applicationContext.xml", + + }; + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet. + * ServletContext) + */ + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + try { + log.info("=============== Loading Config Root Context! ==============="); + final ApplicationContext cfgRootContext = + new ClassPathXmlApplicationContext(new String[] { + "/applicationContext.xml" + }); + + log.info("=============== Loading Root Context! ==============="); + final GenericWebApplicationContext rootContext = new GenericWebApplicationContext(); + rootContext.setServletContext(servletContext); + rootContext.setParent(cfgRootContext); + + log.info("Spring-context was initialized with active profiles: {}", + Arrays.asList(rootContext.getEnvironment().getActiveProfiles())); + + log.info("=============== Loading Local Contexts! ==============="); + final XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( + rootContext); + if (rootServletContexts != null) { + for (final String rootServletContext : rootServletContexts) { + log.debug("Loading: " + rootServletContext); + xmlReader.loadBeanDefinitions(new ServletContextResource( + servletContext, rootServletContext)); + } + } + // Manage the lifecycle of the root application context + servletContext.addListener(new ContextLoaderListener(rootContext)); + + // log.debug("Beans after logAMQP in {}", rootContext); + // dumpBeanDefinitions(rootContext); + + log.info("=============== Loading SPI Context! ==============="); + log.debug("Loading modules and components"); + SpringLoader.loadSpringServices(rootContext); + + log.trace("Beans after SPI in " + rootContext); + dumpBeanDefinitions(rootContext); + + log.debug("Loading servlet config in " + rootContext); + if (servletContexts != null) { + for (final String servletContextString : servletContexts) { + xmlReader.loadBeanDefinitions(new ClassPathResource(servletContextString, SpringInitializer.class)); + } + + } + + log.debug("Refreshing context " + rootContext); + rootContext.refresh(); + + log.info("=============== Register Dispatcher Servlet! ==============="); + + log.trace("Final Beans in " + rootContext); + dumpBeanDefinitions(rootContext); + + log.info("Registering dispatcher configuration"); + final ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", + new DispatcherServlet(rootContext)); + if (dispatcher != null) { + dispatcher.setLoadOnStartup(1); + dispatcher.addMapping("/"); + dispatcher.setAsyncSupported(true); + + } else { + log.error("Failed to register dispatcher server in servlet context!"); + } + + log.info("=============== Register RequestContextListener! ==============="); + servletContext.addListener(new RequestContextListener()); + + // initialize status messenger + LogMessageProviderFactory.setStatusMessager(rootContext.getBean(IStatusMessenger.class)); + + log.info("Bootstrap openSAML .... "); + EaafDefaultSaml2Bootstrap.bootstrap(); + + log.info("Seed random number generator ... "); + Random.seedRandom(); + + log.info("Initialization of MS-specific eIDAS-connector finished."); + + } catch (final Throwable e) { + log.error("MS-specific eIDAS-connector initialization FAILED!", e); + + } + + } + + private void dumpBeanDefinitions(GenericApplicationContext context) { + log.trace("Registered Bean in context " + context.toString()); + + final String[] registeredBeans = context.getBeanDefinitionNames(); + for (final String registeredBean : registeredBeans) { + final BeanDefinition beanDefinition = context + .getBeanDefinition(registeredBean); + log.trace(registeredBean + " -> " + beanDefinition.getBeanClassName()); + + } + + log.trace("Registered Bean in context --" + context); + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/auth/AuthenticationManager.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/auth/AuthenticationManager.java index b4944675..abda468d 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/auth/AuthenticationManager.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/auth/AuthenticationManager.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.auth; import javax.servlet.http.HttpServletRequest; @@ -40,21 +39,22 @@ import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; @Service("AuthenticationManager") public class AuthenticationManager extends AbstractAuthenticationManager { - private static final Logger log = LoggerFactory.getLogger(AuthenticationManager.class); - - @Override - public ISloInformationContainer performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp, - IRequest pendingReq, String internalSSOId) throws EaafException { - throw new RuntimeException("Single LogOut is NOT supported by this implementation"); - - } - - @Override - protected void populateExecutionContext(ExecutionContext executionContext, - RequestImpl pendingReq, HttpServletRequest httpReq) - throws EaafException { - log.trace("No implementation-specific population of execution-context required ... "); - - } + private static final Logger log = LoggerFactory.getLogger(AuthenticationManager.class); + + @Override + public ISloInformationContainer performSingleLogOut(HttpServletRequest httpReq, + HttpServletResponse httpResp, + IRequest pendingReq, String internalSsoId) throws EaafException { + throw new RuntimeException("Single LogOut is NOT supported by this implementation"); + + } + + @Override + protected void populateExecutionContext(ExecutionContext executionContext, + RequestImpl pendingReq, HttpServletRequest httpReq) + throws EaafException { + log.trace("No implementation-specific population of execution-context required ... "); + + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java index 0688a13f..b14faa62 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.builder; import java.util.Date; @@ -31,7 +30,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.w3c.dom.DOMException; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; @@ -49,70 +48,70 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; @Service("AuthenticationDataBuilder") public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder { - private static final Logger log = LoggerFactory.getLogger(AuthenticationDataBuilder.class); - - @Override - public IAuthData buildAuthenticationData(IRequest pendingReq) throws EaafAuthenticationException { - - IAuthProcessDataContainer authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); - AuthenticationData authData = new AuthenticationData(); - - try { - generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData); - - //set specific informations - authData.setSsoSessionValidTo(new Date(new Date().getTime() - + MSeIDASNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000)); - - } catch (EaafBuilderException | EaafParserException | EaafConfigurationException - | XPathException | DOMException e) { - log.warn("Can not build authentication data from auth. process information"); - throw new EaafAuthenticationException("builder.11", new Object[]{e.getMessage()}, e); - - } - - return authData; - - } - - @Override - protected IAuthData buildDeprecatedAuthData(IRequest arg0) throws EaafException { - // TODO Auto-generated method stub - return null; - } - - @Override - protected void buildServiceSpecificAuthenticationData(IAuthData arg0, IRequest arg1) throws EaafException { - // TODO Auto-generated method stub - - } - - @Override - protected IAuthData getAuthDataInstance(IRequest arg0) throws EaafException { - return new AuthenticationData(); - - } - - @Override - protected Pair buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) throws EaafBuilderException { - //TODO: check if bPK already exists - - - return super.buildOAspecificbPK(pendingReq, authData); - - } - - @Override - protected Pair getEncryptedBpkFromPvpAttribute(IAuthProcessDataContainer arg0, - AuthenticationData arg1, ISpConfiguration arg2) throws EaafBuilderException { - return null; - - } - - @Override - protected Pair getbaseIdFromSzr(AuthenticationData arg0, String arg1, String arg2) { - return null; - - } + private static final Logger log = LoggerFactory.getLogger(AuthenticationDataBuilder.class); + + @Override + public IAuthData buildAuthenticationData(IRequest pendingReq) throws EaafAuthenticationException { + + final IAuthProcessDataContainer authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + final AuthenticationData authData = new AuthenticationData(); + + try { + generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData); + + // set specific informations + authData.setSsoSessionValidTo(new Date(new Date().getTime() + + MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000)); + + } catch (EaafBuilderException | EaafParserException | EaafConfigurationException + | XPathException | DOMException e) { + log.warn("Can not build authentication data from auth. process information"); + throw new EaafAuthenticationException("builder.11", new Object[] { e.getMessage() }, e); + + } + + return authData; + + } + + @Override + protected IAuthData buildDeprecatedAuthData(IRequest arg0) throws EaafException { + return new AuthenticationData(); + + } + + @Override + protected void buildServiceSpecificAuthenticationData(IAuthData arg0, IRequest arg1) throws EaafException { + // TODO Auto-generated method stub + + } + + @Override + protected IAuthData getAuthDataInstance(IRequest arg0) throws EaafException { + return new AuthenticationData(); + + } + + @Override + protected Pair buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) + throws EaafBuilderException { + // TODO: check if bPK already exists + + return super.buildOAspecificbPK(pendingReq, authData); + + } + + @Override + protected Pair getEncryptedBpkFromPvpAttribute(IAuthProcessDataContainer arg0, + AuthenticationData arg1, ISpConfiguration arg2) throws EaafBuilderException { + return null; + + } + + @Override + protected Pair getbaseIdFromSzr(AuthenticationData arg0, String arg1, String arg2) { + return null; + + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/PvpSubjectNameGenerator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/PvpSubjectNameGenerator.java index bb43ee08..d4e97433 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/PvpSubjectNameGenerator.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/PvpSubjectNameGenerator.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.builder; import at.gv.egiz.eaaf.core.api.idp.IAuthData; @@ -32,9 +31,10 @@ import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator; public class PvpSubjectNameGenerator implements ISubjectNameIdGenerator { - @Override - public Pair generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig) throws Pvp2Exception { - return Pair.newInstance(authData.getBpk(), authData.getBpkType()); - } + @Override + public Pair generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig) + throws Pvp2Exception { + return Pair.newInstance(authData.getBpk(), authData.getBpkType()); + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPEndPointConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPEndPointConfiguration.java deleted file mode 100644 index 4086ef7e..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPEndPointConfiguration.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.config; - -import java.util.List; - -import org.opensaml.saml2.metadata.ContactPerson; -import org.opensaml.saml2.metadata.Organization; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; - -@Service("PVPEndPointConfiguration") -public class PVPEndPointConfiguration implements IPvp2BasicConfiguration { - private static final Logger log = LoggerFactory.getLogger(PVPEndPointConfiguration.class); - - @Autowired(required=true) IConfiguration basicConfiguration; - - @Override - public String getIdpEntityId(String authURL) throws EaafException { - return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_METADATA; - - } - - @Override - public String getIdpSsoPostService(String authURL) throws EaafException { - return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_POST; - - } - - @Override - public String getIdpSsoRedirectService(String authURL) throws EaafException { - return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_REDIRECT; - - } - - @Override - public Object getIdpSsoSoapService(String extractAuthURLFromRequest) throws EaafException { - log.warn("PVP S-Profile End-Point does NOT support SOAP Binding"); - return null; - - } - - @Override - public List getIdpContacts() throws EaafException { - // Return contact person, if it shall be included in metadata - return null; - } - - @Override - public Organization getIdpOrganisation() throws EaafException { - // Return organization, if it shall be included in metadata - return null; - } - - private String removePostFix(String url) { - if (url != null && url.endsWith("/")) - return url.substring(0, url.length() - 1); - else - return url; - } -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPMetadataConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPMetadataConfiguration.java deleted file mode 100644 index 62ca42ac..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PVPMetadataConfiguration.java +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.config; - -import java.util.Arrays; -import java.util.List; - -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.core.NameIDType; -import org.opensaml.saml2.metadata.ContactPerson; -import org.opensaml.saml2.metadata.Organization; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.xml.security.credential.Credential; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; - -public class PVPMetadataConfiguration implements IPvpMetadataBuilderConfiguration{ - private static final Logger log = LoggerFactory.getLogger(PVPMetadataConfiguration.class); - - private IConfiguration basicConfig; - private String authUrl; - private AbstractCredentialProvider pvpIDPCredentials; - private IPvp2BasicConfiguration pvpBasicConfig; - - public PVPMetadataConfiguration(IConfiguration basicConfig, String authURL, IPvp2BasicConfiguration pvpBasicConfig, AbstractCredentialProvider pvpIDPCredentials) { - this.authUrl = authURL; - this.pvpIDPCredentials = pvpIDPCredentials; - this.basicConfig = basicConfig; - this.pvpBasicConfig = pvpBasicConfig; - - } - - @Override - public String getSpNameForLogging() { - return "PVP2 S-Profile IDP"; - } - - @Override - public int getMetadataValidUntil() { - return Integer.valueOf(basicConfig.getBasicConfiguration( - MSeIDASNodeConstants.PROP_CONFIG_PVP2_METADATA_VALIDITY, - String.valueOf(MSeIDASNodeConstants.DEFAULT_PVP_METADATA_VALIDITY))); - - } - - @Override - public boolean buildEntitiesDescriptorAsRootElement() { - return false; - - } - - @Override - public boolean buildIdpSsoDescriptor() { - return true; - - } - - @Override - public boolean buildSpSsoDescriptor() { - return false; - - } - - @Override - public String getEntityID() { - try { - return pvpBasicConfig.getIdpEntityId(authUrl); - - } catch (EaafException e) { - log.error("Can NOT build PVP metadata configuration.", e); - throw new RuntimeException("Can NOT build PVP metadata configuration."); - - } - - } - - @Override - public String getEntityFriendlyName() { - return null; - - } - - @Override - public List getContactPersonInformation() { - try { - return pvpBasicConfig.getIdpContacts(); - - } catch (EaafException e) { - log.error("Can NOT build PVP metadata configuration.", e); - throw new RuntimeException("Can NOT build PVP metadata configuration."); - - } - - } - - @Override - public Organization getOrgansiationInformation() { - try { - return pvpBasicConfig.getIdpOrganisation(); - - } catch (EaafException e) { - log.error("Can NOT build PVP metadata configuration.", e); - throw new RuntimeException("Can NOT build PVP metadata configuration."); - - } - } - - @Override - public Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException { - return pvpIDPCredentials.getIdpMetaDataSigningCredential(); - - } - - @Override - public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException { - return pvpIDPCredentials.getIdpAssertionSigningCredential(); - - } - - @Override - public Credential getEncryptionCredentials() throws CredentialsNotAvailableException { - return null; - - - } - - @Override - public String getIdpWebSsoPostBindingUrl() { - try { - return pvpBasicConfig.getIdpSsoPostService(authUrl); - - } catch (EaafException e) { - log.error("Can NOT build PVP metadata configuration.", e); - throw new RuntimeException("Can NOT build PVP metadata configuration."); - - } - - } - - @Override - public String getIdpWebSsoRedirectBindingUrl() { - try { - return pvpBasicConfig.getIdpSsoRedirectService(authUrl); - - } catch (EaafException e) { - log.error("Can NOT build PVP metadata configuration.", e); - throw new RuntimeException("Can NOT build PVP metadata configuration."); - - } - } - - @Override - public String getIdpSloPostBindingUrl() { - return null; - - } - - @Override - public String getIdpSloRedirectBindingUrl() { - return null; - - } - - @Override - public String getSpAssertionConsumerServicePostBindingUrl() { - return null; - - } - - @Override - public String getSpAssertionConsumerServiceRedirectBindingUrl() { - return null; - - } - - @Override - public String getSpSloPostBindingUrl() { - return null; - - } - - @Override - public String getSpSloRedirectBindingUrl() { - return null; - - } - - @Override - public String getSpSloSoapBindingUrl() { - return null; - - } - - @Override - public List getIdpPossibleAttributes() { - return PvpAttributeBuilder.buildSupportedEmptyAttributes(); - - } - - @Override - public List getIdpPossibleNameIdTypes() { - return Arrays.asList(NameIDType.PERSISTENT, - NameIDType.TRANSIENT, - NameIDType.UNSPECIFIED); - } - - @Override - public List getSpRequiredAttributes() { - return null; - - } - - @Override - public List getSpAllowedNameIdTypes() { - return null; - - } - - @Override - public boolean wantAssertionSigned() { - return false; - - } - - @Override - public boolean wantAuthnRequestSigned() { - return true; - - } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpEndPointConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpEndPointConfiguration.java new file mode 100644 index 00000000..fb7cb625 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpEndPointConfiguration.java @@ -0,0 +1,91 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.config; + +import java.util.List; + +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.Organization; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; + +@Service("PVPEndPointConfiguration") +public class PvpEndPointConfiguration implements IPvp2BasicConfiguration { + private static final Logger log = LoggerFactory.getLogger(PvpEndPointConfiguration.class); + + @Autowired(required = true) + IConfiguration basicConfiguration; + + @Override + public String getIdpEntityId(String authUrl) throws EaafException { + return removePostFix(authUrl) + MsEidasNodeConstants.ENDPOINT_PVP_METADATA; + + } + + @Override + public String getIdpSsoPostService(String authUrl) throws EaafException { + return removePostFix(authUrl) + MsEidasNodeConstants.ENDPOINT_PVP_POST; + + } + + @Override + public String getIdpSsoRedirectService(String authUrl) throws EaafException { + return removePostFix(authUrl) + MsEidasNodeConstants.ENDPOINT_PVP_REDIRECT; + + } + + @Override + public Object getIdpSsoSoapService(String extractAuthUrlFromRequest) throws EaafException { + log.warn("PVP S-Profile End-Point does NOT support SOAP Binding"); + return null; + + } + + @Override + public List getIdpContacts() throws EaafException { + // Return contact person, if it shall be included in metadata + return null; + } + + @Override + public Organization getIdpOrganisation() throws EaafException { + // Return organization, if it shall be included in metadata + return null; + } + + private String removePostFix(String url) { + if (url != null && url.endsWith("/")) { + return url.substring(0, url.length() - 1); + } else { + return url; + } + } +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpMetadataConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpMetadataConfiguration.java new file mode 100644 index 00000000..f1828f87 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/PvpMetadataConfiguration.java @@ -0,0 +1,269 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.config; + +import java.util.Arrays; +import java.util.List; + +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.Organization; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.xml.security.credential.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; + +public class PvpMetadataConfiguration implements IPvpMetadataBuilderConfiguration { + private static final Logger log = LoggerFactory.getLogger(PvpMetadataConfiguration.class); + + private final IConfiguration basicConfig; + private final String authUrl; + private final AbstractCredentialProvider pvpIdpCredentials; + private final IPvp2BasicConfiguration pvpBasicConfig; + + /** + * Configuration object to create PVP2 S-Profile metadata. + * + * @param basicConfig Application configuration + * @param authUrl Public-URL Prefix of the application + * @param pvpBasicConfig PVP2 configuration object + * @param pvpIdpCredentials PVP2 credentials + */ + public PvpMetadataConfiguration(IConfiguration basicConfig, String authUrl, + IPvp2BasicConfiguration pvpBasicConfig, AbstractCredentialProvider pvpIdpCredentials) { + this.authUrl = authUrl; + this.pvpIdpCredentials = pvpIdpCredentials; + this.basicConfig = basicConfig; + this.pvpBasicConfig = pvpBasicConfig; + + } + + @Override + public String getSpNameForLogging() { + return "PVP2 S-Profile IDP"; + } + + @Override + public int getMetadataValidUntil() { + return Integer.parseInt(basicConfig.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_PVP2_METADATA_VALIDITY, + String.valueOf(MsEidasNodeConstants.DEFAULT_PVP_METADATA_VALIDITY))); + + } + + @Override + public boolean buildEntitiesDescriptorAsRootElement() { + return false; + + } + + @Override + public boolean buildIdpSsoDescriptor() { + return true; + + } + + @Override + public boolean buildSpSsoDescriptor() { + return false; + + } + + @Override + public String getEntityID() { + try { + return pvpBasicConfig.getIdpEntityId(authUrl); + + } catch (final EaafException e) { + log.error("Can NOT build PVP metadata configuration.", e); + throw new RuntimeException("Can NOT build PVP metadata configuration."); + + } + + } + + @Override + public String getEntityFriendlyName() { + return null; + + } + + @Override + public List getContactPersonInformation() { + try { + return pvpBasicConfig.getIdpContacts(); + + } catch (final EaafException e) { + log.error("Can NOT build PVP metadata configuration.", e); + throw new RuntimeException("Can NOT build PVP metadata configuration."); + + } + + } + + @Override + public Organization getOrgansiationInformation() { + try { + return pvpBasicConfig.getIdpOrganisation(); + + } catch (final EaafException e) { + log.error("Can NOT build PVP metadata configuration.", e); + throw new RuntimeException("Can NOT build PVP metadata configuration."); + + } + } + + @Override + public Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException { + return pvpIdpCredentials.getIdpMetaDataSigningCredential(); + + } + + @Override + public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException { + return pvpIdpCredentials.getIdpAssertionSigningCredential(); + + } + + @Override + public Credential getEncryptionCredentials() throws CredentialsNotAvailableException { + return null; + + } + + @Override + public String getIdpWebSsoPostBindingUrl() { + try { + return pvpBasicConfig.getIdpSsoPostService(authUrl); + + } catch (final EaafException e) { + log.error("Can NOT build PVP metadata configuration.", e); + throw new RuntimeException("Can NOT build PVP metadata configuration."); + + } + + } + + @Override + public String getIdpWebSsoRedirectBindingUrl() { + try { + return pvpBasicConfig.getIdpSsoRedirectService(authUrl); + + } catch (final EaafException e) { + log.error("Can NOT build PVP metadata configuration.", e); + throw new RuntimeException("Can NOT build PVP metadata configuration."); + + } + } + + @Override + public String getIdpSloPostBindingUrl() { + return null; + + } + + @Override + public String getIdpSloRedirectBindingUrl() { + return null; + + } + + @Override + public String getSpAssertionConsumerServicePostBindingUrl() { + return null; + + } + + @Override + public String getSpAssertionConsumerServiceRedirectBindingUrl() { + return null; + + } + + @Override + public String getSpSloPostBindingUrl() { + return null; + + } + + @Override + public String getSpSloRedirectBindingUrl() { + return null; + + } + + @Override + public String getSpSloSoapBindingUrl() { + return null; + + } + + @Override + public List getIdpPossibleAttributes() { + return PvpAttributeBuilder.buildSupportedEmptyAttributes(); + + } + + @Override + public List getIdpPossibleNameIdTypes() { + return Arrays.asList(NameIDType.PERSISTENT, + NameIDType.TRANSIENT, + NameIDType.UNSPECIFIED); + } + + @Override + public List getSpRequiredAttributes() { + return null; + + } + + @Override + public List getSpAllowedNameIdTypes() { + return null; + + } + + @Override + public boolean wantAssertionSigned() { + return false; + + } + + @Override + public boolean wantAuthnRequestSigned() { + return true; + + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java index 97842262..81ab02ce 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2019 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.config; import java.net.MalformedURLException; @@ -33,129 +34,164 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.thymeleaf.templateresolver.FileTemplateResolver; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; /** + * Spring configurator for Web resources. + * * @author tlenz * */ @Configuration @EnableWebMvc -public class StaticResourceConfiguration extends WebMvcConfigurerAdapter { - private static final Logger log = LoggerFactory.getLogger(StaticResourceConfiguration.class); - private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { - "/" - }; - - private static final String DEFAULT_MESSAGE_SOURCE = "classpath:properties/status_messages"; - - @Autowired private IConfiguration basicConfig; - - - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - String staticResources = basicConfig.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_WEBCONTENT_STATIC_PATH); - try { - if (StringUtils.isNotEmpty(staticResources)) { - String absPath = FileUtils.makeAbsoluteUrl(staticResources , basicConfig.getConfigurationRootDirectory()); - if (!absPath.endsWith("/")) - absPath += "/"; - - registry.addResourceHandler("/static/**").addResourceLocations(absPath); - log.info("Add Ressourcefolder: " + absPath + " for static Web content"); - - } else - log.debug("No Ressourcefolder for static Web content"); - - } catch (MalformedURLException e) { - log.warn("Can NOT initialize ressourcefolder for static Web content", e); - - } - - registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); - - } - - @Bean - public ReloadableResourceBundleMessageSource internalMessageSource(){ - final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); - - //add default message source - messageSource.setBasename(DEFAULT_MESSAGE_SOURCE); - messageSource.setDefaultEncoding("UTF-8"); - return messageSource; - - } - - @Bean - public ReloadableResourceBundleMessageSource messageSource(){ - final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); - messageSource.setDefaultEncoding("UTF-8"); - messageSource.setParentMessageSource(internalMessageSource()); - - final String staticResources = basicConfig.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); - try { - if (StringUtils.isNotEmpty(staticResources)) { - final String absPath = FileUtils.makeAbsoluteUrl(staticResources , basicConfig.getConfigurationRootDirectory()); - messageSource.setBasename(absPath); - - } else - log.debug("No Ressourcefolder for dynamic Web content templates"); - - } catch (final MalformedURLException e) { - log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); - - } - - return messageSource; - - } - - @Bean - public CookieLocaleResolver localeResolver(){ - final CookieLocaleResolver localeResolver = new CookieLocaleResolver(); - localeResolver.setCookieName("currentLanguage"); - localeResolver.setCookieMaxAge(3600); - return localeResolver; - } - - @Bean(name="templateResolver") - public FileTemplateResolver templateResolver() { - final String staticResources = basicConfig.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); - try { - if (StringUtils.isNotEmpty(staticResources)) { - String absPath = FileUtils.makeAbsoluteUrl(staticResources , basicConfig.getConfigurationRootDirectory()); - if (!absPath.endsWith("/")) - absPath += "/"; - - if (absPath.startsWith("file:")) - absPath = absPath.substring("file:".length()); - - final FileTemplateResolver viewResolver = new FileTemplateResolver(); - viewResolver.setPrefix(absPath); - viewResolver.setSuffix(".html"); - viewResolver.setTemplateMode("HTML5"); - viewResolver.setCacheable(false); - - log.info("Add Ressourcefolder: " + absPath + " for dynamic Web content templates"); - return viewResolver ; - - } else - log.debug("No Ressourcefolder for dynamic Web content templates"); - - } catch (final MalformedURLException e) { - log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); - - } - - //TODO: implement some backup solution - return null; - - } +public class StaticResourceConfiguration implements WebMvcConfigurer { + private static final Logger log = LoggerFactory.getLogger(StaticResourceConfiguration.class); + private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { + "/" + }; + + private static final String DEFAULT_MESSAGE_SOURCE = "classpath:properties/status_messages"; + + @Autowired + private IConfiguration basicConfig; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + final String staticResources = basicConfig.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_STATIC_PATH); + try { + if (StringUtils.isNotEmpty(staticResources)) { + String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig + .getConfigurationRootDirectory()); + if (!absPath.endsWith("/")) { + absPath += "/"; + } + + registry.addResourceHandler("/static/**").addResourceLocations(absPath); + log.info("Add Ressourcefolder: " + absPath + " for static Web content"); + + } else { + log.debug("No Ressourcefolder for static Web content"); + } + + } catch (final MalformedURLException e) { + log.warn("Can NOT initialize ressourcefolder for static Web content", e); + + } + + registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); + + } + + /** + * Internal i18n message source. + * + * @return + */ + @Bean + public ReloadableResourceBundleMessageSource internalMessageSource() { + final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + + // add default message source + messageSource.setBasename(DEFAULT_MESSAGE_SOURCE); + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + + } + + /** + * External i18n message source. + * + * @return + */ + @Bean + public ReloadableResourceBundleMessageSource messageSource() { + final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setParentMessageSource(internalMessageSource()); + + final String staticResources = basicConfig.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); + try { + if (StringUtils.isNotEmpty(staticResources)) { + final String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig + .getConfigurationRootDirectory()); + messageSource.setBasename(absPath); + + } else { + log.debug("No Ressourcefolder for dynamic Web content templates"); + } + + } catch (final MalformedURLException e) { + log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); + + } + + return messageSource; + + } + + /** + * Cookie based i18n language selector. + * + * @return + */ + @Bean + public CookieLocaleResolver localeResolver() { + final CookieLocaleResolver localeResolver = new CookieLocaleResolver(); + localeResolver.setCookieName("currentLanguage"); + localeResolver.setCookieMaxAge(3600); + return localeResolver; + } + + + /** + * Thymeleaf based template resolver. + * + * @return + */ + @Bean(name = "templateResolver") + public FileTemplateResolver templateResolver() { + final String staticResources = basicConfig.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); + try { + if (StringUtils.isNotEmpty(staticResources)) { + String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig + .getConfigurationRootDirectory()); + if (!absPath.endsWith("/")) { + absPath += "/"; + } + + if (absPath.startsWith("file:")) { + absPath = absPath.substring("file:".length()); + } + + final FileTemplateResolver viewResolver = new FileTemplateResolver(); + viewResolver.setPrefix(absPath); + viewResolver.setSuffix(".html"); + viewResolver.setTemplateMode("HTML5"); + viewResolver.setCacheable(false); + + log.info("Add Ressourcefolder: " + absPath + " for dynamic Web content templates"); + return viewResolver; + + } else { + log.debug("No Ressourcefolder for dynamic Web content templates"); + } + + } catch (final MalformedURLException e) { + log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); + + } + + // TODO: implement some backup solution + return null; + + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java index 14095ffc..2776ec53 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.controller; import java.io.IOException; @@ -42,7 +43,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; @@ -56,197 +57,225 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; @Controller public class MonitoringController { - private static final Logger log = LoggerFactory.getLogger(MonitoringController.class); - - private static final String MESSAGE_OK = "OK"; - private static final String MESSAGE_ERROR = "ERROR"; - private static final String MESSAGE_SKIPPED = "SKIPPED"; - - private static final String TEST_STORAGE = "Storage: "; - private static final String TEST_CONFIG = "Config: "; - private static final String TEST_PVPMETADATA = "PVP_metadata: "; - private static final String TEST_EIDASNODEMETADATA = "eIDASNode_metadata: "; - - @Autowired private ITransactionStorage storage; - @Autowired private IConfigurationWithSP config; - - @Autowired private PvpMetadataBuilder metadatabuilder; - @Autowired private IPvpMetadataConfigurationFactory configFactory; - private AbstractCredentialProvider pvpIDPCredentials; - - /** - * Sets a specific credential provider for PVP S-Profile IDP component. - * @param pvpIDPCredentials credential provider - */ - public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) { - this.pvpIDPCredentials = pvpIDPCredentials; - - } - - @ExceptionHandler({Throwable.class}) - public void genericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException { - log.error("Monitoring Servlet receives an error." , exception); - resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); - resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - resp.getWriter().write("Reason: " - + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage()))); - return; - - } - - @RequestMapping(value = {MSeIDASNodeConstants.ENDPOINT_MONITORING_MONITOR}, - method = {RequestMethod.GET} ) - public void startFullTest(HttpServletRequest req, HttpServletResponse resp) throws IOException { - resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); - - try { - testConfig(); - testStorage(); - testPVPMetadata(); - testEidasNodeMetadata(); - resp.setStatus(HttpServletResponse.SC_OK); - resp.getWriter().write(MESSAGE_OK); - - } catch (Exception e) { - resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - resp.getWriter().write(MESSAGE_ERROR); - - } - - - } - - @RequestMapping(value = {MSeIDASNodeConstants.ENDPOINT_MONITORING_VERIFY}, - method = {RequestMethod.GET} ) - - public void startSingleTests(HttpServletRequest req, HttpServletResponse resp) throws IOException { - String result = StringUtils.EMPTY; - try { - result += testConfig() + "
"; - } catch (Exception e) { - result += e.getMessage() + "
"; - } - - try { - result += testStorage() + "
"; - } catch (Exception e) { - result += e.getMessage() + "
"; - } - - try { - result += testPVPMetadata() + "
"; - } catch (Exception e) { - result += e.getMessage() + "
"; - } - - try { - result += testEidasNodeMetadata() + "
"; - } catch (Exception e) { - result += e.getMessage() + "
"; - } - - resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); - resp.setStatus(HttpServletResponse.SC_OK); - resp.getWriter().write(result); - - } - - private String testStorage( ) throws Exception { - try { - String key = Random.nextHexRandom16(); - String value = Random.nextHexRandom16(); - - storage.put(key, value, -1); - String result = storage.get(key, String.class); - storage.remove(key); - - if (result != null && result.equals(value)) - return TEST_STORAGE + MESSAGE_OK; - else - log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test"); - - } catch (EaafException e) { - log.warn("Montioring: Can not read/write to storage.", e); - - } - - throw new Exception(TEST_STORAGE + MESSAGE_ERROR); - - } - - private String testConfig( ) throws Exception { - try { - if (config.getBasicConfigurationWithPrefix(MSeIDASNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) != null - && config.getBasicConfigurationWithPrefix(MSeIDASNodeConstants.PROP_CONFIG_SP_LIST_PREFIX).size() > 0) - return TEST_CONFIG + MESSAGE_OK; - - else - log.warn("Montioring: Can not read from configuration file."); - - } catch (Exception e) { - log.warn("Montioring: Can not read from configuration file.", e); - } - - throw new Exception(TEST_CONFIG + MESSAGE_ERROR); - - } - - private String testPVPMetadata() throws Exception { - try { - //build metadata - IPvpMetadataBuilderConfiguration metadataConfig = - configFactory.generateMetadataBuilderConfiguration( - "http://localhost/monitoring", - pvpIDPCredentials); - metadatabuilder.buildPvpMetadata(metadataConfig); - return TEST_PVPMETADATA + MESSAGE_OK; - - } catch (Exception | TransformerFactoryConfigurationError e) { - log.warn("Monitoring: Has an error in '" + TEST_PVPMETADATA + "': " + e.getMessage(), e); - throw new Exception(TEST_PVPMETADATA + MESSAGE_ERROR, e); - - } - - } - - private String testEidasNodeMetadata() throws Exception { - try { - String urlString = config.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL); - if (StringUtils.isEmpty(urlString)) { - log.debug("No eIDASNode metadata URL. Skipping test ... "); - return TEST_EIDASNODEMETADATA + MESSAGE_SKIPPED; - - } - - //create HTTP client - //TODO: update if we switch to openSAML3 - HttpClient httpClient = new HttpClient(); - - //set parameters - HttpClientParams params = new HttpClientParams(); - params.setSoTimeout(5*1000); - httpClient.setParams(params ); - - //request URL - HttpMethod method = new GetMethod(urlString); - int respCode = httpClient.executeMethod(method); - if (respCode != 200) { - log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + " HTTP responsecode: " + respCode); - throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR); - - } - - //parse metadata - DomUtils.parseXmlNonValidating(method.getResponseBodyAsStream()); - - return TEST_EIDASNODEMETADATA + MESSAGE_OK; - - } catch (Exception | TransformerFactoryConfigurationError e) { - log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + e.getMessage(), e); - throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR, e); - - } - - } - + private static final Logger log = LoggerFactory.getLogger(MonitoringController.class); + + private static final String MESSAGE_OK = "OK"; + private static final String MESSAGE_ERROR = "ERROR"; + private static final String MESSAGE_SKIPPED = "SKIPPED"; + + private static final String TEST_STORAGE = "Storage: "; + private static final String TEST_CONFIG = "Config: "; + private static final String TEST_PVPMETADATA = "PVP_metadata: "; + private static final String TEST_EIDASNODEMETADATA = "eIDASNode_metadata: "; + + @Autowired + private ITransactionStorage storage; + @Autowired + private IConfigurationWithSP config; + + @Autowired + private PvpMetadataBuilder metadatabuilder; + @Autowired + private IPvpMetadataConfigurationFactory configFactory; + private AbstractCredentialProvider pvpIdpCredentials; + + /** + * Sets a specific credential provider for PVP S-Profile IDP component. + * + * @param pvpIdpCredentials credential provider + */ + public void setPvpIdpCredentials(AbstractCredentialProvider pvpIdpCredentials) { + this.pvpIdpCredentials = pvpIdpCredentials; + + } + + /** + * Generic exception handling that wrote an error-message to html response. + * + * @param resp Http response object + * @param exception Error + * @throws IOException In case of a html response error. + */ + @ExceptionHandler({ Throwable.class }) + public void genericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException { + log.error("Monitoring Servlet receives an error.", exception); + resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + resp.getWriter().write("Reason: " + + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage()))); + + } + + /** + * MS-Connector status-monitoring end-point. + * + * @param req http request + * @param resp http response + * @throws IOException In case of a general processing error + */ + @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_MONITOR }, + method = { RequestMethod.GET }) + public void startFullTest(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); + + try { + testConfig(); + testStorage(); + testPvpMetadata(); + testEidasNodeMetadata(); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().write(MESSAGE_OK); + + } catch (final Exception e) { + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + resp.getWriter().write(MESSAGE_ERROR); + + } + + } + + /** + * MS-Connector internal verify monitoring end-point. + * + * @param req http request object + * @param resp http response object + * @throws IOException In case of an internal processing error + */ + @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_VERIFY }, + method = { RequestMethod.GET }) + + public void startSingleTests(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String result = StringUtils.EMPTY; + try { + result += testConfig() + "
"; + } catch (final Exception e) { + result += e.getMessage() + "
"; + } + + try { + result += testStorage() + "
"; + } catch (final Exception e) { + result += e.getMessage() + "
"; + } + + try { + result += testPvpMetadata() + "
"; + } catch (final Exception e) { + result += e.getMessage() + "
"; + } + + try { + result += testEidasNodeMetadata() + "
"; + } catch (final Exception e) { + result += e.getMessage() + "
"; + } + + resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().write(result); + + } + + private String testStorage() throws Exception { + try { + final String key = Random.nextHexRandom16(); + final String value = Random.nextHexRandom16(); + + storage.put(key, value, -1); + final String result = storage.get(key, String.class); + storage.remove(key); + + if (result != null && result.equals(value)) { + return TEST_STORAGE + MESSAGE_OK; + } else { + log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test"); + } + + } catch (final EaafException e) { + log.warn("Montioring: Can not read/write to storage.", e); + + } + + throw new Exception(TEST_STORAGE + MESSAGE_ERROR); + + } + + private String testConfig() throws Exception { + try { + if (config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) != null + && config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) + .size() > 0) { + return TEST_CONFIG + MESSAGE_OK; + } else { + log.warn("Montioring: Can not read from configuration file."); + } + + } catch (final Exception e) { + log.warn("Montioring: Can not read from configuration file.", e); + } + + throw new Exception(TEST_CONFIG + MESSAGE_ERROR); + + } + + private String testPvpMetadata() throws Exception { + try { + // build metadata + final IPvpMetadataBuilderConfiguration metadataConfig = + configFactory.generateMetadataBuilderConfiguration( + "http://localhost/monitoring", + pvpIdpCredentials); + metadatabuilder.buildPvpMetadata(metadataConfig); + return TEST_PVPMETADATA + MESSAGE_OK; + + } catch (Exception | TransformerFactoryConfigurationError e) { + log.warn("Monitoring: Has an error in '" + TEST_PVPMETADATA + "': " + e.getMessage(), e); + throw new Exception(TEST_PVPMETADATA + MESSAGE_ERROR, e); + + } + + } + + private String testEidasNodeMetadata() throws Exception { + try { + final String urlString = config.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL); + if (StringUtils.isEmpty(urlString)) { + log.debug("No eIDASNode metadata URL. Skipping test ... "); + return TEST_EIDASNODEMETADATA + MESSAGE_SKIPPED; + + } + + // create HTTP client + // TODO: update if we switch to openSAML3 + final HttpClient httpClient = new HttpClient(); + + // set parameters + final HttpClientParams params = new HttpClientParams(); + params.setSoTimeout(5 * 1000); + httpClient.setParams(params); + + // request URL + final HttpMethod method = new GetMethod(urlString); + final int respCode = httpClient.executeMethod(method); + if (respCode != 200) { + log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + " HTTP responsecode: " + + respCode); + throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR); + + } + + // parse metadata + DomUtils.parseXmlNonValidating(method.getResponseBodyAsStream()); + + return TEST_EIDASNODEMETADATA + MESSAGE_OK; + + } catch (Exception | TransformerFactoryConfigurationError e) { + log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + e.getMessage(), e); + throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR, e); + + } + + } + } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/PVP2SProfileEndpoint.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/PVP2SProfileEndpoint.java deleted file mode 100644 index 19230c62..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/PVP2SProfileEndpoint.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AbstractPvp2XProtocol; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest; - -@Controller -public class PVP2SProfileEndpoint extends AbstractPvp2XProtocol{ - - public static final String NAME = PVP2SProfileEndpoint.class.getName(); - public static final String PROTOCOL_ID = "pvp2-s"; - - @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_METADATA, method = {RequestMethod.POST, RequestMethod.GET}) - public void PVPMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { - super.pvpMetadataRequest(req, resp); - - } - - @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_POST, method = {RequestMethod.POST}) - public void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { - super.pvpIdpPostRequest(req, resp); - - } - - @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_REDIRECT, method = {RequestMethod.GET}) - public void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { - super.pvpIdpRedirecttRequest(req, resp); - - } - - - @Override - public String getAuthProtocolIdentifier() { - return PROTOCOL_ID; - } - - @Override - public String getName() { - return NAME; - } - - @Override - protected boolean childPreProcess(HttpServletRequest arg0, HttpServletResponse arg1, PvpSProfilePendingRequest arg2) - throws Throwable { - return false; - } - - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/ProcessEngineSignalController.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/ProcessEngineSignalController.java index bb98f483..1bf1ad67 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/ProcessEngineSignalController.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/ProcessEngineSignalController.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.controller; import java.io.IOException; @@ -31,23 +32,26 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController; /** + * Default process-engine signaling controller. + * * @author tlenz * */ @Controller public class ProcessEngineSignalController extends AbstractProcessEngineSignalController { - - @RequestMapping(value = {MSeIDASNodeConstants.ENDPOINT_COUNTRYSELECTION - }, - method = {RequestMethod.POST, RequestMethod.GET}) - public void performGenericAuthenticationProcess(HttpServletRequest req, HttpServletResponse resp) throws IOException, EaafException { - signalProcessManagement(req, resp); - - } + + @RequestMapping(value = { + MsEidasNodeConstants.ENDPOINT_COUNTRYSELECTION + }, + method = { RequestMethod.POST, RequestMethod.GET }) + public void performGenericAuthenticationProcess(HttpServletRequest req, HttpServletResponse resp) + throws IOException, EaafException { + signalProcessManagement(req, resp); + + } } - \ No newline at end of file diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/Pvp2SProfileEndpoint.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/Pvp2SProfileEndpoint.java new file mode 100644 index 00000000..d2ec5a7c --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/Pvp2SProfileEndpoint.java @@ -0,0 +1,80 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.controller; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AbstractPvp2XProtocol; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest; + +@Controller +public class Pvp2SProfileEndpoint extends AbstractPvp2XProtocol { + + public static final String NAME = Pvp2SProfileEndpoint.class.getName(); + public static final String PROTOCOL_ID = "pvp2-s"; + + @RequestMapping(value = MsEidasNodeConstants.ENDPOINT_PVP_METADATA, method = { RequestMethod.POST, + RequestMethod.GET }) + public void pvpMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { + super.pvpMetadataRequest(req, resp); + + } + + @RequestMapping(value = MsEidasNodeConstants.ENDPOINT_PVP_POST, method = { RequestMethod.POST }) + public void pvpIdpPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { + super.pvpIdpPostRequest(req, resp); + + } + + @RequestMapping(value = MsEidasNodeConstants.ENDPOINT_PVP_REDIRECT, method = { RequestMethod.GET }) + public void pvpIdpRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EaafException { + super.pvpIdpRedirecttRequest(req, resp); + + } + + @Override + public String getAuthProtocolIdentifier() { + return PROTOCOL_ID; + } + + @Override + public String getName() { + return NAME; + } + + @Override + protected boolean childPreProcess(HttpServletRequest arg0, HttpServletResponse arg1, + PvpSProfilePendingRequest arg2) + throws Throwable { + return false; + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/interceptor/WebFrontEndSecurityInterceptor.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/interceptor/WebFrontEndSecurityInterceptor.java index e60b535c..d90cd22b 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/interceptor/WebFrontEndSecurityInterceptor.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/interceptor/WebFrontEndSecurityInterceptor.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.interceptor; import javax.servlet.http.HttpServletRequest; @@ -29,47 +30,61 @@ import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** + * Spring interceptor to inject securtiy headers into http response. + * * @author tlenz * */ public class WebFrontEndSecurityInterceptor implements HandlerInterceptor { - - /* (non-Javadoc) - * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) - */ - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - //set security headers - response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT"); - response.setHeader("Pragma", "no-cache"); - response.setHeader("Cache-control", "no-store, no-cache, must-revalidate"); - - return true; - - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet. + * http.HttpServletRequest, javax.servlet.http.HttpServletResponse, + * java.lang.Object) + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + + // set security headers + response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Cache-control", "no-store, no-cache, must-revalidate"); - /* (non-Javadoc) - * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView) - */ - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, - ModelAndView modelAndView) throws Exception { + return true; - - + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet. + * http.HttpServletRequest, javax.servlet.http.HttpServletResponse, + * java.lang.Object, org.springframework.web.servlet.ModelAndView) + */ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { - } + } - /* (non-Javadoc) - * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception) - */ - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { + /* + * (non-Javadoc) + * + * @see + * org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax. + * servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, + * java.lang.Object, java.lang.Exception) + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + Exception ex) + throws Exception { - } + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/RevisionLogger.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/RevisionLogger.java index faaf1e57..16385e10 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/RevisionLogger.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/RevisionLogger.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.logger; import java.util.Date; @@ -28,7 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.components.eventlog.api.Event; import at.gv.egiz.components.eventlog.api.EventConstants; import at.gv.egiz.components.eventlog.api.EventLogFactory; @@ -39,68 +40,71 @@ import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger; public class RevisionLogger extends EventLogFactory implements IRevisionLogger { - private static final Logger log = LoggerFactory.getLogger(RevisionLogger.class); - - @Autowired private IConfiguration basicConfig; - - @Override - public void logEvent(ISpConfiguration oaConfig, int eventCode, String message) { - logEvent(createNewEvent(new Date().getTime(), eventCode, message)); - - } - - @Override - public void logEvent(IRequest pendingRequest, int eventCode) { - logEvent(createNewEvent(new Date().getTime(), eventCode, - pendingRequest.getUniqueSessionIdentifier(), pendingRequest.getUniqueTransactionIdentifier())); - - } - - @Override - public void logEvent(IRequest pendingRequest, int eventCode, String message) { - logEvent(createNewEvent(new Date().getTime(), eventCode, message, - pendingRequest.getUniqueSessionIdentifier(), pendingRequest.getUniqueTransactionIdentifier())); - - } - - @Override - public void logEvent(int eventCode, String message) { - logEvent(createNewEvent(new Date().getTime(), eventCode, message)); - - } - - @Override - public void logEvent(String sessionID, String transactionID, int eventCode, String message) { - logEvent(createNewEvent(new Date().getTime(), eventCode, message, sessionID, transactionID)); - - } - - @Override - public void logEvent(String sessionID, String transactionID, int eventCode) { - logEvent(createNewEvent(new Date().getTime(), eventCode, sessionID, transactionID)); - - } - - private void logEvent(Event event) { - try { - if (event.getEventCode() >= 1100) { - if ( (event.getEventCode() == EventConstants.TRANSACTION_IP) - && !basicConfig.getBasicConfigurationBoolean( - MSeIDASNodeConstants.PROP_CONFIG_REVISIONLOG_LOG_IP_ADDRESS_OF_USER, true) ) { - log.trace("Ignore Event: " + event.getEventCode() + " because IP adresse logging prohibited"); - return; - - } - - getEventLog().logEvent(event); - - } else - log.trace("Ignore Event: " + event.getEventCode() + " because session functionallity is not implemented"); - - } catch (EventLoggingException e) { - log.warn("Event logging FAILED! Reason: " + e.getMessage()); - - } - - } + private static final Logger log = LoggerFactory.getLogger(RevisionLogger.class); + + @Autowired + private IConfiguration basicConfig; + + @Override + public void logEvent(ISpConfiguration oaConfig, int eventCode, String message) { + logEvent(createNewEvent(new Date().getTime(), eventCode, message)); + + } + + @Override + public void logEvent(IRequest pendingRequest, int eventCode) { + logEvent(createNewEvent(new Date().getTime(), eventCode, + pendingRequest.getUniqueSessionIdentifier(), pendingRequest.getUniqueTransactionIdentifier())); + + } + + @Override + public void logEvent(IRequest pendingRequest, int eventCode, String message) { + logEvent(createNewEvent(new Date().getTime(), eventCode, message, + pendingRequest.getUniqueSessionIdentifier(), pendingRequest.getUniqueTransactionIdentifier())); + + } + + @Override + public void logEvent(int eventCode, String message) { + logEvent(createNewEvent(new Date().getTime(), eventCode, message)); + + } + + @Override + public void logEvent(String sessionID, String transactionID, int eventCode, String message) { + logEvent(createNewEvent(new Date().getTime(), eventCode, message, sessionID, transactionID)); + + } + + @Override + public void logEvent(String sessionID, String transactionID, int eventCode) { + logEvent(createNewEvent(new Date().getTime(), eventCode, sessionID, transactionID)); + + } + + private void logEvent(Event event) { + try { + if (event.getEventCode() >= 1100) { + if (event.getEventCode() == EventConstants.TRANSACTION_IP + && !basicConfig.getBasicConfigurationBoolean( + MsEidasNodeConstants.PROP_CONFIG_REVISIONLOG_LOG_IP_ADDRESS_OF_USER, true)) { + log.trace("Ignore Event: " + event.getEventCode() + " because IP adresse logging prohibited"); + return; + + } + + getEventLog().logEvent(event); + + } else { + log.trace("Ignore Event: " + event.getEventCode() + + " because session functionallity is not implemented"); + } + + } catch (final EventLoggingException e) { + log.warn("Event logging FAILED! Reason: " + e.getMessage()); + + } + + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/StatisticLogger.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/StatisticLogger.java index e742c748..3483f367 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/StatisticLogger.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/logger/StatisticLogger.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.logger; import org.apache.commons.lang3.StringUtils; @@ -27,7 +28,7 @@ import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger; @@ -35,104 +36,106 @@ import at.gv.egiz.eaaf.core.exceptions.EaafException; public class StatisticLogger implements IStatisticLogger { - private static final Logger log = LoggerFactory.getLogger(StatisticLogger.class); - - private static final String DATEFORMATER = "yyyy.MM.dd-HH:mm:ss+z"; - private static final String STATUS_SUCCESS = "success"; - private static final String STATUS_ERROR = "error"; - - @Override - public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession) { - log.info(buildLogMessage( - protocolRequest.getUniqueTransactionIdentifier(), - protocolRequest.getSpEntityId(), - protocolRequest.getRawData(MSeIDASNodeConstants.DATA_REQUESTERID), - protocolRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), - authData.getCiticenCountryCode(), - STATUS_SUCCESS , - StringUtils.EMPTY, - StringUtils.EMPTY)); - - - } - - @Override - public void logErrorOperation(Throwable throwable) { - String errorId = "TODO"; - if (throwable instanceof EaafException) - errorId = ((EaafException) throwable).getErrorId(); - - log.info(buildLogMessage( - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - STATUS_ERROR, - errorId, - throwable.getMessage())); - - - } - - @Override - public void logErrorOperation(Throwable throwable, IRequest errorRequest) { - String errorId = "TODO"; - if (throwable instanceof EaafException) - errorId = ((EaafException) throwable).getErrorId(); - - if (errorRequest != null) - log.info(buildLogMessage( - errorRequest.getUniqueTransactionIdentifier(), - errorRequest.getSpEntityId(), - errorRequest.getRawData(MSeIDASNodeConstants.DATA_REQUESTERID), - errorRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), - StringUtils.EMPTY, - STATUS_ERROR, - errorId, - throwable.getMessage())); - - else - log.info(buildLogMessage( - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - StringUtils.EMPTY, - STATUS_ERROR, - errorId, - throwable.getMessage())); - - } - - @Override - public void internalTesting() throws Exception { - log.trace("Not implemented for a File-based logger"); - - } - - private String buildLogMessage(String tId, String moaIDEntityId, Object requesterId, String target, String cc, - String status, String errorCode, String errorMsg) { - String logMsg = StringUtils.EMPTY; - - //data,tId,MOAID-Id,SP-Id,bPKTarget,CC,status,error-code,error-msg - - logMsg += DateTime.now().toString(DATEFORMATER ) + ","; - logMsg += tId + ","; - logMsg += moaIDEntityId + ","; - - if (requesterId instanceof String && StringUtils.isNotEmpty((String)requesterId)) - logMsg += (String)requesterId + ","; - else - logMsg += StringUtils.EMPTY + ","; - - logMsg += target + ","; - logMsg += cc + ","; - - logMsg += status + ","; - logMsg += errorCode + ","; - logMsg += errorMsg; - - return logMsg; - } + private static final Logger log = LoggerFactory.getLogger(StatisticLogger.class); + + private static final String DATEFORMATER = "yyyy.MM.dd-HH:mm:ss+z"; + private static final String STATUS_SUCCESS = "success"; + private static final String STATUS_ERROR = "error"; + + @Override + public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSsoSession) { + log.info(buildLogMessage( + protocolRequest.getUniqueTransactionIdentifier(), + protocolRequest.getSpEntityId(), + protocolRequest.getRawData(MsEidasNodeConstants.DATA_REQUESTERID), + protocolRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), + authData.getCiticenCountryCode(), + STATUS_SUCCESS, + StringUtils.EMPTY, + StringUtils.EMPTY)); + + } + + @Override + public void logErrorOperation(Throwable throwable) { + String errorId = "TODO"; + if (throwable instanceof EaafException) { + errorId = ((EaafException) throwable).getErrorId(); + } + + log.info(buildLogMessage( + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + STATUS_ERROR, + errorId, + throwable.getMessage())); + + } + + @Override + public void logErrorOperation(Throwable throwable, IRequest errorRequest) { + String errorId = "TODO"; + if (throwable instanceof EaafException) { + errorId = ((EaafException) throwable).getErrorId(); + } + + if (errorRequest != null) { + log.info(buildLogMessage( + errorRequest.getUniqueTransactionIdentifier(), + errorRequest.getSpEntityId(), + errorRequest.getRawData(MsEidasNodeConstants.DATA_REQUESTERID), + errorRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), + StringUtils.EMPTY, + STATUS_ERROR, + errorId, + throwable.getMessage())); + } else { + log.info(buildLogMessage( + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + StringUtils.EMPTY, + STATUS_ERROR, + errorId, + throwable.getMessage())); + } + + } + + @Override + public void internalTesting() throws Exception { + log.trace("Not implemented for a File-based logger"); + + } + + private String buildLogMessage(String transId, String entityId, Object requesterId, String target, + String cc, + String status, String errorCode, String errorMsg) { + String logMsg = StringUtils.EMPTY; + + // data,tId,MOAID-Id,SP-Id,bPKTarget,CC,status,error-code,error-msg + + logMsg += DateTime.now().toString(DATEFORMATER) + ","; + logMsg += transId + ","; + logMsg += entityId + ","; + + if (requesterId instanceof String && StringUtils.isNotEmpty((String) requesterId)) { + logMsg += (String) requesterId + ","; + } else { + logMsg += StringUtils.EMPTY + ","; + } + + logMsg += target + ","; + logMsg += cc + ","; + + logMsg += status + ","; + logMsg += errorCode + ","; + logMsg += errorMsg; + + return logMsg; + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/mapper/LoALevelMapper.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/mapper/LoALevelMapper.java index f92ccf28..564160be 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/mapper/LoALevelMapper.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/mapper/LoALevelMapper.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.mapper; import org.slf4j.Logger; @@ -32,30 +31,30 @@ import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper; @Service("LoALevelMapper") -public class LoALevelMapper implements ILoALevelMapper{ - private static final Logger log = LoggerFactory.getLogger(LoALevelMapper.class); - - @Override - public String mapToSecClass(String LoA) { - log.info("Mapping to PVP SecClass is NOT supported"); - return null; - } - - @Override - public String mapToEidasLoa(String LoA) { - if (LoA.startsWith(EaafConstants.EIDAS_LOA_PREFIX)) - return LoA; - - else - log.info("Can NOT map '" + LoA + "' to eIDAS LoA"); - - return null; - - } - - @Override - public String mapEidasQaaToStorkQaa(String eidasqaaLevel) { - return null; - } +public class LoALevelMapper implements ILoALevelMapper { + private static final Logger log = LoggerFactory.getLogger(LoALevelMapper.class); + + @Override + public String mapToSecClass(String loa) { + log.info("Mapping to PVP SecClass is NOT supported"); + return null; + } + + @Override + public String mapToEidasLoa(String loa) { + if (loa.startsWith(EaafConstants.EIDAS_LOA_PREFIX)) { + return loa; + } else { + log.info("Can NOT map '" + loa + "' to eIDAS LoA"); + } + + return null; + + } + + @Override + public String mapEidasQaaToStorkQaa(String eidasqaaLevel) { + return null; + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/CountrySelectionProcessImpl.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/CountrySelectionProcessImpl.java index e4492a3f..805148f7 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/CountrySelectionProcessImpl.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/CountrySelectionProcessImpl.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,47 +19,50 @@ * 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.asitplus.eidas.specific.connector.processes; import org.apache.commons.lang3.StringUtils; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; /** + * Auth-Process selector for User's country selection. + * * @author tlenz * */ public class CountrySelectionProcessImpl implements AuthModule { - @Override - public int getPriority() { - return 0; - - } + @Override + public int getPriority() { + return 0; + + } + + @Override + public String selectProcess(ExecutionContext context, IRequest pendingReq) { + final Object selectedCountryObj = context.get(MsEidasNodeConstants.REQ_PARAM_SELECTED_COUNTRY); + if (selectedCountryObj != null && selectedCountryObj instanceof String) { + final String selectedCountry = (String) selectedCountryObj; + if (StringUtils.isNotEmpty(selectedCountry)) { + return null; + } + + } + + return "CountrySelectionProcess"; + + } - @Override - public String selectProcess(ExecutionContext context, IRequest pendingReq) { - Object selectedCountryObj = context.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY); - if (selectedCountryObj != null && selectedCountryObj instanceof String) { - String selectedCountry = (String) selectedCountryObj; - if (StringUtils.isNotEmpty(selectedCountry)) - return null; - - } - - return "CountrySelectionProcess"; - - - } + @Override + public String[] getProcessDefinitions() { + return new String[] { "classpath:processes/CountrySelection.process.xml" }; - @Override - public String[] getProcessDefinitions() { - return new String[] { "classpath:processes/CountrySelection.process.xml" }; - - } + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java index 9a91d407..727653b3 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.processes.tasks; import java.util.Enumeration; @@ -33,48 +34,50 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.controller.tasks.AbstractLocaleAuthServletTask; /** + * Evaluate the User's country selection. + * * @author tlenz * */ @Component("EvaluateCountrySelectionTask") -public class EvaluateCountrySelectionTask extends AbstractLocaleAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(EvaluateCountrySelectionTask.class); - - - @Override - public void executeWithLocale(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - try { - - // set parameter execution context - Enumeration reqParamNames = request.getParameterNames(); - while(reqParamNames.hasMoreElements()) { - String paramName = reqParamNames.nextElement(); - if (StringUtils.isNotEmpty(paramName) && - !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName)) { - for (String el : MSeIDASNodeConstants.COUNTRY_SELECTION_PARAM_WHITELIST) { - if (el.equalsIgnoreCase(paramName)) - executionContext.put(paramName, - StringEscapeUtils.escapeHtml(request.getParameter(paramName))); - } - } - } - - log.info("Country selection finished. Starting auth. process for country ... "); - - - } catch (Exception e) { - log.warn("EvaluateBKUSelectionTask has an internal error", e); - throw new TaskExecutionException(pendingReq, e.getMessage(), e); - - } - } +public class EvaluateCountrySelectionTask extends AbstractLocaleAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(EvaluateCountrySelectionTask.class); + + @Override + public void executeWithLocale(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) + throws TaskExecutionException { + try { + + // set parameter execution context + final Enumeration reqParamNames = request.getParameterNames(); + while (reqParamNames.hasMoreElements()) { + final String paramName = reqParamNames.nextElement(); + if (StringUtils.isNotEmpty(paramName) + && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName)) { + for (final String el : MsEidasNodeConstants.COUNTRY_SELECTION_PARAM_WHITELIST) { + if (el.equalsIgnoreCase(paramName)) { + executionContext.put(paramName, + StringEscapeUtils.escapeHtml(request.getParameter(paramName))); + } + } + } + } + + log.info("Country selection finished. Starting auth. process for country ... "); + + } catch (final Exception e) { + log.warn("EvaluateBKUSelectionTask has an internal error", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java index 5f3fb20a..bf7453de 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.processes.tasks; import javax.servlet.http.HttpServletRequest; @@ -30,8 +31,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsConnectorEventCodes; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; import at.gv.egiz.eaaf.core.api.gui.IGuiBuilderConfiguration; import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder; @@ -43,42 +44,49 @@ import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; /** + * Create country-selection page. + * * @author tlenz * */ @Component("GenerateCountrySelectionFrameTask") public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(GenerateCountrySelectionFrameTask.class); - - @Autowired ISpringMvcGuiFormBuilder guiBuilder; - @Autowired IConfiguration basicConfig; - - @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - try { - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.STARTING_COUNTRY_SELECTION); - - IGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( - basicConfig, - pendingReq, - MSeIDASNodeConstants.TEMPLATE_HTML_COUNTRYSELECTION, - MSeIDASNodeConstants.ENDPOINT_COUNTRYSELECTION); - - guiBuilder.build(request, response, config, "BKU-Selection form"); - - } catch (GuiBuildException e) { - log.warn("Can not build GUI:'BKU-Selection'. Msg:" + e.getMessage()); - throw new TaskExecutionException(pendingReq, - "Can not build GUI. Msg:" + e.getMessage(), - new EaafException("gui.00", new Object[]{e.getMessage()}, e)); - - } catch (Exception e) { - log.warn("FinalizeAuthenticationTask has an internal error", e); - throw new TaskExecutionException(pendingReq, e.getMessage(), e); - - } - - } + private static final Logger log = LoggerFactory.getLogger(GenerateCountrySelectionFrameTask.class); + + @Autowired + ISpringMvcGuiFormBuilder guiBuilder; + @Autowired + IConfiguration basicConfig; + + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) + throws TaskExecutionException { + try { + revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.STARTING_COUNTRY_SELECTION); + + final IGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + pendingReq, + MsEidasNodeConstants.TEMPLATE_HTML_COUNTRYSELECTION, + MsEidasNodeConstants.ENDPOINT_COUNTRYSELECTION, + resourceLoader); + + guiBuilder.build(request, response, config, "BKU-Selection form"); + + } catch (final GuiBuildException e) { + log.warn("Can not build GUI:'BKU-Selection'. Msg:" + e.getMessage()); + throw new TaskExecutionException(pendingReq, + "Can not build GUI. Msg:" + e.getMessage(), + new EaafException("gui.00", new Object[] { e.getMessage() }, e)); + + } catch (final Exception e) { + log.warn("FinalizeAuthenticationTask has an internal error", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java deleted file mode 100644 index 2259acd5..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.provider; - -import java.net.MalformedURLException; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.utils.FileUtils; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; - -public class PVPEndPointCredentialProvider extends AbstractCredentialProvider { - private static final Logger log = LoggerFactory.getLogger(PVPEndPointCredentialProvider.class); - - @Autowired(required=true) IConfiguration basicConfiguration; - - @Override - public String getFriendlyName() { - return "PVP2 S-Profile EndPoint"; - } - - @Override - public String getKeyStoreFilePath() throws EaafException { - try { - String path = basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PATH); - if (StringUtils.isEmpty(path)) { - log.error(getFriendlyName() + " | Path to keyStore is NULL or EMPTY"); - throw new EaafConfigurationException("config.27", - new Object[] {getFriendlyName() + " | Path to keyStore is NULL or EMPTY"}); - - } - - return FileUtils.makeAbsoluteUrl( - path, - basicConfiguration.getConfigurationRootDirectory()); - - } catch (MalformedURLException e) { - log.error(getFriendlyName() + " | Path to keyStore NOT valid.", e); - throw new EaafConfigurationException("config.27", - new Object[] {getFriendlyName() + " | Path to keyStore NOT valid."}, e); - - } - - } - - @Override - public String getKeyStorePassword() { - return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PASSWORD); - - } - - @Override - public String getMetadataKeyAlias() { - return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_ALIAS); - } - - @Override - public String getMetadataKeyPassword() { - return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_PASSWORD); - - } - - @Override - public String getSignatureKeyAlias() { - return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_ALIAS); - - } - - @Override - public String getSignatureKeyPassword() { - return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_PASSWORD); - - } - - @Override - public String getEncryptionKeyAlias() { - return null; - - } - - @Override - public String getEncryptionKeyPassword() { - return null; - - } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java deleted file mode 100644 index 6965a407..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.provider; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import at.asitplus.eidas.specific.connector.config.PVPMetadataConfiguration; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; - -@Service("PVPMetadataConfigurationFactory") -public class PVPMetadataConfigurationFactory implements IPvpMetadataConfigurationFactory { - - @Autowired private IConfiguration basicConfig; - @Autowired private IPvp2BasicConfiguration pvpBasicConfig; - - @Override - public IPvpMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authURL, - AbstractCredentialProvider pvpIDPCredentials) { - return new PVPMetadataConfiguration(basicConfig, authURL, pvpBasicConfig, pvpIDPCredentials); - - } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataProvider.java deleted file mode 100644 index 4db6ac5a..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PVPMetadataProvider.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.provider; - -import java.io.IOException; -import java.security.cert.CertificateException; -import java.util.List; - -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.params.HttpClientParams; -import org.apache.commons.lang3.StringUtils; -import org.opensaml.saml2.metadata.provider.MetadataProvider; -import org.opensaml.xml.parse.BasicParserPool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; -import at.asitplus.eidas.specific.connector.verification.MetadataSignatureVerificationFilter; -import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; -import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.core.impl.utils.FileUtils; -import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; -import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.MetadataFilterChain; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.PvpEntityCategoryFilter; -import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter; - -@Service("PVPMetadataProvider") -public class PVPMetadataProvider extends AbstractChainingMetadataProvider{ - private static final Logger log = LoggerFactory.getLogger(PVPMetadataProvider.class); - - @Autowired(required=true) IConfigurationWithSP basicConfig; - - @Override - protected String getMetadataUrl(String entityId) throws EaafConfigurationException { - ISpConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId); - if (spConfig != null) { - String metadataURL = entityId; - - String metadataURLFromConfig = spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL); - if (StringUtils.isNotEmpty(metadataURLFromConfig)) { - log.debug("Use metdataURL from configuration for EntityId: " + entityId); - metadataURL = metadataURLFromConfig; - - } - - return metadataURL; - - } else - log.info("No ServiceProvider with entityId: " + entityId + " in configuration."); - - return null; - } - - @Override - protected MetadataProvider createNewMetadataProvider(String entityId) - throws EaafConfigurationException, IOException, CertificateException { - ISpConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId); - if (spConfig != null) { - try { - String metadataURL = spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL); - if (StringUtils.isEmpty(metadataURL)) { - log.debug("Use EntityId: " + entityId + " instead of explicite metadataURL ... "); - metadataURL = entityId; - - } - String trustStoreUrl = FileUtils.makeAbsoluteUrl( - spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE), - authConfig.getConfigurationRootDirectory()); - String trustStorePassword = spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE_PASSWORD); - - return createNewSimpleMetadataProvider(metadataURL, - buildMetadataFilterChain(spConfig, metadataURL, trustStoreUrl, trustStorePassword), - spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER), - getTimer(), - new BasicParserPool(), - createHttpClient(metadataURL)); - - } catch (Pvp2MetadataException e) { - log.info("Can NOT initialize Metadata signature-verification filter. Reason: " + e.getMessage()); - throw new EaafConfigurationException("config.27", - new Object[] {"Can NOT initialize Metadata signature-verification filter. Reason: " + e.getMessage()}, e); - - } - - } else - log.info("No ServiceProvider with entityId: " + entityId + " in configuration."); - - return null; - } - - @Override - protected List getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException { - // TODO Auto-generated method stub - return null; - } - - private HttpClient createHttpClient(String metadataURL) { - HttpClient httpClient = new HttpClient(); - HttpClientParams httpClientParams = new HttpClientParams(); - httpClientParams.setSoTimeout(MSeIDASNodeConstants.METADATA_SOCKED_TIMEOUT); - httpClient.setParams(httpClientParams); - return httpClient; - - } - - private MetadataFilterChain buildMetadataFilterChain(ISpConfiguration oaParam, String metadataURL, String trustStoreUrl, String trustStorePassword) throws CertificateException, Pvp2MetadataException{ - MetadataFilterChain filterChain = new MetadataFilterChain(); - filterChain.getFilters().add(new SchemaValidationFilter( - basicConfig.getBasicConfigurationBoolean(MSeIDASNodeConstants.PROP_CONFIG_PVP_SCHEME_VALIDATION, true))); - - filterChain.getFilters().add( - new MetadataSignatureVerificationFilter( - trustStoreUrl, trustStorePassword, metadataURL)); - - filterChain.getFilters().add(new PvpEntityCategoryFilter( - basicConfig.getBasicConfigurationBoolean(MSeIDASNodeConstants.PROP_CONFIG_PVP_ENABLE_ENTITYCATEGORIES, true))); - - return filterChain; - } -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpEndPointCredentialProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpEndPointCredentialProvider.java new file mode 100644 index 00000000..92373328 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpEndPointCredentialProvider.java @@ -0,0 +1,119 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.provider; + +import java.net.MalformedURLException; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; + +public class PvpEndPointCredentialProvider extends AbstractCredentialProvider { + private static final Logger log = LoggerFactory.getLogger(PvpEndPointCredentialProvider.class); + + @Autowired(required = true) + IConfiguration basicConfiguration; + + @Override + public String getFriendlyName() { + return "PVP2 S-Profile EndPoint"; + } + + @Override + public String getKeyStoreFilePath() throws EaafException { + try { + final String path = basicConfiguration.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PATH); + if (StringUtils.isEmpty(path)) { + log.error(getFriendlyName() + " | Path to keyStore is NULL or EMPTY"); + throw new EaafConfigurationException("config.27", + new Object[] { getFriendlyName() + " | Path to keyStore is NULL or EMPTY" }); + + } + + return FileUtils.makeAbsoluteUrl( + path, + basicConfiguration.getConfigurationRootDirectory()); + + } catch (final MalformedURLException e) { + log.error(getFriendlyName() + " | Path to keyStore NOT valid.", e); + throw new EaafConfigurationException("config.27", + new Object[] { getFriendlyName() + " | Path to keyStore NOT valid." }, e); + + } + + } + + @Override + public String getKeyStorePassword() { + return basicConfiguration.getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PASSWORD); + + } + + @Override + public String getMetadataKeyAlias() { + return basicConfiguration.getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_ALIAS); + } + + @Override + public String getMetadataKeyPassword() { + return basicConfiguration.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_PASSWORD); + + } + + @Override + public String getSignatureKeyAlias() { + return basicConfiguration.getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_ALIAS); + + } + + @Override + public String getSignatureKeyPassword() { + return basicConfiguration.getBasicConfiguration( + MsEidasNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_PASSWORD); + + } + + @Override + public String getEncryptionKeyAlias() { + return null; + + } + + @Override + public String getEncryptionKeyPassword() { + return null; + + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataConfigurationFactory.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataConfigurationFactory.java new file mode 100644 index 00000000..8b0419d0 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataConfigurationFactory.java @@ -0,0 +1,51 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.provider; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.asitplus.eidas.specific.connector.config.PvpMetadataConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; + +@Service("PVPMetadataConfigurationFactory") +public class PvpMetadataConfigurationFactory implements IPvpMetadataConfigurationFactory { + + @Autowired + private IConfiguration basicConfig; + @Autowired + private IPvp2BasicConfiguration pvpBasicConfig; + + @Override + public IPvpMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authUrl, + AbstractCredentialProvider pvpIdpCredentials) { + return new PvpMetadataConfiguration(basicConfig, authUrl, pvpBasicConfig, pvpIdpCredentials); + + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataProvider.java new file mode 100644 index 00000000..6a223fd0 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/PvpMetadataProvider.java @@ -0,0 +1,155 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.provider; + +import java.io.IOException; +import java.security.cert.CertificateException; +import java.util.List; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.xml.parse.BasicParserPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.asitplus.eidas.specific.connector.verification.MetadataSignatureVerificationFilter; +import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; +import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.MetadataFilterChain; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.PvpEntityCategoryFilter; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter; + +@Service("PVPMetadataProvider") +public class PvpMetadataProvider extends AbstractChainingMetadataProvider { + private static final Logger log = LoggerFactory.getLogger(PvpMetadataProvider.class); + + @Autowired(required = true) + IConfigurationWithSP basicConfig; + + @Override + protected String getMetadataUrl(String entityId) throws EaafConfigurationException { + final ISpConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId); + if (spConfig != null) { + String metadataUrl = entityId; + + final String metadataUrlFromConfig = spConfig.getConfigurationValue( + MsEidasNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL); + if (StringUtils.isNotEmpty(metadataUrlFromConfig)) { + log.debug("Use metdataURL from configuration for EntityId: " + entityId); + metadataUrl = metadataUrlFromConfig; + + } + + return metadataUrl; + + } else { + log.info("No ServiceProvider with entityId: " + entityId + " in configuration."); + } + + return null; + } + + @Override + protected MetadataProvider createNewMetadataProvider(String entityId) + throws EaafConfigurationException, IOException, CertificateException { + final ISpConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId); + if (spConfig != null) { + try { + String metadataUrl = spConfig.getConfigurationValue( + MsEidasNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL); + if (StringUtils.isEmpty(metadataUrl)) { + log.debug("Use EntityId: " + entityId + " instead of explicite metadataURL ... "); + metadataUrl = entityId; + + } + final String trustStoreUrl = FileUtils.makeAbsoluteUrl( + spConfig.getConfigurationValue(MsEidasNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE), + authConfig.getConfigurationRootDirectory()); + final String trustStorePassword = spConfig.getConfigurationValue( + MsEidasNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE_PASSWORD); + + return createNewSimpleMetadataProvider(metadataUrl, + buildMetadataFilterChain(metadataUrl, trustStoreUrl, trustStorePassword), + spConfig.getConfigurationValue(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER), + getTimer(), + new BasicParserPool(), + createHttpClient()); + + } catch (final Pvp2MetadataException e) { + log.info("Can NOT initialize Metadata signature-verification filter. Reason: " + e.getMessage()); + throw new EaafConfigurationException("config.27", + new Object[] { "Can NOT initialize Metadata signature-verification filter. Reason: " + e + .getMessage() }, e); + + } + + } else { + log.info("No ServiceProvider with entityId: " + entityId + " in configuration."); + } + + return null; + } + + @Override + protected List getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException { + // TODO Auto-generated method stub + return null; + } + + private HttpClient createHttpClient() { + final HttpClient httpClient = new HttpClient(); + final HttpClientParams httpClientParams = new HttpClientParams(); + httpClientParams.setSoTimeout(MsEidasNodeConstants.METADATA_SOCKED_TIMEOUT); + httpClient.setParams(httpClientParams); + return httpClient; + + } + + private MetadataFilterChain buildMetadataFilterChain(String metadataUrl, + String trustStoreUrl, String trustStorePassword) throws CertificateException, Pvp2MetadataException { + final MetadataFilterChain filterChain = new MetadataFilterChain(); + filterChain.getFilters().add(new SchemaValidationFilter( + basicConfig.getBasicConfigurationBoolean(MsEidasNodeConstants.PROP_CONFIG_PVP_SCHEME_VALIDATION, + true))); + + filterChain.getFilters().add( + new MetadataSignatureVerificationFilter( + trustStoreUrl, trustStorePassword, metadataUrl)); + + filterChain.getFilters().add(new PvpEntityCategoryFilter( + basicConfig.getBasicConfigurationBoolean(MsEidasNodeConstants.PROP_CONFIG_PVP_ENABLE_ENTITYCATEGORIES, + true))); + + return filterChain; + } +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java index f4dee848..d38da6fe 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,15 +19,13 @@ * 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.asitplus.eidas.specific.connector.provider; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; -import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import org.slf4j.Logger; @@ -39,94 +37,97 @@ import at.gv.egiz.eaaf.core.exceptions.EaafException; @Service("StatusMessageProvider") public class StatusMessageProvider implements IStatusMessenger { - private static final Logger log = LoggerFactory.getLogger(StatusMessageProvider.class); - - private static final String ERROR_MESSAGES_UNAVAILABLE = "Error messages can NOT be load from application. Only errorCode: {0} is availabe" ; - private static final String ERROR_NO_MESSAGE = "No errormesseage for error with number.={0}"; - - private static final String ERROR_EXTERNALERROR_CODES_UNAVAILABLE = "External error-codes can NOT be load from application. Only internal errorCode: {0} is availabe" ; - private static final String ERROR_NO_EXTERNALERROR_CODE = "No external error for internal error with number.={0}"; - - //internal messanges - private static final String DEFAULT_MESSAGE_RESOURCES = "properties/status_messages_en"; - private static final Locale DEFAULT_MESSAGE_LOCALES = new Locale("en", "GB"); - private ResourceBundle messages; - - //external error codes - private static final String DEFAULT_EXTERNALERROR_RESOURCES = "properties/external_statuscodes_map"; - private static final Locale DEFAULT_EXTERNALERROR_LOCALES = new Locale("en", "GB"); - private ResourceBundle externalError = null; - - @Override - public String getMessageWithoutDefault(String messageId, Object[] parameters) { - // initialize messages - if (messages == null) { - this.messages = PropertyResourceBundle.getBundle( - DEFAULT_MESSAGE_RESOURCES, - DEFAULT_MESSAGE_LOCALES); - - } - - // create the message - if (messages == null) { - return MessageFormat.format(ERROR_MESSAGES_UNAVAILABLE, new Object[] { messageId }); - - } else { - String rawMessage = messages.getString(messageId); - return MessageFormat.format(rawMessage, parameters); - - } - } - - @Override - public String getMessage(String messageId, Object[] parameters) { - try { - return getMessageWithoutDefault(messageId, parameters); - - } catch (MissingResourceException e2) { - return MessageFormat.format(ERROR_NO_MESSAGE, new Object[] { messageId }); - - } - } - - @Override - public String getResponseErrorCode(Throwable throwable) { - String errorCode = IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; - if (throwable instanceof EaafException) { - errorCode = ((EaafException) throwable).getErrorId(); - - } - //TODO: maybe more internal switches are required - - return errorCode; - - } - - @Override - public String mapInternalErrorToExternalError(String intErrorCode) { - // initialize messages - if (externalError == null) { - this.externalError = PropertyResourceBundle.getBundle( - DEFAULT_EXTERNALERROR_RESOURCES, - DEFAULT_EXTERNALERROR_LOCALES); - - } - - // create the message - if (externalError == null) { - log.warn(MessageFormat.format(ERROR_EXTERNALERROR_CODES_UNAVAILABLE, new Object[] { intErrorCode })); - return IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; - - } else { - try { - return externalError.getString(intErrorCode); - - } catch (MissingResourceException e2) { - log.info(MessageFormat.format(ERROR_NO_EXTERNALERROR_CODE, new Object[] { intErrorCode })); - return IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; - - } - } - } + private static final Logger log = LoggerFactory.getLogger(StatusMessageProvider.class); + + private static final String ERROR_MESSAGES_UNAVAILABLE = + "Error messages can NOT be load from application. Only errorCode: {0} is availabe"; + private static final String ERROR_NO_MESSAGE = "No errormesseage for error with number.={0}"; + + private static final String ERROR_EXTERNALERROR_CODES_UNAVAILABLE = + "External error-codes can NOT be load from application. Only internal errorCode: {0} is availabe"; + private static final String ERROR_NO_EXTERNALERROR_CODE = + "No external error for internal error with number.={0}"; + + // internal messanges + private static final String DEFAULT_MESSAGE_RESOURCES = "properties/status_messages_en"; + private static final Locale DEFAULT_MESSAGE_LOCALES = new Locale("en", "GB"); + private ResourceBundle messages; + + // external error codes + private static final String DEFAULT_EXTERNALERROR_RESOURCES = "properties/external_statuscodes_map"; + private static final Locale DEFAULT_EXTERNALERROR_LOCALES = new Locale("en", "GB"); + private ResourceBundle externalError = null; + + @Override + public String getMessageWithoutDefault(String messageId, Object[] parameters) { + // initialize messages + if (messages == null) { + this.messages = ResourceBundle.getBundle( + DEFAULT_MESSAGE_RESOURCES, + DEFAULT_MESSAGE_LOCALES); + + } + + // create the message + if (messages == null) { + return MessageFormat.format(ERROR_MESSAGES_UNAVAILABLE, new Object[] { messageId }); + + } else { + final String rawMessage = messages.getString(messageId); + return MessageFormat.format(rawMessage, parameters); + + } + } + + @Override + public String getMessage(String messageId, Object[] parameters) { + try { + return getMessageWithoutDefault(messageId, parameters); + + } catch (final MissingResourceException e2) { + return MessageFormat.format(ERROR_NO_MESSAGE, new Object[] { messageId }); + + } + } + + @Override + public String getResponseErrorCode(Throwable throwable) { + String errorCode = IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; + if (throwable instanceof EaafException) { + errorCode = ((EaafException) throwable).getErrorId(); + + } + // TODO: maybe more internal switches are required + + return errorCode; + + } + + @Override + public String mapInternalErrorToExternalError(String intErrorCode) { + // initialize messages + if (externalError == null) { + this.externalError = ResourceBundle.getBundle( + DEFAULT_EXTERNALERROR_RESOURCES, + DEFAULT_EXTERNALERROR_LOCALES); + + } + + // create the message + if (externalError == null) { + log.warn(MessageFormat.format(ERROR_EXTERNALERROR_CODES_UNAVAILABLE, new Object[] { intErrorCode })); + return IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; + + } else { + try { + return externalError.getString(intErrorCode); + + } catch (final MissingResourceException e2) { + log.info(MessageFormat.format(ERROR_NO_EXTERNALERROR_CODE, new Object[] { intErrorCode })); + return IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC; + + } + } + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWithEidasBackend.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWithEidasBackend.java new file mode 100644 index 00000000..87ebda92 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWithEidasBackend.java @@ -0,0 +1,35 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.storage; + +import eu.eidas.auth.commons.cache.ConcurrentCacheService; +import eu.eidas.auth.commons.tx.AbstractCache; + +public class CacheWithEidasBackend extends AbstractCache { + + protected CacheWithEidasBackend(ConcurrentCacheService concurrentMapService) { + super(concurrentMapService); + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java deleted file mode 100644 index 4bcced82..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.storage; - -import eu.eidas.auth.commons.cache.ConcurrentCacheService; -import eu.eidas.auth.commons.tx.AbstractCache; - -public class CacheWitheIDASBackend extends AbstractCache { - - protected CacheWitheIDASBackend(ConcurrentCacheService concurrentMapService) { - super(concurrentMapService); - } - -// public List clean(Date now, long dataTimeOut) { -// List result = new ArrayList(); -// Iterator iterator = map.keySet().iterator(); -// while (iterator.hasNext()) { -// String key = iterator.next(); -// if (map.containsKey(key)) { -// TransactionStoreElement element = map.get(key); -// if (now.getTime() - element.getCreated().getTime() > dataTimeOut) -// result.add(key); -// } -// } -// -// return result; -// -// } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java new file mode 100644 index 00000000..557e245a --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java @@ -0,0 +1,152 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.connector.storage; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; + +public class EidasCacheTransactionStoreDecorator implements ITransactionStorage { + private static final Logger log = LoggerFactory.getLogger(EidasCacheTransactionStoreDecorator.class); + + @Autowired(required = true) + private CacheWithEidasBackend storage; + + @Override + public void changeKey(String oldKey, String newKey, Object value) throws EaafException { + if (containsKey(oldKey)) { + final TransactionStoreElement el = storage.get(oldKey); + el.setKey(newKey); + el.setData(value); + storage.put(newKey, el); + boolean delResult = storage.remove(oldKey); + log.trace("Object: {} removed from cache: {}", oldKey, delResult); + + } else { + throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); + } + + } + + @Override + public List clean(Date now, long dataTimeOut) { + log.info("Clean is NOT implemented, because its not needed"); + return Arrays.asList(); + + } + + @Override + public boolean containsKey(String key) { + return storage.containsKey(key); + + } + + @Override + public Object get(String key) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement element = storage.get(key); + return element.getData(); + + } else { + return null; + } + } + + @Override + public T get(String key, Class type) throws EaafException { + return get(key, type, -1); + + } + + @Override + public T get(String key, Class type, long dataTimeOut) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement value = storage.get(key); + + if (dataTimeOut > -1) { + final long now = new Date().getTime(); + if (now - value.getCreated().getTime() > dataTimeOut) { + log.info("Transaction-Data with key: " + key + " is out of time."); + throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); + + } + } + + if (type.isAssignableFrom(value.getData().getClass())) { + return (T) value.getData(); + + } else { + log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); + } + + } + + return null; + } + + @Override + public Object getRaw(String key) throws EaafException { + return storage.get(key); + + } + + @Override + public void put(String key, Object value, int dataTimeOut) throws EaafException { + final TransactionStoreElement element = new TransactionStoreElement(); + element.setKey(key); + element.setData(value); + storage.put(key, element); + + } + + @Override + public void putRaw(String key, Object value) throws EaafException { + if (value instanceof TransactionStoreElement) { + storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); + } else { + log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class + .getName()); + } + + } + + @Override + public void remove(String key) { + if (containsKey(key)) { + log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); + boolean delResult = storage.remove(key); + log.trace("Object: {} removed from cache: {}", key, delResult); + + } + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java index 58ab7930..26d442cb 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.storage; import java.util.ArrayList; @@ -29,6 +28,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; @@ -40,124 +40,132 @@ import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; @Service("SimpleInMemoryTransactionStorage") -public class SimpleInMemoryTransactionStorage implements ITransactionStorage{ - private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class); - - private Map storage = new ConcurrentHashMap(); - - @Override - public void changeKey(String oldKey, String newKey, Object value) throws EaafException { - if (containsKey(oldKey)) { - TransactionStoreElement el = storage.get(oldKey); - el.setKey(newKey); - storage.put(newKey, el); - storage.remove(oldKey); - - } else - throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); - - } - - @Override - public List clean(Date now, long dataTimeOut) { - List result = new ArrayList(); - Iterator iterator = storage.keySet().iterator(); - while (iterator.hasNext()) { - String key = iterator.next(); - synchronized (storage) { - if (storage.containsKey(key)) { - TransactionStoreElement element = storage.get(key); - if (now.getTime() - element.getCreated().getTime() > dataTimeOut) - result.add(key); - } - } - } - - return result; - - } - - @Override - public boolean containsKey(String key) { - if (key != null) - return storage.containsKey(key); - else - return false; - - } - - @Override - public Object get(String key) throws EaafException { - if (key != null && containsKey(key)) { - TransactionStoreElement element = storage.get(key); - return element.getData(); - - } else - return null; - } - - @Override - public T get(String key, Class type) throws EaafException { - return get(key, type, -1); - - } - - @Override - public T get(String key, Class type, long dataTimeOut) throws EaafException { - if (key != null && containsKey(key)) { - TransactionStoreElement value = storage.get(key); - - if (dataTimeOut > -1) { - long now = new Date().getTime(); - if (now - value.getCreated().getTime() > dataTimeOut) { - log.info("Transaction-Data with key: " + key + " is out of time."); - throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); - - } - } - - if (type.isAssignableFrom(value.getData().getClass())) { - return (T) value.getData(); - - } else - log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); - - } - - return null; - } - - @Override - public Object getRaw(String key) throws EaafException { - return storage.get(key); - - } - - @Override - public void put(String key, Object value, int dataTimeOut) throws EaafException { - TransactionStoreElement element = new TransactionStoreElement(); - element.setKey(key); - element.setData(value); - storage.put(key, element); - - } - - @Override - public void putRaw(String key, Object value) throws EaafException { - if (value instanceof TransactionStoreElement) - storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); - else - log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class.getName()); - - } - - @Override - public void remove(String key) { - if (containsKey(key)) { - log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); - storage.remove(key); - - } - } +public class SimpleInMemoryTransactionStorage implements ITransactionStorage { + private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class); + + private final Map storage = + new ConcurrentHashMap<>(); + + @Override + public void changeKey(String oldKey, String newKey, Object value) throws EaafException { + if (containsKey(oldKey)) { + final TransactionStoreElement el = storage.get(oldKey); + el.setKey(newKey); + storage.put(newKey, el); + storage.remove(oldKey); + + } else { + throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); + } + + } + + @Override + public List clean(Date now, long dataTimeOut) { + final List result = new ArrayList<>(); + final Iterator> iterator = storage.entrySet().iterator(); + while (iterator.hasNext()) { + final Entry key = iterator.next(); + synchronized (storage) { + if (storage.containsKey(key.getKey())) { + final TransactionStoreElement element = key.getValue(); + if (now.getTime() - element.getCreated().getTime() > dataTimeOut) { + result.add(key.getKey()); + } + } + } + } + + return result; + + } + + @Override + public boolean containsKey(String key) { + if (key != null) { + return storage.containsKey(key); + } else { + return false; + } + + } + + @Override + public Object get(String key) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement element = storage.get(key); + return element.getData(); + + } else { + return null; + } + } + + @Override + public T get(String key, Class type) throws EaafException { + return get(key, type, -1); + + } + + @Override + public T get(String key, Class type, long dataTimeOut) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement value = storage.get(key); + + if (dataTimeOut > -1) { + final long now = new Date().getTime(); + if (now - value.getCreated().getTime() > dataTimeOut) { + log.info("Transaction-Data with key: " + key + " is out of time."); + throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); + + } + } + + if (type.isAssignableFrom(value.getData().getClass())) { + return (T) value.getData(); + + } else { + log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); + } + + } + + return null; + } + + @Override + public Object getRaw(String key) throws EaafException { + return storage.get(key); + + } + + @Override + public void put(String key, Object value, int dataTimeOut) throws EaafException { + final TransactionStoreElement element = new TransactionStoreElement(); + element.setKey(key); + element.setData(value); + storage.put(key, element); + + } + + @Override + public void putRaw(String key, Object value) throws EaafException { + if (value instanceof TransactionStoreElement) { + storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); + } else { + log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class + .getName()); + } + + } + + @Override + public void remove(String key) { + if (containsKey(key)) { + log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); + storage.remove(key); + + } + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/TransactionStoreElement.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/TransactionStoreElement.java index d0907f20..4e9e737f 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/TransactionStoreElement.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/TransactionStoreElement.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,40 +19,52 @@ * 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.asitplus.eidas.specific.connector.storage; import java.io.Serializable; import java.util.Date; -public class TransactionStoreElement implements Serializable{ - - private static final long serialVersionUID = 1L; - private String key = null; - private Object data = null; - private Date created; - - public String getKey() { - return key; - } - public void setKey(String key) { - this.key = key; - } - public Object getData() { - return data; - } - public void setData(Object data) { - this.data = data; - } - public Date getCreated() { - return created; - } - public void setCreated(Date created) { - this.created = created; - } - - - +public class TransactionStoreElement implements Serializable { + + private static final long serialVersionUID = 1L; + private String key = null; + private Object data = null; + private Date created; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public Date getCreated() { + return copyOrNull(created); + } + + public void setCreated(Date created) { + this.created = copyOrNull(created); + } + + private Date copyOrNull(Date in) { + if (in != null) { + return new Date(in.getTime()); + + } + + return null; + + } + } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java deleted file mode 100644 index be7812f4..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.connector.storage; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; - -public class eIDASCacheTransactionStoreDecorator implements ITransactionStorage{ - private static final Logger log = LoggerFactory.getLogger(eIDASCacheTransactionStoreDecorator.class); - - @Autowired(required=true) private CacheWitheIDASBackend storage; - - @Override - public void changeKey(String oldKey, String newKey, Object value) throws EaafException { - if (containsKey(oldKey)) { - TransactionStoreElement el = storage.get(oldKey); - el.setKey(newKey); - el.setData(value); - storage.put(newKey, el); - storage.remove(oldKey); - - } else - throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); - - } - - @Override - public List clean(Date now, long dataTimeOut) { - log.info("Clean is NOT implemented, because its not needed"); - return Arrays.asList(); - - } - - @Override - public boolean containsKey(String key) { - return storage.containsKey(key); - - } - - @Override - public Object get(String key) throws EaafException { - if (key != null && containsKey(key)) { - TransactionStoreElement element = storage.get(key); - return element.getData(); - - } else - return null; - } - - @Override - public T get(String key, Class type) throws EaafException { - return get(key, type, -1); - - } - - @Override - public T get(String key, Class type, long dataTimeOut) throws EaafException { - if (key != null && containsKey(key)) { - TransactionStoreElement value = storage.get(key); - - if (dataTimeOut > -1) { - long now = new Date().getTime(); - if (now - value.getCreated().getTime() > dataTimeOut) { - log.info("Transaction-Data with key: " + key + " is out of time."); - throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); - - } - } - - if (type.isAssignableFrom(value.getData().getClass())) { - return (T) value.getData(); - - } else - log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); - - } - - return null; - } - - @Override - public Object getRaw(String key) throws EaafException { - return storage.get(key); - - } - - @Override - public void put(String key, Object value, int dataTimeOut) throws EaafException { - TransactionStoreElement element = new TransactionStoreElement(); - element.setKey(key); - element.setData(value); - storage.put(key, element); - - } - - @Override - public void putRaw(String key, Object value) throws EaafException { - if (value instanceof TransactionStoreElement) - storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); - else - log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class.getName()); - - } - - @Override - public void remove(String key) { - if (containsKey(key)) { - log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); - storage.remove(key); - - } - } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java index c49c0b28..0230521c 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,7 +19,8 @@ * 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.asitplus.eidas.specific.connector.verification; import java.util.ArrayList; @@ -31,8 +32,8 @@ import org.apache.commons.lang3.StringUtils; import org.opensaml.saml2.core.AuthnContextClassRef; import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.NameIDPolicy; +import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.core.RequestedAuthnContext; import org.opensaml.saml2.core.Scoping; import org.opensaml.saml2.metadata.SPSSODescriptor; @@ -41,7 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.asitplus.eidas.specific.connector.config.ServiceProviderConfiguration; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.EaafConstants; @@ -58,215 +59,230 @@ import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; public class AuthnRequestValidator implements IAuthnRequestValidator { - private static final Logger log = LoggerFactory.getLogger(AuthnRequestValidator.class); - - @Autowired(required=true) private IConfiguration basicConfig; - - @Override - public void validate(HttpServletRequest httpReq, IRequest pendingReq, AuthnRequest authnReq, - SPSSODescriptor spSSODescriptor) throws AuthnRequestValidatorException { - try { - //validate NameIDPolicy - NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy(); - if (nameIDPolicy != null) { - String nameIDFormat = nameIDPolicy.getFormat(); - if (nameIDFormat != null) { - if ( !(NameID.TRANSIENT.equals(nameIDFormat) || - NameID.PERSISTENT.equals(nameIDFormat)) ) { - - throw new NameIdFormatNotSupportedException(nameIDFormat); - - } - - } else - log.trace("Find NameIDPolicy, but NameIDFormat is 'null'"); - } else - log.trace("AuthnRequest includes no 'NameIDPolicy'"); - - - //post-process RequesterId - String spEntityId = extractScopeRequsterId(authnReq); - if (StringUtils.isEmpty(spEntityId)) { - log.info("NO service-provider entityID in Authn. request. Stop authn. process ... "); - throw new AuthnRequestValidatorException("pvp2.22", - new Object[] {"NO relaying-party entityID in Authn. request"}, pendingReq); - - } else - pendingReq.setRawDataToTransaction(MSeIDASNodeConstants.DATA_REQUESTERID, spEntityId); - - - //post-process ProviderName - String providerName = authnReq.getProviderName(); - if (StringUtils.isEmpty(providerName)) - log.info("Authn. request contains NO SP friendlyName"); - else - pendingReq.setRawDataToTransaction(MSeIDASNodeConstants.DATA_PROVIDERNAME, spEntityId); - - //post-process requested LoA - List reqLoA = extractLoA(authnReq); - - LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration( - MSeIDASNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL, - EaafConstants.EIDAS_LOA_HIGH)); - if (minimumLoAFromConfig == null) { - log.warn("Can not load minimum LoA from configuration. Use LoA: {} as default", EaafConstants.EIDAS_LOA_HIGH); - minimumLoAFromConfig = LevelOfAssurance.HIGH; - - } - - log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...", minimumLoAFromConfig); - List allowedLoA = new ArrayList<>(); - for (String loa : reqLoA) { - try { - LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa); - String selectedLoA = EaafConstants.EIDAS_LOA_HIGH; - if (intLoa != null && - intLoa.numericValue() >= minimumLoAFromConfig.numericValue()) { - log.info("Client: {} requested LoA: {} will be upgraded to: {}", - pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(), - loa, - minimumLoAFromConfig); - selectedLoA = intLoa.getValue(); - - } - - if (!allowedLoA.contains(selectedLoA)) { - log.debug("Allow LoA: {} for Client: {}", - selectedLoA, - pendingReq.getServiceProviderConfiguration().getUniqueIdentifier()); - allowedLoA.add(selectedLoA); - - } - - } catch (IllegalArgumentException e) { - log.warn("LoA: {} is currently NOT supported and it will be ignored.", loa); - - } - - } - - pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA(allowedLoA); - - //post-process requested LoA comparison-level - String reqLoAComperison = extractComparisonLevel(authnReq); - pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode(reqLoAComperison); - - //validate and process requested attributes - boolean sectorDetected = false; - List requestedAttributes = authnReq.getExtensions().getUnknownXMLObjects(); - for (XMLObject reqAttrObj : requestedAttributes) { - if (reqAttrObj instanceof EaafRequestedAttributes) { - EaafRequestedAttributes reqAttr = (EaafRequestedAttributes)reqAttrObj; - if (reqAttr.getAttributes() != null && reqAttr.getAttributes().size() != 0 ) { - for (EaafRequestedAttribute el : reqAttr.getAttributes()) { - log.trace("Processing req. attribute '" + el.getName() + "' ... "); - if (el.getName().equals(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) { - if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { - String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent(); - ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class); - - try { - spConfig.setbPKTargetIdentifier(sectorId); - sectorDetected = true; - - } catch (EaafException e) { - log.info("Requested sector: " + sectorId + " DOES NOT match to allowed sectors for SP: " + spConfig.getUniqueIdentifier()); - } - - } else - log.info("Req. attribute '" + el.getName() + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute"); - - } else - log.debug("Ignore req. attribute: " + el.getName()); - - } - - } else - log.debug("No requested Attributes in Authn. Request"); - - } else - log.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString()); - - } - - if (!sectorDetected) { - log.info("Authn.Req validation FAILED. Reason: Contains NO or NO VALID target-sector information."); - throw new AuthnRequestValidatorException("pvp2.22", new Object[] {"NO or NO VALID target-sector information"}); - - } - - } catch (EaafStorageException e) { - log.info("Can NOT store Authn. Req. data into pendingRequest." , e); - throw new AuthnRequestValidatorException("internal.02", null, e); - - } - - } - - private String extractComparisonLevel(AuthnRequest authnReq) { - if (authnReq.getRequestedAuthnContext() != null) { - RequestedAuthnContext authContext = authnReq.getRequestedAuthnContext(); - return authContext.getComparison().toString(); - - } - - return null; - } - - private List extractLoA(AuthnRequest authnReq) throws AuthnRequestValidatorException { - List result = new ArrayList(); - if (authnReq.getRequestedAuthnContext() != null) { - RequestedAuthnContext authContext = authnReq.getRequestedAuthnContext(); - if (authContext.getComparison().equals(AuthnContextComparisonTypeEnumeration.MINIMUM)) { - if (authContext.getAuthnContextClassRefs().isEmpty()) { - log.debug("Authn. Req. contains no requested LoA"); - - } else if (authContext.getAuthnContextClassRefs().size() > 1) { - log.info("Authn. Req. contains MORE THAN ONE requested LoA, but " - + AuthnContextComparisonTypeEnumeration.MINIMUM + " allows only one" ); - throw new AuthnRequestValidatorException("pvp2.22", - new Object[] {"Authn. Req. contains MORE THAN ONE requested LoA, but " - + AuthnContextComparisonTypeEnumeration.MINIMUM + " allows only one"}); - - } else - result.add(authContext.getAuthnContextClassRefs().get(0).getAuthnContextClassRef()); - - } else if (authContext.getComparison().equals(AuthnContextComparisonTypeEnumeration.EXACT)) { - for (AuthnContextClassRef el : authContext.getAuthnContextClassRefs()) - result.add(el.getAuthnContextClassRef()); - - } else { - log.info("Currently only '" + AuthnContextComparisonTypeEnumeration.MINIMUM + "' and '" - + AuthnContextComparisonTypeEnumeration.EXACT + "' are supported"); - throw new AuthnRequestValidatorException("pvp2.22", - new Object[] {"Currently only '" + AuthnContextComparisonTypeEnumeration.MINIMUM + "' and '" - + AuthnContextComparisonTypeEnumeration.EXACT + "' are supported"}); - - } - - } - - return result; - } - - private String extractScopeRequsterId(AuthnRequest authnReq) { - if (authnReq.getScoping() != null) { - Scoping scoping = authnReq.getScoping(); - if (scoping.getRequesterIDs() != null && - scoping.getRequesterIDs().size() > 0) { - if (scoping.getRequesterIDs().size() == 1) - return scoping.getRequesterIDs().get(0).getRequesterID(); - - else { - log.info("Authn. request contains more than on RequesterIDs! Only use first one"); - return scoping.getRequesterIDs().get(0).getRequesterID(); - - } - } - } - - return null; - } - + private static final Logger log = LoggerFactory.getLogger(AuthnRequestValidator.class); + + @Autowired(required = true) + private IConfiguration basicConfig; + + @Override + public void validate(HttpServletRequest httpReq, IRequest pendingReq, AuthnRequest authnReq, + SPSSODescriptor spSsoDescriptor) throws AuthnRequestValidatorException { + try { + // validate NameIDPolicy + final NameIDPolicy nameIdPolicy = authnReq.getNameIDPolicy(); + if (nameIdPolicy != null) { + final String nameIdFormat = nameIdPolicy.getFormat(); + if (nameIdFormat != null) { + if (!(NameIDType.TRANSIENT.equals(nameIdFormat) + || NameIDType.PERSISTENT.equals(nameIdFormat))) { + + throw new NameIdFormatNotSupportedException(nameIdFormat); + + } + + } else { + log.trace("Find NameIDPolicy, but NameIDFormat is 'null'"); + } + } else { + log.trace("AuthnRequest includes no 'NameIDPolicy'"); + } + + // post-process RequesterId + final String spEntityId = extractScopeRequsterId(authnReq); + if (StringUtils.isEmpty(spEntityId)) { + log.info("NO service-provider entityID in Authn. request. Stop authn. process ... "); + throw new AuthnRequestValidatorException("pvp2.22", + new Object[] { "NO relaying-party entityID in Authn. request" }, pendingReq); + + } else { + pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_REQUESTERID, spEntityId); + } + + // post-process ProviderName + final String providerName = authnReq.getProviderName(); + if (StringUtils.isEmpty(providerName)) { + log.info("Authn. request contains NO SP friendlyName"); + } else { + pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_PROVIDERNAME, spEntityId); + } + + // post-process requested LoA + final List reqLoA = extractLoA(authnReq); + + LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration( + MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL, + EaafConstants.EIDAS_LOA_HIGH)); + if (minimumLoAFromConfig == null) { + log.warn("Can not load minimum LoA from configuration. Use LoA: {} as default", + EaafConstants.EIDAS_LOA_HIGH); + minimumLoAFromConfig = LevelOfAssurance.HIGH; + + } + + log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...", + minimumLoAFromConfig); + final List allowedLoA = new ArrayList<>(); + for (final String loa : reqLoA) { + try { + final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa); + String selectedLoA = EaafConstants.EIDAS_LOA_HIGH; + if (intLoa != null + && intLoa.numericValue() >= minimumLoAFromConfig.numericValue()) { + log.info("Client: {} requested LoA: {} will be upgraded to: {}", + pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(), + loa, + minimumLoAFromConfig); + selectedLoA = intLoa.getValue(); + + } + + if (!allowedLoA.contains(selectedLoA)) { + log.debug("Allow LoA: {} for Client: {}", + selectedLoA, + pendingReq.getServiceProviderConfiguration().getUniqueIdentifier()); + allowedLoA.add(selectedLoA); + + } + + } catch (final IllegalArgumentException e) { + log.warn("LoA: {} is currently NOT supported and it will be ignored.", loa); + + } + + } + + pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA( + allowedLoA); + + // post-process requested LoA comparison-level + final String reqLoAComperison = extractComparisonLevel(authnReq); + pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode( + reqLoAComperison); + + // validate and process requested attributes + boolean sectorDetected = false; + final List requestedAttributes = authnReq.getExtensions().getUnknownXMLObjects(); + for (final XMLObject reqAttrObj : requestedAttributes) { + if (reqAttrObj instanceof EaafRequestedAttributes) { + final EaafRequestedAttributes reqAttr = (EaafRequestedAttributes) reqAttrObj; + if (reqAttr.getAttributes() != null && reqAttr.getAttributes().size() != 0) { + for (final EaafRequestedAttribute el : reqAttr.getAttributes()) { + log.trace("Processing req. attribute '" + el.getName() + "' ... "); + if (el.getName().equals(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) { + if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { + final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent(); + final ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration( + ServiceProviderConfiguration.class); + + try { + spConfig.setBpkTargetIdentifier(sectorId); + sectorDetected = true; + + } catch (final EaafException e) { + log.info("Requested sector: " + sectorId + " DOES NOT match to allowed sectors for SP: " + + spConfig.getUniqueIdentifier()); + } + + } else { + log.info("Req. attribute '" + el.getName() + + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute"); + } + + } else { + log.debug("Ignore req. attribute: " + el.getName()); + } + + } + + } else { + log.debug("No requested Attributes in Authn. Request"); + } + + } else { + log.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString()); + } + + } + + if (!sectorDetected) { + log.info("Authn.Req validation FAILED. Reason: Contains NO or NO VALID target-sector information."); + throw new AuthnRequestValidatorException("pvp2.22", new Object[] { + "NO or NO VALID target-sector information" }); + + } + + } catch (final EaafStorageException e) { + log.info("Can NOT store Authn. Req. data into pendingRequest.", e); + throw new AuthnRequestValidatorException("internal.02", null, e); + + } + + } + + private String extractComparisonLevel(AuthnRequest authnReq) { + if (authnReq.getRequestedAuthnContext() != null) { + final RequestedAuthnContext authContext = authnReq.getRequestedAuthnContext(); + return authContext.getComparison().toString(); + + } + + return null; + } + + private List extractLoA(AuthnRequest authnReq) throws AuthnRequestValidatorException { + final List result = new ArrayList<>(); + if (authnReq.getRequestedAuthnContext() != null) { + final RequestedAuthnContext authContext = authnReq.getRequestedAuthnContext(); + if (authContext.getComparison().equals(AuthnContextComparisonTypeEnumeration.MINIMUM)) { + if (authContext.getAuthnContextClassRefs().isEmpty()) { + log.debug("Authn. Req. contains no requested LoA"); + + } else if (authContext.getAuthnContextClassRefs().size() > 1) { + log.info("Authn. Req. contains MORE THAN ONE requested LoA, but " + + AuthnContextComparisonTypeEnumeration.MINIMUM + " allows only one"); + throw new AuthnRequestValidatorException("pvp2.22", + new Object[] { "Authn. Req. contains MORE THAN ONE requested LoA, but " + + AuthnContextComparisonTypeEnumeration.MINIMUM + " allows only one" }); + + } else { + result.add(authContext.getAuthnContextClassRefs().get(0).getAuthnContextClassRef()); + } + + } else if (authContext.getComparison().equals(AuthnContextComparisonTypeEnumeration.EXACT)) { + for (final AuthnContextClassRef el : authContext.getAuthnContextClassRefs()) { + result.add(el.getAuthnContextClassRef()); + } + + } else { + log.info("Currently only '" + AuthnContextComparisonTypeEnumeration.MINIMUM + "' and '" + + AuthnContextComparisonTypeEnumeration.EXACT + "' are supported"); + throw new AuthnRequestValidatorException("pvp2.22", + new Object[] { "Currently only '" + AuthnContextComparisonTypeEnumeration.MINIMUM + "' and '" + + AuthnContextComparisonTypeEnumeration.EXACT + "' are supported" }); + + } + + } + + return result; + } + + private String extractScopeRequsterId(AuthnRequest authnReq) { + if (authnReq.getScoping() != null) { + final Scoping scoping = authnReq.getScoping(); + if (scoping.getRequesterIDs() != null + && scoping.getRequesterIDs().size() > 0) { + if (scoping.getRequesterIDs().size() == 1) { + return scoping.getRequesterIDs().get(0).getRequesterID(); + } else { + log.info("Authn. request contains more than on RequesterIDs! Only use first one"); + return scoping.getRequesterIDs().get(0).getRequesterID(); + + } + } + } + + return null; + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java index eeaea135..b6dd249a 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java @@ -1,6 +1,6 @@ -/******************************************************************************* +/* * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by @@ -19,9 +19,8 @@ * 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.asitplus.eidas.specific.connector.verification; import java.io.IOException; @@ -49,116 +48,128 @@ import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; import at.gv.egiz.eaaf.modules.pvp2.idp.exception.SamlRequestNotSignedException; import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.AbstractMetadataSignatureFilter; -public class MetadataSignatureVerificationFilter extends AbstractMetadataSignatureFilter{ - private static final Logger log = LoggerFactory.getLogger(MetadataSignatureVerificationFilter.class); - - private String metadataURL; - private List trustedCredential = new ArrayList(); - - public MetadataSignatureVerificationFilter(String trustStorePath, String trustStorePassword, String metadataURL) - throws Pvp2MetadataException { - this.metadataURL = metadataURL; - - log.trace("Initialize metadata signature-verification filter with truststore: " + trustStorePath + " ... "); - try { - KeyStore keyStore = KeyStoreUtils.loadKeyStore(trustStorePath, trustStorePassword); - if (keyStore != null) { - //load trusted certificates - Enumeration aliases = keyStore.aliases(); - while(aliases.hasMoreElements()) { - String el = aliases.nextElement(); - log.trace("Process TrustStoreEntry: " + el); - if (keyStore.isCertificateEntry(el)) { - Certificate cert = keyStore.getCertificate(el); - if (cert != null && cert instanceof X509Certificate) { - BasicX509Credential trustedCert = new BasicX509Credential(); - trustedCert.setEntityCertificate((X509Certificate) cert); - this.trustedCredential.add(trustedCert); - log.debug("Add cert: " + ((X509Certificate) cert).getSubjectDN() + " as trusted for metadata: " + metadataURL); - - } else - log.info("Can not process entry: " + el + ". Reason: " + cert.toString()); - - } - } - - - } else - throw new Pvp2MetadataException("pvp2.26", - new Object[] {"Can not open trustStore: " + trustStorePath + " for metadata: " + metadataURL}); - - } catch (KeyStoreException | IOException e) { - log.warn("Can not open trustStore: " + trustStorePath + " for metadata: " + metadataURL + " Reason: " + e.getMessage(), e); - throw new Pvp2MetadataException("pvp2.26", - new Object[] {"Can not open trustStore: " + trustStorePath + " for metadata"}, e); - - } - - - } - - - @Override - protected void verify(EntityDescriptor desc) throws Pvp2MetadataException { - try { - internalVerify(desc); - - } catch (EaafException e) { - log.info("Metadata verification FAILED for: " + metadataURL + " Reason: " +e.getMessage()); - throw new Pvp2MetadataException("pvp2.26", - new Object[] {"Metadata verification FAILED for: " + metadataURL + " Reason: " +e.getMessage()}, e); - - } - } - - @Override - protected void verify(EntitiesDescriptor desc) throws Pvp2MetadataException { - throw new Pvp2MetadataException("pvp2.26", - new Object[] {"EntitiesDescritors are NOT supported"}); - - } - - @Override - protected void verify(EntityDescriptor entity, EntitiesDescriptor desc) throws Pvp2MetadataException { - throw new Pvp2MetadataException("pvp2.26", - new Object[] {"EntitiesDescritors are NOT supported"}); - - } - - private void internalVerify(SignableSAMLObject signedElement) - throws EaafException { - if (signedElement.getSignature() == null) { - throw new SamlRequestNotSignedException(); - } - - try { - SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator(); - sigValidator.validate(signedElement.getSignature()); - } catch (ValidationException e) { - log.error("Failed to validate Signature", e); - throw new SamlRequestNotSignedException(e); - } - - boolean isTrusted = false; - for (BasicX509Credential cred : trustedCredential) { - SignatureValidator sigValidator = new SignatureValidator(cred); - try { - sigValidator.validate(signedElement.getSignature()); - isTrusted = true; - - } catch (ValidationException e) { - log.info("Failed to verfiy Signature with cert: " + cred.getEntityCertificate().getSubjectDN() - + " Reason: " + e.getMessage()); - - } - } - - if (!isTrusted) { - log.warn("PVP2 metadata: " + metadataURL + " are NOT trusted!"); - throw new SamlRequestNotSignedException(); - - } - - } +public class MetadataSignatureVerificationFilter extends AbstractMetadataSignatureFilter { + private static final Logger log = LoggerFactory.getLogger(MetadataSignatureVerificationFilter.class); + + private final String metadataUrl; + private final List trustedCredential = new ArrayList<>(); + + /** + * SAML2 Metadata signature verifier that checks signer certificates based on local TrustStores. + * + * @param trustStorePath Path to truststore + * @param trustStorePassword TrustStore password + * @param metadataUrl URL to PVP2 metadata + * @throws Pvp2MetadataException In case of a verification error + */ + public MetadataSignatureVerificationFilter(String trustStorePath, String trustStorePassword, + String metadataUrl) + throws Pvp2MetadataException { + this.metadataUrl = metadataUrl; + + log.trace("Initialize metadata signature-verification filter with truststore: " + trustStorePath + + " ... "); + try { + final KeyStore keyStore = KeyStoreUtils.loadKeyStore(trustStorePath, trustStorePassword); + if (keyStore != null) { + // load trusted certificates + final Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + final String el = aliases.nextElement(); + log.trace("Process TrustStoreEntry: " + el); + if (keyStore.isCertificateEntry(el)) { + final Certificate cert = keyStore.getCertificate(el); + if (cert != null && cert instanceof X509Certificate) { + final BasicX509Credential trustedCert = new BasicX509Credential(); + trustedCert.setEntityCertificate((X509Certificate) cert); + this.trustedCredential.add(trustedCert); + log.debug("Add cert: " + ((X509Certificate) cert).getSubjectDN() + " as trusted for metadata: " + + metadataUrl); + + } else { + log.info("Can not process entry: " + el + ". Reason: is null"); + } + + } + } + + } else { + throw new Pvp2MetadataException("pvp2.26", + new Object[] { "Can not open trustStore: " + trustStorePath + " for metadata: " + metadataUrl }); + } + + } catch (KeyStoreException | IOException e) { + log.warn("Can not open trustStore: " + trustStorePath + " for metadata: " + metadataUrl + " Reason: " + + e.getMessage(), e); + throw new Pvp2MetadataException("pvp2.26", + new Object[] { "Can not open trustStore: " + trustStorePath + " for metadata" }, e); + + } + + } + + @Override + protected void verify(EntityDescriptor desc) throws Pvp2MetadataException { + try { + internalVerify(desc); + + } catch (final EaafException e) { + log.info("Metadata verification FAILED for: " + metadataUrl + " Reason: " + e.getMessage()); + throw new Pvp2MetadataException("pvp2.26", + new Object[] { "Metadata verification FAILED for: " + metadataUrl + " Reason: " + e.getMessage() }, + e); + + } + } + + @Override + protected void verify(EntitiesDescriptor desc) throws Pvp2MetadataException { + throw new Pvp2MetadataException("pvp2.26", + new Object[] { "EntitiesDescritors are NOT supported" }); + + } + + @Override + protected void verify(EntityDescriptor entity, EntitiesDescriptor desc) throws Pvp2MetadataException { + throw new Pvp2MetadataException("pvp2.26", + new Object[] { "EntitiesDescritors are NOT supported" }); + + } + + private void internalVerify(SignableSAMLObject signedElement) + throws EaafException { + if (signedElement.getSignature() == null) { + throw new SamlRequestNotSignedException(); + } + + try { + final SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator(); + sigValidator.validate(signedElement.getSignature()); + } catch (final ValidationException e) { + log.error("Failed to validate Signature", e); + throw new SamlRequestNotSignedException(e); + } + + boolean isTrusted = false; + for (final BasicX509Credential cred : trustedCredential) { + final SignatureValidator sigValidator = new SignatureValidator(cred); + try { + sigValidator.validate(signedElement.getSignature()); + isTrusted = true; + + } catch (final ValidationException e) { + log.info("Failed to verfiy Signature with cert: " + cred.getEntityCertificate().getSubjectDN() + + " Reason: " + e.getMessage()); + + } + } + + if (!isTrusted) { + log.warn("PVP2 metadata: " + metadataUrl + " are NOT trusted!"); + throw new SamlRequestNotSignedException(); + + } + + } } -- cgit v1.2.3