diff options
| author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-12-10 07:39:27 +0100 | 
|---|---|---|
| committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-12-10 07:39:27 +0100 | 
| commit | e443168b481bb88fecbad73084147e7e8c882908 (patch) | |
| tree | 52812f6555c4efaaf84253a3fb068cd73ff08a30 /connector/src/main/java | |
| parent | 0224cdf7be78cf0778f0b832a42c18c480c4b784 (diff) | |
| download | National_eIDAS_Gateway-e443168b481bb88fecbad73084147e7e8c882908.tar.gz National_eIDAS_Gateway-e443168b481bb88fecbad73084147e7e8c882908.tar.bz2 National_eIDAS_Gateway-e443168b481bb88fecbad73084147e7e8c882908.zip | |
refactoring to new EGIZ code requirements
Diffstat (limited to 'connector/src/main/java')
34 files changed, 2544 insertions, 2386 deletions
| 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 index 346c4fd7..6e8e06ef 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.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 org.springframework.core.io.ClassPathResource; @@ -29,23 +28,25 @@ import org.springframework.core.io.Resource;  import at.gv.egiz.components.spring.api.SpringResourceProvider; -public class MSSpecificeIDASNodeSpringResourceProvider implements 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 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[] getPackagesToScan() { +    return null; +  } -	@Override -	public String getName() { -		return "MS-specific eIDAS Node SpringResourceProvider"; -	} +  @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<String, String> buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) throws EaafBuilderException { -		//TODO: check if bPK already exists -		 -		 -		return super.buildOAspecificbPK(pendingReq, authData); -				 -	} -	 -	@Override -	protected Pair<String, String> getEncryptedBpkFromPvpAttribute(IAuthProcessDataContainer arg0, -			AuthenticationData arg1, ISpConfiguration arg2) throws EaafBuilderException { -		return null; -		 -	} - -	@Override -	protected Pair<String, String> 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<String, String> buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) +      throws EaafBuilderException { +    // TODO: check if bPK already exists + +    return super.buildOAspecificbPK(pendingReq, authData); + +  } + +  @Override +  protected Pair<String, String> getEncryptedBpkFromPvpAttribute(IAuthProcessDataContainer arg0, +      AuthenticationData arg1, ISpConfiguration arg2) throws EaafBuilderException { +    return null; + +  } + +  @Override +  protected Pair<String, String> 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<String, String> generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig) throws Pvp2Exception { -		return Pair.newInstance(authData.getBpk(), authData.getBpkType()); -	} +  @Override +  public Pair<String, String> 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<ContactPerson> 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<ContactPerson> 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<Attribute> getIdpPossibleAttributes() { -		return PvpAttributeBuilder.buildSupportedEmptyAttributes(); -		 -	} - -	@Override -	public List<String> getIdpPossibleNameIdTypes() { -		return Arrays.asList(NameIDType.PERSISTENT,  -				 NameIDType.TRANSIENT, -				 NameIDType.UNSPECIFIED); -	} - -	@Override -	public List<RequestedAttribute> getSpRequiredAttributes() { -		return null; -		 -	} - -	@Override -	public List<String> 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<ContactPerson> 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<ContactPerson> 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<Attribute> getIdpPossibleAttributes() { +    return PvpAttributeBuilder.buildSupportedEmptyAttributes(); + +  } + +  @Override +  public List<String> getIdpPossibleNameIdTypes() { +    return Arrays.asList(NameIDType.PERSISTENT, +        NameIDType.TRANSIENT, +        NameIDType.UNSPECIFIED); +  } + +  @Override +  public List<RequestedAttribute> getSpRequiredAttributes() { +    return null; + +  } + +  @Override +  public List<String> 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() + "<br>"; -		} catch (Exception e) { -			result += e.getMessage() + "<br>"; -		} -		 -		try { -			result += testStorage() + "<br>"; -		} catch (Exception e) { -			result += e.getMessage() + "<br>"; -		} -		 -		try { -			result += testPVPMetadata() + "<br>"; -		} catch (Exception e) { -			result += e.getMessage() + "<br>"; -		} -		 -		try { -			result += testEidasNodeMetadata() + "<br>"; -		} catch (Exception e) { -			result += e.getMessage() + "<br>"; -		} -		 -		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() + "<br>"; +    } catch (final Exception e) { +      result += e.getMessage() + "<br>"; +    } + +    try { +      result += testStorage() + "<br>"; +    } catch (final Exception e) { +      result += e.getMessage() + "<br>"; +    } + +    try { +      result += testPvpMetadata() + "<br>"; +    } catch (final Exception e) { +      result += e.getMessage() + "<br>"; +    } + +    try { +      result += testEidasNodeMetadata() + "<br>"; +    } catch (final Exception e) { +      result += e.getMessage() + "<br>"; +    } + +    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<String> 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<String> 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/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<String> 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 index 6965a407..8b0419d0 100644 --- 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 @@ -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,14 @@   * 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.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; @@ -35,16 +34,18 @@ import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactor  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); -		 -	} +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<String> 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 index 4bcced82..87ebda92 100644 --- 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 @@ -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,32 +19,17 @@   * 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<String, TransactionStoreElement> { - -	protected CacheWitheIDASBackend(ConcurrentCacheService concurrentMapService) { -		super(concurrentMapService); -	} -	 -//	public List<String> clean(Date now, long dataTimeOut) { -//		List<String> result = new ArrayList<String>(); -//		Iterator<String> 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; -//		 -//	} +public class CacheWithEidasBackend extends AbstractCache<String, TransactionStoreElement> { +  protected CacheWithEidasBackend(ConcurrentCacheService concurrentMapService) { +    super(concurrentMapService); +  } +    } 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<String> 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> T get(String key, Class<T> type) throws EaafException { +    return get(key, type, -1); + +  } + +  @Override +  public <T> T get(String key, Class<T> 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<String, TransactionStoreElement> storage = new ConcurrentHashMap<String, TransactionStoreElement>(); -	 -	@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<String> clean(Date now, long dataTimeOut) { -		List<String> result = new ArrayList<String>(); -		Iterator<String> 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> T get(String key, Class<T> type) throws EaafException { -		return get(key, type, -1); -		 -	} - -	@Override -	public <T> T get(String key, Class<T> 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<String, TransactionStoreElement> 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<String> clean(Date now, long dataTimeOut) { +    final List<String> result = new ArrayList<>(); +    final Iterator<Entry<String, TransactionStoreElement>> iterator = storage.entrySet().iterator(); +    while (iterator.hasNext()) { +      final Entry<String, TransactionStoreElement> 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> T get(String key, Class<T> type) throws EaafException { +    return get(key, type, -1); + +  } + +  @Override +  public <T> T get(String key, Class<T> 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<String> 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> T get(String key, Class<T> type) throws EaafException { -		return get(key, type, -1); -		 -	} - -	@Override -	public <T> T get(String key, Class<T> 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<String> 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<String> 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<XMLObject> 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<String> extractLoA(AuthnRequest authnReq) throws AuthnRequestValidatorException { -		List<String> result = new ArrayList<String>(); -		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<String> 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<String> 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<XMLObject> 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<String> extractLoA(AuthnRequest authnReq) throws AuthnRequestValidatorException { +    final List<String> 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<BasicX509Credential> trustedCredential = new ArrayList<BasicX509Credential>(); -	 -	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<String> 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<BasicX509Credential> 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<String> 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(); + +    } + +  }  } | 
