diff options
Diffstat (limited to 'id/server/idserverlib/src')
75 files changed, 2877 insertions, 1965 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/MOAIDEventConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/MOAIDEventConstants.java index d5d0a3ab1..eccd63e3d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/MOAIDEventConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/MOAIDEventConstants.java @@ -81,7 +81,7 @@ public interface MOAIDEventConstants extends EventConstants { public static final int AUTHPROCESS_PEPS_REQUESTED = 4400; public static final int AUTHPROCESS_PEPS_RECEIVED = 4401; public static final int AUTHPROCESS_PEPS_IDL_RECEIVED = 4402; - + //person information public static final int PERSONAL_INFORMATION_PROF_REPRESENTATIVE_BPK = 5000; public static final int PERSONAL_INFORMATION_PROF_REPRESENTATIVE = 5001; @@ -92,6 +92,10 @@ public interface MOAIDEventConstants extends EventConstants { public static final int PERSONAL_INFORMATION_MANDATE_MANDATOR_HASH = 5102; public static final int PERSONAL_INFORMATION_MANDATE_MANDATOR_BASEID = 5103; + //Attribute Provider [6000 --> 7900] + public static final int AUTHPROCESS_ELGA_MANDATE_SERVICE_REQUESTED = 6000; + public static final int AUTHPROCESS_ELGA_MANDATE_RECEIVED = 6001; + public static final int AUTHPROCESS_ELGA_MANDATE_ERROR_RECEIVED = 6002; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java index 87b3bc9ca..8efdf6014 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java @@ -54,6 +54,7 @@ import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -106,12 +107,14 @@ public class StatisticLogger { boolean isbusinessservice = isBusinessService(dbOA); dblog.setBusinessservice(isbusinessservice); dblog.setOatarget(authData.getBPKType()); - - dblog.setInterfederatedSSOSession(authData.isInterfederatedSSOSession()); + + + boolean isFederatedAuthentication = protocolRequest.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_RESPONSE) != null; + dblog.setInterfederatedSSOSession(isFederatedAuthentication); - if (authData.isInterfederatedSSOSession()) { + if (isFederatedAuthentication) { dblog.setBkutype(IOAAuthParameters.INDERFEDERATEDIDP); - dblog.setBkuurl(authData.getInterfederatedIDP()); + dblog.setBkuurl(protocolRequest.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_ENTITYID, String.class)); } else { dblog.setBkuurl(authData.getBkuURL()); @@ -252,7 +255,7 @@ public class StatisticLogger { dblog.setBkutype(findBKUType(moasession.getBkuURL(), dbOA)); } - dblog.setMandatelogin(moasession.getUseMandate()); + dblog.setMandatelogin(moasession.isMandateUsed()); } } catch (MOADatabaseException e) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java index 1a9018563..27c87ccbf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java @@ -25,6 +25,8 @@ public class MOAIDAuthConstants extends MOAIDConstants{ public static final String PARAM_TARGET = "Target"; /** servlet parameter "useMandate" */ public static final String PARAM_USEMANDATE = "useMandate"; + public static final String PARAM_USEMISMANDATE = "useMISMandate"; + public static final String PARAM_USEELGAMANDATE = "useELGAMandate"; /** servlet parameter "OA" */ public static final String PARAM_OA = "OA"; /** servlet parameter "bkuURI" */ @@ -166,6 +168,8 @@ public class MOAIDAuthConstants extends MOAIDConstants{ } }); + public static final String COUNTRYCODE_AUSTRIA = "AT"; + public static final String REGEX_PATTERN_TARGET = "^[A-Za-z]{2}(-.*)?$"; public static final String MDC_TRANSACTION_ID = "transactionId"; @@ -184,5 +188,7 @@ public class MOAIDAuthConstants extends MOAIDConstants{ public static final String AUTHPROCESS_DATA_TARGETFRIENDLYNAME = "authProces_TargetFriendlyName"; public static final String AUTHPROCESS_DATA_SECURITYLAYERTEMPLATE = "authProces_SecurityLayerTemplate"; + //General MOASession data-store keys + public static final String MOASESSION_DATA_HOLDEROFKEY_CERTIFICATE = "holderofkey_cert"; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java index ce158d7fe..458f9afe6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java @@ -1,6 +1,25 @@ - - - +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ package at.gv.egovernment.moa.id.auth; import java.io.IOException; @@ -10,27 +29,15 @@ import java.security.Security; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -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.support.GenericApplicationContext; -import org.springframework.web.WebApplicationInitializer; -import org.springframework.web.context.ContextLoaderListener; -import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.context.support.GenericWebApplicationContext; -import org.springframework.web.context.support.ServletContextResource; -import org.springframework.web.servlet.DispatcherServlet; -import at.gv.egiz.components.spring.api.SpringLoader; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SSLUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.logging.LoggingContext; @@ -44,124 +51,12 @@ import iaik.security.ecc.provider.ECCProvider; import iaik.security.provider.IAIK; /** - * Web application initializer - * - * @author Paul Ivancsics - * @version $Id$ + * @author tlenz + * */ -public class MOAIDAuthInitializer implements WebApplicationInitializer { - - private String[] rootServletContexts = null; - - private String[] servletContexts = null; - - private String[] activeProfiles = null; - - public MOAIDAuthInitializer() { - this.rootServletContexts = null; - this.servletContexts = new String[] { - "/WEB-INF/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 { - Logger.info("=============== Loading Root Context! ==============="); - GenericWebApplicationContext rootContext = new GenericWebApplicationContext(); - rootContext.setServletContext(servletContext); - - Logger.info("=============== Setting active profiles! ==============="); - if (this.activeProfiles != null) { - for (String profile : this.activeProfiles) { - rootContext.getEnvironment().addActiveProfile(profile); - } - } +public class MOAIDAuthInitializer { - Logger.info("=============== Loading Local Contexts! ==============="); - XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( - rootContext); - if (rootServletContexts != null) { - for (String rootServletContext : rootServletContexts) { - Logger.debug("Loading: "+ rootServletContext); - xmlReader.loadBeanDefinitions(new ServletContextResource( - servletContext, rootServletContext)); - } - } - // Manage the lifecycle of the root application context - servletContext.addListener(new ContextLoaderListener(rootContext)); - - // logger.debug("Beans after logAMQP in {}", rootContext); - // dumpBeanDefinitions(rootContext); - - Logger.info("=============== Loading SPI Context! ==============="); - // logger.debug("Startup with context {}", rootContext); - if (rootContext instanceof BeanDefinitionRegistry) { - Logger.debug("Loading EGIZ components"); - SpringLoader - .loadSpringServices(rootContext); - } else { - Logger.warn("Failed to load external Spring since no BeanDefinitionRegistry"); - } - - Logger.trace("Beans after SPI in "+ rootContext); - dumpBeanDefinitions(rootContext); - - Logger.debug("Loading servlet config in "+ rootContext); - if (servletContexts != null) { - for (String servletContextString : servletContexts) { - xmlReader.loadBeanDefinitions(new ServletContextResource( - servletContext, servletContextString)); - } - } - Logger.debug("Refreshing context "+ rootContext); - rootContext.refresh(); - - Logger.info("=============== Register Dispatcher Servlet! ==============="); - - Logger.trace("Final Beans in "+ rootContext); - dumpBeanDefinitions(rootContext); - - - Logger.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 { - Logger.error("Failed to register dispatcher server in servlet context!"); - } - - Logger.info("=============== Register RequestContextListener! ==============="); - servletContext.addListener(new RequestContextListener()); - - Logger.info("Basic Context initalisation finished --> Start MOA-ID-Auth initialisation process ..."); - MOAIDAuthInitializer.initialize(rootContext); - Logger.info(MOAIDMessageProvider.getInstance().getMessage( - "init.00", null)); - Logger.info("MOA-ID-Auth initialization finished."); - - - } catch (Throwable e) { - Logger.fatal( - MOAIDMessageProvider.getInstance().getMessage("init.02", - null), e); - - } - - } - - - - /** + /** * Initializes the web application components which need initialization: * logging, JSSE, MOA-ID Auth configuration, Axis, session cleaner. * @param rootContext @@ -220,6 +115,9 @@ public class MOAIDAuthInitializer implements WebApplicationInitializer { "http://www.w3.org/2001/04/xmldsig-more#"); Constants.nSMap.put(Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); + //seed the random number generator + Random.seedRandom(); + Logger.debug("Random-number generator is seeded."); // Initialize configuration provider AuthConfiguration authConf = AuthConfigurationProviderFactory.reload(rootContext); @@ -265,18 +163,4 @@ public class MOAIDAuthInitializer implements WebApplicationInitializer { MOAGarbageCollector.start(); } - - private void dumpBeanDefinitions(GenericApplicationContext context) { - Logger.trace("Registered Bean in context " + context.toString()); - - String[] registeredBeans = context.getBeanDefinitionNames(); - for (String registeredBean : registeredBeans) { - BeanDefinition beanDefinition = context - .getBeanDefinition(registeredBean); - Logger.trace(registeredBean + " -> " + beanDefinition.getBeanClassName()); - - } - - Logger.trace("Registered Bean in context --"+ context); - } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java deleted file mode 100644 index a82a958db..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ -package at.gv.egovernment.moa.id.auth; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -/** - * @author tlenz - * - */ -public class MOAIDAuthSpringResourceProvider implements SpringResourceProvider { - - /* (non-Javadoc) - * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getResourcesToLoad() - */ - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource moaidauthConfig = new ClassPathResource("/moaid.configuration.beans.xml", MOAIDAuthSpringResourceProvider.class); - ClassPathResource configurationDBConfig = new ClassPathResource("/configuration.beans.xml", MOAIDAuthSpringResourceProvider.class); - ClassPathResource moaIdAuthBeans = new ClassPathResource("/moaid.authentication.beans.xml", MOAIDAuthSpringResourceProvider.class); - - return new Resource[] {configurationDBConfig, moaidauthConfig, moaIdAuthBeans}; - - } - - /* (non-Javadoc) - * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getPackagesToScan() - */ - @Override - public String[] getPackagesToScan() { - // TODO Auto-generated method stub - return null; - } - - /* (non-Javadoc) - * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getName() - */ - @Override - public String getName() { - return "MOA-ID-Auth SpringResourceProvider"; - } - -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index 8a9999d85..32fabc3f4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -22,46 +22,31 @@ */ package at.gv.egovernment.moa.id.auth.builder; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeQuery; -import org.opensaml.saml2.core.AuthnStatement; import org.opensaml.saml2.core.Response; import org.opensaml.ws.soap.common.SOAPException; import org.opensaml.xml.XMLObject; -import org.opensaml.xml.security.SecurityException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; -import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; -import at.gv.e_government.reference.namespace.mandates._20040701_.Mandator; -import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; -import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; -import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; -import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; @@ -75,31 +60,26 @@ import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException; import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; -import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; -import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; -import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.data.AuthenticationRoleFactory; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.MISMandate; +import at.gv.egovernment.moa.id.data.Pair; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; -import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException; -import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; -import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.MOASAMLSOAPClient; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngineSP; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; @@ -111,7 +91,6 @@ import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moa.util.XPathUtils; import at.gv.util.client.szr.SZRClient; import at.gv.util.config.EgovUtilPropertiesConfiguration; -import at.gv.util.ex.EgovUtilException; import at.gv.util.wsdl.szr.SZRException; import at.gv.util.xsd.szr.PersonInfoType; import iaik.x509.X509Certificate; @@ -126,10 +105,17 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { @Autowired private IAuthenticationSessionStoreage authenticatedSessionStorage; @Autowired protected AuthConfiguration authConfig; @Autowired private AttributQueryBuilder attributQueryBuilder; - @Autowired private SAMLVerificationEngine samlVerificationEngine; + @Autowired private SAMLVerificationEngineSP samlVerificationEngine; - public IAuthData buildAuthenticationData(IRequest protocolRequest, - AuthenticationSession session, List<Attribute> reqAttributes) throws ConfigurationException, BuildException, WrongParametersException, DynamicOABuildException { + + public IAuthData buildAuthenticationData(IRequest pendingReq, + AuthenticationSession session) throws ConfigurationException, BuildException, WrongParametersException, DynamicOABuildException { + return buildAuthenticationData(pendingReq, session, pendingReq.getOnlineApplicationConfiguration()); + + } + + public IAuthData buildAuthenticationData(IRequest pendingReq, + AuthenticationSession session, IOAAuthParameters oaParam) throws ConfigurationException, BuildException, WrongParametersException, DynamicOABuildException { AuthenticationData authdata = null; //only needed for SAML1 legacy support @@ -138,7 +124,7 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { Class<?> saml1RequstTemplate = Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl"); IAuthData saml1authdata = (IAuthData) Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1AuthenticationData").newInstance(); if (saml1RequstTemplate != null && - saml1RequstTemplate.isInstance(protocolRequest)) { + saml1RequstTemplate.isInstance(pendingReq)) { //request is SAML1 --> invoke SAML1 protocol specific methods if (session.getExtendedSAMLAttributesOA() == null) { saml1authdata.getClass().getMethod("setExtendedSAMLAttributesOA", List.class).invoke(saml1authdata, new ArrayList<ExtendedSAMLAttribute>()); @@ -158,723 +144,695 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { authdata = new AuthenticationData(); } - - //reuse some parameters if it is a Service-Provider reauthentication - OASessionStore activeOA = authenticatedSessionStorage.searchActiveOASSOSession(session, protocolRequest.getOAURL(), protocolRequest.requestedModule()); + + OASessionStore activeOA = authenticatedSessionStorage.searchActiveOASSOSession(session, pendingReq.getOAURL(), pendingReq.requestedModule()); + //reuse authentication information in case of service-provider reauthentication if (activeOA != null) { authdata.setSessionIndex(activeOA.getAssertionSessionID()); authdata.setNameID(activeOA.getUserNameID()); authdata.setNameIDFormat(activeOA.getUserNameIDFormat()); - - //mark AttributeQuery as used - if ( protocolRequest instanceof PVPTargetConfiguration && - ((PVPTargetConfiguration) protocolRequest).getRequest() instanceof MOARequest && - ((PVPTargetConfiguration) protocolRequest).getRequest().getInboundMessage() instanceof AttributeQuery) { - try { - activeOA.setAttributeQueryUsed(true); - MOASessionDBUtils.saveOrUpdate(activeOA); - - } catch (MOADatabaseException e) { - Logger.error("MOASession interfederation information can not stored to database.", e); - - } - } - } - - //search federated IDP information in MOASession - InterfederationSessionStore interfIDP = authenticatedSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(session); - - IOAAuthParameters oaParam = null; - if (reqAttributes == null) { - //get OnlineApplication from MOA-ID-Auth configuration - oaParam = protocolRequest.getOnlineApplicationConfiguration(); - - //build OA dynamically from STROK request if this OA is used as STORK<->PVP gateway - if (oaParam.isSTORKPVPGateway()) - oaParam = DynamicOAAuthParameterBuilder.buildFromAuthnRequest(oaParam, protocolRequest); - } else { - //build OnlineApplication dynamic from requested attributes (AttributeQuerry Request) - oaParam = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes, interfIDP); - } - if (interfIDP != null ) { - //authentication by using a federated IDP - if (oaParam.isInderfederationIDP() && protocolRequest instanceof PVPTargetConfiguration && - !(((PVPTargetConfiguration)protocolRequest).getRequest() instanceof AttributeQuery)) { - //IDP is a chained interfederated IDP and Authentication is requested + //TODO: move to eIDAS-Code in case of ISA1.18 action is enabled for eIDAS + //build OA dynamically from STROK request if this OA is used as STORK<->PVP gateway + if (oaParam.isSTORKPVPGateway()) + oaParam = DynamicOAAuthParameterBuilder.buildFromAuthnRequest(oaParam, pendingReq); - //only set minimal response attributes - authdata.setQAALevel(interfIDP.getQAALevel()); - authdata.setBPK(interfIDP.getUserNameID()); - - } else { - //get attributes from interfederated IDP - OAAuthParameter idp = authConfig.getOnlineApplicationParameter(interfIDP.getIdpurlprefix()); - getAuthDataFromInterfederation(authdata, session, oaParam, protocolRequest, interfIDP, idp, reqAttributes); - - //mark attribute request as used - try { - interfIDP.setAttributesRequested(true); - MOASessionDBUtils.saveOrUpdate(interfIDP); - - } catch (MOADatabaseException e) { - Logger.error("MOASession interfederation information can not stored to database.", e); - - } - } - + Boolean isMinimalFrontChannelResp = pendingReq.getGenericData( + PVPTargetConfiguration.DATAID_INTERFEDERATION_MINIMAL_FRONTCHANNEL_RESP, Boolean.class); + if (isMinimalFrontChannelResp != null && isMinimalFrontChannelResp) { + //only set minimal response attributes + authdata.setQAALevel( + pendingReq.getGenericData(PVPTargetConfiguration.DATAID_INTERFEDERATION_QAALEVEL, String.class)); + authdata.setBPK( + pendingReq.getGenericData(PVPTargetConfiguration.DATAID_INTERFEDERATION_NAMEID, String.class)); + } else { //build AuthenticationData from MOASession - buildAuthDataFormMOASession(authdata, session, oaParam, protocolRequest); - + buildAuthDataFormMOASession(authdata, session, oaParam, pendingReq); + } return authdata; } /** - * @param req - * @param session - * @param reqAttributes - * @return - * @throws WrongParametersException - * @throws ConfigurationException - * @throws BuildException - * @throws DynamicOABuildException + * Get PVP authentication attributes by using a SAML2 AttributeQuery + * + * @param reqQueryAttr List of PVP attributes which are requested + * @param userNameID SAML2 UserNameID of the user for which attributes are requested + * @param idpConfig Configuration of the IDP, which is requested + * @return + * @return PVP attribute DAO, which contains all received information + * @throws MOAIDException */ - public IAuthData buildAuthenticationData(IRequest req, - AuthenticationSession session) throws WrongParametersException, ConfigurationException, BuildException, DynamicOABuildException { - return buildAuthenticationData(req, session, null); - } - - /** - * @param authdata - * @param session - * @param oaParam - * @param protocolRequest - * @param interfIDP - * @param idp - * @param reqQueryAttr - * @throws ConfigurationException - */ - private void getAuthDataFromInterfederation( - AuthenticationData authdata, AuthenticationSession session, - IOAAuthParameters oaParam, IRequest req, - InterfederationSessionStore interfIDP, OAAuthParameter idp, List<Attribute> reqQueryAttr) throws BuildException, ConfigurationException{ + public AssertionAttributeExtractor getAuthDataFromAttributeQuery(List<Attribute> reqQueryAttr, + String userNameID, IOAAuthParameters idpConfig ) throws MOAIDException{ + String idpEnityID = idpConfig.getPublicURLPrefix(); try { - List<Attribute> attributs = null; - - //IDP is a chained interfederated IDP and request is of type AttributQuery - if (oaParam.isInderfederationIDP() && req instanceof PVPTargetConfiguration && - (((PVPTargetConfiguration)req).getRequest() instanceof AttributeQuery) && - reqQueryAttr != null) { - attributs = reqQueryAttr; - - //IDP is a service provider IDP and request interfederated IDP to collect attributes - } else { - //get PVP 2.1 attributes from protocol specific requested attributes - attributs = (List<Attribute>) req.getGenericData(RequestImpl.DATAID_REQUESTED_ATTRIBUTES); + Logger.debug("Starting AttributeQuery process ..."); + //collect attributes by using BackChannel communication + String endpoint = idpConfig.getIDPAttributQueryServiceURL(); + if (MiscUtil.isEmpty(endpoint)) { + Logger.error("No AttributeQueryURL for interfederationIDP " + idpEnityID); + throw new ConfigurationException("config.26", new Object[]{idpEnityID}); } - - //get SAML2 Response from federated IDP - Response intfResp = - (Response) req.getGenericData( - RequestImpl.DATAID_INTERFEDERATIOIDP_RESPONSE, MOAResponse.class).getResponse(); - - //initialize Attribute extractor - AssertionAttributeExtractor extractor = new AssertionAttributeExtractor(intfResp); - - //check if SAML2 Assertion contains already all required attributes - if (!extractor.containsAllRequiredAttributes()) { - Logger.info("Received assertion does no contain a minimum set of attributes. Starting AttributeQuery process ..."); - //collect attributes by using BackChannel communication - String endpoint = idp.getIDPAttributQueryServiceURL(); - if (MiscUtil.isEmpty(endpoint)) { - Logger.error("No AttributeQueryURL for interfederationIDP " + idp.getPublicURLPrefix()); - throw new ConfigurationException("No AttributeQueryURL for interfederationIDP " + idp.getPublicURLPrefix(), null); - } - //build attributQuery request - AttributeQuery query = - attributQueryBuilder.buildAttributQueryRequest(interfIDP.getUserNameID(), endpoint, attributs); + //build attributQuery request + AttributeQuery query = attributQueryBuilder.buildAttributQueryRequest(userNameID, endpoint, reqQueryAttr); - //build SOAP request - List<XMLObject> xmlObjects = MOASAMLSOAPClient.send(endpoint, query); + //build SOAP request + List<XMLObject> xmlObjects = MOASAMLSOAPClient.send(endpoint, query); + + if (xmlObjects.size() == 0) { + Logger.error("Receive emptry AttributeQuery response-body."); + throw new AttributQueryException("auth.27", + new Object[]{idpEnityID, "Receive emptry AttributeQuery response-body."}); - if (xmlObjects.size() == 0) { - Logger.error("Receive emptry AttributeQuery response-body."); - throw new AttributQueryException("Receive emptry AttributeQuery response-body.", null); - - } + } + + Response intfResp; + if (xmlObjects.get(0) instanceof Response) { + intfResp = (Response) xmlObjects.get(0); - if (xmlObjects.get(0) instanceof Response) { - intfResp = (Response) xmlObjects.get(0); - - //validate PVP 2.1 response - try { - samlVerificationEngine.verifyIDPResponse(intfResp, TrustEngineFactory.getSignatureKnownKeysTrustEngine()); - - //TODO: find better solution - //SAMLVerificationEngine.validateAssertion(intfResp, false); - - } catch (Exception e) { - Logger.warn("PVP 2.1 assertion validation FAILED.", e); - throw new AssertionValidationExeption("PVP 2.1 assertion validation FAILED.", null, e); - } - - } else { - Logger.error("Receive AttributeQuery response-body include no PVP 2.1 response"); - throw new AttributQueryException("Receive AttributeQuery response-body include no PVP 2.1 response.", null); - + //validate PVP 2.1 response + try { + samlVerificationEngine.verifyIDPResponse(intfResp, + TrustEngineFactory.getSignatureKnownKeysTrustEngine( + MOAMetadataProvider.getInstance())); + + //create assertion attribute extractor from AttributeQuery response + return new AssertionAttributeExtractor(intfResp); + + } catch (Exception e) { + Logger.warn("PVP 2.1 assertion validation FAILED.", e); + throw new AssertionValidationExeption("auth.27", + new Object[]{idpEnityID, e.getMessage()}, e); } - - //create assertion attribute extractor from AttributeQuery response - extractor = new AssertionAttributeExtractor(intfResp); - + } else { - Logger.info("Interfedation response include all attributes with are required. Skip AttributQuery request step. "); - - } - //parse response information to authData - buildAuthDataFormInterfederationResponse(authdata, session, extractor, oaParam, req); + Logger.error("Receive AttributeQuery response-body include no PVP 2.1 response"); + throw new AttributQueryException("auth.27", + new Object[]{idpEnityID, "Receive AttributeQuery response-body include no PVP 2.1 response"}); + } + } catch (SOAPException e) { throw new BuildException("builder.06", null, e); } catch (SecurityException e) { throw new BuildException("builder.06", null, e); - - } catch (AttributQueryException e) { - throw new BuildException("builder.06", null, e); - - } catch (BuildException e) { - throw new BuildException("builder.06", null, e); - - } catch (AssertionValidationExeption e) { - throw new BuildException("builder.06", null, e); - - } catch (AssertionAttributeExtractorExeption e) { - throw new BuildException("builder.06", null, e); + + } catch (org.opensaml.xml.security.SecurityException e1) { + throw new BuildException("builder.06", null, e1); } } - - private void buildAuthDataFormInterfederationResponse( - AuthenticationData authData, - AuthenticationSession session, - AssertionAttributeExtractor extractor, - IOAAuthParameters oaParam, - IRequest req) - throws BuildException, AssertionAttributeExtractorExeption { - Logger.debug("Build AuthData from assertion starts ...."); - - authData.setIsBusinessService(oaParam.getBusinessService()); + private void buildAuthDataFormMOASession(AuthenticationData authData, AuthenticationSession session, + IOAAuthParameters oaParam, IRequest protocolRequest) throws BuildException, ConfigurationException { + + Collection<String> includedToGenericAuthData = null; + if (session.getGenericSessionDataStorage() != null && + !session.getGenericSessionDataStorage().isEmpty()) + includedToGenericAuthData = session.getGenericSessionDataStorage().keySet(); + else + includedToGenericAuthData = new ArrayList<String>(); - authData.setFamilyName(extractor.getSingleAttributeValue(PVPConstants.PRINCIPAL_NAME_NAME)); - authData.setGivenName(extractor.getSingleAttributeValue(PVPConstants.GIVEN_NAME_NAME)); - authData.setDateOfBirth(extractor.getSingleAttributeValue(PVPConstants.BIRTHDATE_NAME)); - authData.setCcc(extractor.getSingleAttributeValue(PVPConstants.EID_ISSUING_NATION_NAME)); - authData.setBkuURL(extractor.getSingleAttributeValue(PVPConstants.EID_CCS_URL_NAME)); - authData.setIdentificationValue(extractor.getSingleAttributeValue(PVPConstants.EID_SOURCE_PIN_NAME)); - authData.setIdentificationType(extractor.getSingleAttributeValue(PVPConstants.EID_SOURCE_PIN_TYPE_NAME)); + try { + //#################################################### + //set general authData info's + authData.setIssuer(protocolRequest.getAuthURL()); + authData.setSsoSession(protocolRequest.needSingleSignOnFunctionality()); + authData.setIsBusinessService(oaParam.getBusinessService()); - if (extractor.containsAttribute(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) { - String bpkType = extractor.getSingleAttributeValue(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME); - if (bpkType.startsWith(Constants.URN_PREFIX_CDID) && - !bpkType.substring(Constants.URN_PREFIX_CDID.length(), - Constants.URN_PREFIX_CDID.length() + 1).equals("+")) { - Logger.warn("Receive uncorrect encoded bBKType attribute " + bpkType + " Starting attribute value correction ... "); - bpkType = Constants.URN_PREFIX_CDID + "+" + bpkType.substring(Constants.URN_PREFIX_CDID.length() + 1); - - } - - authData.setBPKType(bpkType); - } - - if (extractor.containsAttribute(PVPConstants.BPK_NAME)) { - String pvpbPK = extractor.getSingleAttributeValue(PVPConstants.BPK_NAME); + //#################################################### + //parse user info's from identityLink + IdentityLink idlFromPVPAttr = null; + IdentityLink identityLink = session.getIdentityLink(); + if (identityLink != null) { + parseBasicUserInfosFromIDL(authData, identityLink, includedToGenericAuthData); - if (pvpbPK.startsWith("bPK:")) { - Logger.warn("Attribute " + PVPConstants.BPK_NAME - + " contains a not standardize prefix! Staring attribute value correction process ..."); - pvpbPK = pvpbPK.substring("bPK:".length()); + } else { + // identityLink is not direct in MOASession + String pvpAttrIDL = session.getGenericDataFromSession(PVPConstants.EID_IDENTITY_LINK_NAME, String.class); + //find PVP-Attr. which contains the IdentityLink + if (MiscUtil.isNotEmpty(pvpAttrIDL)) { + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_IDENTITY_LINK_FRIENDLY_NAME + + " --> Parse basic user info's from that attribute."); + InputStream idlStream = null; + try { + idlStream = Base64Utils.decodeToStream(pvpAttrIDL, false); + idlFromPVPAttr = new IdentityLinkAssertionParser(idlStream).parseIdentityLink(); + parseBasicUserInfosFromIDL(authData, idlFromPVPAttr, includedToGenericAuthData); + + } catch (ParseException e) { + Logger.error("Received IdentityLink is not valid", e); + + } catch (Exception e) { + Logger.error("Received IdentityLink is not valid", e); + + } finally { + try { + includedToGenericAuthData.remove(PVPConstants.EID_IDENTITY_LINK_NAME); + if (idlStream != null) + idlStream.close(); + + } catch (IOException e) { + Logger.fatal("Close InputStream FAILED.", e); + + } + + } + + } + //if no basic user info's are set yet, parse info's single PVP-Attributes + if (MiscUtil.isEmpty(authData.getFamilyName())) { + Logger.debug("No IdentityLink found or not parseable --> Parse basic user info's from single PVP-Attributes."); + authData.setFamilyName(session.getGenericDataFromSession(PVPConstants.PRINCIPAL_NAME_NAME, String.class)); + authData.setGivenName(session.getGenericDataFromSession(PVPConstants.GIVEN_NAME_NAME, String.class)); + authData.setDateOfBirth(session.getGenericDataFromSession(PVPConstants.BIRTHDATE_NAME, String.class)); + authData.setIdentificationValue(session.getGenericDataFromSession(PVPConstants.EID_SOURCE_PIN_NAME, String.class)); + authData.setIdentificationType(session.getGenericDataFromSession(PVPConstants.EID_SOURCE_PIN_TYPE_NAME, String.class)); + + //remove corresponding keys from genericSessionData if exists + includedToGenericAuthData.remove(PVPConstants.PRINCIPAL_NAME_NAME); + includedToGenericAuthData.remove(PVPConstants.GIVEN_NAME_NAME); + includedToGenericAuthData.remove(PVPConstants.BIRTHDATE_NAME); + includedToGenericAuthData.remove(PVPConstants.EID_SOURCE_PIN_NAME); + includedToGenericAuthData.remove(PVPConstants.EID_SOURCE_PIN_TYPE_NAME); + } + } - String[] spitted = pvpbPK.split(":"); - authData.setBPK(spitted[1]); - if (MiscUtil.isEmpty(authData.getBPKType())) { - Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " + - "Starting target extraction from bPK/wbPK prefix ..."); - //exract bPK/wbPK type from bpk attribute value prefix if type is - //not transmitted as single attribute - Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?"); - Matcher matcher = pattern.matcher(spitted[0]); - if (matcher.matches()) { - //find public service bPK - authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]); - Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType()); - - } else { - //find business service wbPK - authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]); - Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType()); - - } - } - } - - boolean foundEncryptedbPKForOA = false; - if (extractor.containsAttribute(PVPConstants.ENC_BPK_LIST_NAME)) { - List<String> encbPKList = Arrays.asList( - extractor.getSingleAttributeValue(PVPConstants.ENC_BPK_LIST_NAME).split(";")); - authData.setEncbPKList(encbPKList); - for (String fullEncbPK : encbPKList) { - int index = fullEncbPK.indexOf("|"); - if (index >= 0) { - String encbPK = fullEncbPK.substring(index+1); - String second = fullEncbPK.substring(0, index); - int secIndex = second.indexOf("+"); - if (secIndex >= 0) { - if (oaParam.getTarget().equals(second.substring(secIndex+1))) { - Logger.debug("Found encrypted bPK for online-application " - + oaParam.getPublicURLPrefix() - + " Start decryption process ..."); - PrivateKey privKey = oaParam.getBPKDecBpkDecryptionKey(); - foundEncryptedbPKForOA = true; - if (privKey != null) { - try { - String bPK = BPKBuilder.decryptBPK(encbPK, oaParam.getTarget(), privKey); - if (MiscUtil.isNotEmpty(bPK)) { - if (MiscUtil.isEmpty(authData.getBPK())) { - authData.setBPK(bPK); - authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + oaParam.getTarget()); - Logger.info("bPK decryption process finished successfully."); - } - - } else { - Logger.error("bPK decryption FAILED."); - - } - } catch (BuildException e) { - Logger.error("bPK decryption FAILED.", e); - - } - - } else { - Logger.info("bPK decryption FAILED, because no valid decryption key is found."); + if (authData.getIdentificationType() != null && + !authData.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + Logger.trace("IdentificationType is not a baseID --> clear it. "); + authData.setBPK(authData.getIdentificationValue()); + authData.setBPKType(authData.getIdentificationType()); + + authData.setIdentificationValue(null); + authData.setIdentificationType(null); - } - - } else { - Logger.info("Found encrypted bPK but " + - "encrypted bPK target does not match to online-application target"); - - } - } - } - } - } - - if (MiscUtil.isEmpty(authData.getIdentificationValue()) && - MiscUtil.isEmpty(authData.getBPK()) && - !foundEncryptedbPKForOA) { - Logger.info("Federated assertion include no bPK, encrypted bPK or baseID"); - throw new AssertionAttributeExtractorExeption("No " + PVPConstants.BPK_FRIENDLY_NAME - + " or " + PVPConstants.EID_SOURCE_PIN_NAME - + " or " + PVPConstants.ENC_BPK_LIST_NAME); + } - } - - //check if received bPK matchs to online application configuration - //and no encrypted bPK is found for this oa - if (!matchsReceivedbPKToOnlineApplication(oaParam, authData) - && !foundEncryptedbPKForOA) { - Logger.info("Received bPK/wbPK does not match to online application"); - if (MiscUtil.isEmpty(authData.getIdentificationValue())) { - Logger.info("No baseID found. Connect SZR to reveive baseID ..."); - try { - EgovUtilPropertiesConfiguration eGovClientsConfig = authConfig.geteGovUtilsConfig(); - if (eGovClientsConfig != null) { - SZRClient szrclient = new SZRClient(eGovClientsConfig); - - Logger.debug("Create SZR request to get baseID ... "); - PersonInfoType personInfo = new PersonInfoType(); - at.gv.util.xsd.szr.persondata.PhysicalPersonType person = new at.gv.util.xsd.szr.persondata.PhysicalPersonType(); - personInfo.setPerson(person); - at.gv.util.xsd.szr.persondata.PersonNameType name = new at.gv.util.xsd.szr.persondata.PersonNameType(); - person.setName(name); - at.gv.util.xsd.szr.persondata.IdentificationType idValue = new at.gv.util.xsd.szr.persondata.IdentificationType(); - person.setIdentification(idValue); + //#################################################### + //set BKU URL + includedToGenericAuthData.remove(PVPConstants.EID_CCS_URL_NAME); + if (MiscUtil.isNotEmpty(session.getBkuURL())) + authData.setBkuURL(session.getBkuURL()); + else + authData.setBkuURL(session.getGenericDataFromSession(PVPConstants.EID_CCS_URL_NAME, String.class)); - //set bPK or wbPK - idValue.setValue(authData.getBPK()); - idValue.setType(authData.getBPKType()); + + //#################################################### + //set QAA level + includedToGenericAuthData.remove(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME); + if (MiscUtil.isNotEmpty(session.getQAALevel())) + authData.setQAALevel(session.getQAALevel()); + + else { + String qaaLevel = session.getGenericDataFromSession(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME, String.class); + if (MiscUtil.isNotEmpty(qaaLevel)) { + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME + + " --> Parse QAA-Level from that attribute."); - //set person information - name.setGivenName(authData.getGivenName()); - name.setFamilyName(authData.getFamilyName()); - if (authData.getDateOfBirth() != null) - person.setDateOfBirth(authData.getFormatedDateOfBirth()); + if (qaaLevel.startsWith(PVPConstants.STORK_QAA_PREFIX)) { + authData.setQAALevel(qaaLevel); - //request szr and store baseID - authData.setIdentificationValue(szrclient.getStammzahl(personInfo)); - authData.setIdentificationType(Constants.URN_PREFIX_BASEID); - } else { - Logger.warn("No SZR clieht configuration found. Interfederation SSO login not possible."); - throw new AssertionAttributeExtractorExeption("No " + PVPConstants.BPK_FRIENDLY_NAME - + " or " + PVPConstants.EID_SOURCE_PIN_NAME); - + Logger.debug("Found PVP QAA level. QAA mapping process starts ... "); + String mappedQAA = PVPtoSTORKMapper.getInstance().mapToQAALevel(qaaLevel); + if (MiscUtil.isNotEmpty(mappedQAA)) + authData.setQAALevel(mappedQAA); + } - - } catch (EgovUtilException e) { - Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); - throw new AssertionAttributeExtractorExeption("No " + PVPConstants.BPK_FRIENDLY_NAME - + " or " + PVPConstants.EID_SOURCE_PIN_NAME); - - } catch (SZRException e) { - Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); - throw new AssertionAttributeExtractorExeption("No " + PVPConstants.BPK_FRIENDLY_NAME - + " or " + PVPConstants.EID_SOURCE_PIN_NAME); - } } - //build OA specific bPK/wbPK information - buildOAspecificbPK(req, oaParam, authData, - authData.getIdentificationValue(), - authData.getIdentificationType()); + //if no QAA level is set in MOASession then set default QAA level + if (MiscUtil.isEmpty(authData.getQAALevel())) { + Logger.info("No QAA level found. Set to default level " + PVPConstants.STORK_QAA_PREFIX + "1"); + authData.setQAALevel(PVPConstants.STORK_QAA_PREFIX + "1"); + + } + - } - - if (MiscUtil.isEmpty(authData.getBPK())) { - Logger.debug("Calcutlate bPK from baseID"); - buildOAspecificbPK(req, oaParam, authData, - authData.getIdentificationValue(), - authData.getIdentificationType()); + //#################################################### + //set signer certificate + includedToGenericAuthData.remove(PVPConstants.EID_SIGNER_CERTIFICATE_NAME); + if (session.getEncodedSignerCertificate() != null) + authData.setSignerCertificate(session.getEncodedSignerCertificate()); - } - - - try { - String qaaLevel = extractor.getQAALevel(); - if (MiscUtil.isNotEmpty(qaaLevel) && - qaaLevel.startsWith(PVPConstants.STORK_QAA_PREFIX)) { - authData.setQAALevel(qaaLevel); + else { + String pvpAttrSignerCert = session.getGenericDataFromSession(PVPConstants.EID_SIGNER_CERTIFICATE_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpAttrSignerCert)) { + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_SIGNER_CERTIFICATE_FRIENDLY_NAME); + try { + authData.setSignerCertificate(Base64Utils.decode(pvpAttrSignerCert, false)); + + } catch (IOException e) { + Logger.error("SignerCertificate received via federated IDP is NOT valid", e); + + } + } else + Logger.info("NO SignerCertificate in MOASession."); + + } + + + //#################################################### + //set authBlock + includedToGenericAuthData.remove(PVPConstants.EID_AUTH_BLOCK_NAME); + if (MiscUtil.isNotEmpty(session.getAuthBlock())) { + authData.setAuthBlock(session.getAuthBlock()); } else { - Logger.debug("Found PVP QAA level. QAA mapping process starts ... "); - String mappedQAA = PVPtoSTORKMapper.getInstance().mapToQAALevel(qaaLevel); - if (MiscUtil.isNotEmpty(mappedQAA)) - authData.setQAALevel(mappedQAA); + String pvpAttrAuthBlock = session.getGenericDataFromSession(PVPConstants.EID_AUTH_BLOCK_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpAttrAuthBlock)) { + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_AUTH_BLOCK_FRIENDLY_NAME); + try { + byte[] authBlock = Base64Utils.decode(pvpAttrAuthBlock, false); + authData.setAuthBlock(new String(authBlock, "UTF-8")); + + } catch (IOException e) { + Logger.error("AuthBlock received via federated IDP is NOT valid", e); + + } + + } else + Logger.info("NO AuthBlock in MOASession."); + + } + + + //#################################################### + //set isForeigner flag + //TODO: change to new eIDAS-token attribute identifier + if (session.getGenericDataFromSession(PVPConstants.EID_STORK_TOKEN_NAME) != null) { + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_STORK_TOKEN_FRIENDLY_NAME + + " --> Set 'isForeigner' flag to TRUE"); + authData.setForeigner(true); - else - throw new AssertionAttributeExtractorExeption("PVP SecClass not mappable"); + } else { + authData.setForeigner(session.isForeigner()); } - - } catch (AssertionAttributeExtractorExeption e) { - Logger.warn("No QAA level found in <RequestedAuthnContext> element of interfederated assertion. " + - "(ErrorHeader=" + e.getMessage() + ")"); - if (extractor.containsAttribute(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME)) { - authData.setQAALevel(PVPConstants.STORK_QAA_PREFIX + - extractor.getSingleAttributeValue(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME)); - } else { - Logger.info("No QAA level found. Set to default level " + - PVPConstants.STORK_QAA_PREFIX + "1"); - authData.setQAALevel(PVPConstants.STORK_QAA_PREFIX + "1"); + + //#################################################### + //set citizen country-code + includedToGenericAuthData.remove(PVPConstants.EID_ISSUING_NATION_NAME); + String pvpCCCAttr = session.getGenericDataFromSession(PVPConstants.EID_ISSUING_NATION_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpCCCAttr)) { + authData.setCcc(pvpCCCAttr); + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_ISSUING_NATION_FRIENDLY_NAME); + } else { + if (authData.isForeigner()) { + try { + if (authData.getSignerCertificate() != null) { + //TODO: replace with TSL lookup when TSL is ready! + X509Certificate certificate = new X509Certificate(authData.getSignerCertificate()); + if (certificate != null) { + LdapName ln = new LdapName(certificate.getIssuerDN() + .getName()); + for (Rdn rdn : ln.getRdns()) { + if (rdn.getType().equalsIgnoreCase("C")) { + Logger.info("C is: " + rdn.getValue()); + authData.setCcc(rdn.getValue().toString()); + break; + } + } + } + + } else + Logger.warn("NO PVP-Attr: " + PVPConstants.EID_ISSUING_NATION_NAME + + " and NO SignerCertificate in MOASession -->" + + " Can NOT extract citizen-country of foreign person."); + + + } catch (Exception e) { + Logger.error("Failed to extract country code from certificate with message: " + e.getMessage()); + + } + + } else { + authData.setCcc(COUNTRYCODE_AUSTRIA); + + } } - - } - - if (extractor.containsAttribute(PVPConstants.EID_AUTH_BLOCK_NAME)) { - try { - byte[] authBlock = Base64Utils.decode(extractor.getSingleAttributeValue(PVPConstants.EID_AUTH_BLOCK_NAME), false); - authData.setAuthBlock(new String(authBlock, "UTF-8")); - } catch (IOException e) { - Logger.error("Received AuthBlock is not valid", e); + + //#################################################### + //set max. SSO session time + includedToGenericAuthData.remove(AuthenticationSessionStorageConstants.FEDERATION_RESPONSE_VALIDE_TO); + Date validToFromFederatedIDP = session.getGenericDataFromSession( + AuthenticationSessionStorageConstants.FEDERATION_RESPONSE_VALIDE_TO, Date.class); + if (validToFromFederatedIDP != null) { + authData.setSsoSessionValidTo(validToFromFederatedIDP); + Logger.debug("Use idToken validTo periode from federated IDP response."); + + } else { + if (authData.isSsoSession()) { + long maxSSOSessionTime = authConfig.getSSOCreatedTimeOut() * 1000; + Date ssoSessionValidTo = new Date(session.getSessionCreated().getTime() + maxSSOSessionTime); + authData.setSsoSessionValidTo(ssoSessionValidTo); + } else { + //set valid to 5 min + Date ssoSessionValidTo = new Date(new Date().getTime() + 5 * 60 * 1000); + authData.setSsoSessionValidTo(ssoSessionValidTo); + + } } - } - - if (extractor.containsAttribute(PVPConstants.EID_SIGNER_CERTIFICATE_NAME)) { - try { - authData.setSignerCertificate(Base64Utils.decode( - extractor.getSingleAttributeValue(PVPConstants.EID_SIGNER_CERTIFICATE_NAME), false)); + + //mandate functionality + MISMandate misMandate = null; + if (session.isMandateUsed()) { + //#################################################### + //set Mandate reference value + includedToGenericAuthData.remove(PVPConstants.MANDATE_REFERENCE_VALUE_NAME); + if (MiscUtil.isNotEmpty(session.getMandateReferenceValue())) + authData.setMandateReferenceValue(session.getMandateReferenceValue()); - } catch (IOException e) { - Logger.error("Received SignerCertificate is not valid", e); + else { + String pvpMandateRefAttr = session.getGenericDataFromSession(PVPConstants.MANDATE_REFERENCE_VALUE_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpMandateRefAttr)) { + authData.setMandateReferenceValue(pvpMandateRefAttr); + Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_REFERENCE_VALUE_FRIENDLY_NAME); + } + } - } - } - if (extractor.containsAttribute(PVPConstants.EID_IDENTITY_LINK_NAME)) { - try { - InputStream idlStream = Base64Utils.decodeToStream(extractor.getSingleAttributeValue(PVPConstants.EID_IDENTITY_LINK_NAME), false); - IdentityLink idl = new IdentityLinkAssertionParser(idlStream).parseIdentityLink(); - idlStream.close(); - buildOAspecificIdentityLink(oaParam, authData, idl); - - } catch (ParseException e) { - Logger.error("Received IdentityLink is not valid", e); + /* TODO: Support SSO Mandate MODE! + * Insert functionality to translate mandates in case of SSO + */ - } catch (Exception e) { - Logger.error("Received IdentityLink is not valid", e); + //#################################################### + //set Full-mandate + misMandate = session.getMISMandate(); + if (misMandate != null ) { + //set MIS mandate to authdata + authData.setMISMandate(misMandate); + authData.setUseMandate(session.isMandateUsed()); + + } else { + String pvpFullMandateAttr = session.getGenericDataFromSession( + PVPConstants.MANDATE_FULL_MANDATE_NAME, String.class); + //check if full-mandate is available as PVP attribute + if (MiscUtil.isNotEmpty(pvpFullMandateAttr)) { + Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_FULL_MANDATE_FRIENDLY_NAME); + try { + byte[] mandate = Base64Utils.decode(pvpFullMandateAttr, false); + misMandate = new MISMandate(); + misMandate.setMandate(mandate); + + //read Organwalter OID + String pvpRepOIDAttr = session.getGenericDataFromSession(PVPConstants.MANDATE_PROF_REP_OID_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpRepOIDAttr)) { + misMandate.setProfRep(pvpRepOIDAttr); + Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_PROF_REP_OID_NAME); + + } + + //read Organwalter bPK from full-mandate + NodeList mandateElements = misMandate.getMandateDOM().getChildNodes(); + for (int i=0; i<mandateElements.getLength(); i++) { + Element mandateEl = (Element) mandateElements.item(i); + if (mandateEl.hasAttribute("OWbPK")) { + misMandate.setOWbPK(mandateEl.getAttribute("OWbPK")); + session.setOW(true); + + } + } + + authData.setMISMandate(misMandate); + authData.setUseMandate(true); + + } catch (IOException e) { + Logger.error("Base64 decoding of PVP-Attr:"+ PVPConstants.MANDATE_FULL_MANDATE_FRIENDLY_NAME + + " FAILED.", e); + + } + + } else { + Logger.debug("No full MIS-Mandate found --> Use single PVP attributes for mandate information."); + //check if ELGA mandates exists + String mandateType = session.getGenericDataFromSession(PVPConstants.MANDATE_TYPE_NAME, String.class); + if (MiscUtil.isNotEmpty(mandateType)) { + //switch to mandate-mode for authdata generation, because mandate-information + // is directly included in MOA-Session as PVP attributes + Logger.info("AuthDataBuilder find directly included 'MandateType' PVP-attribute." + + " --> Switch to mandate-mode for authdata generation."); + authData.setUseMandate(true); + + } + } + } + //remove PVP attributes with mandate information, because full-mandate exists + if (authData.getMISMandate() != null) { + includedToGenericAuthData.remove(PVPConstants.MANDATE_FULL_MANDATE_NAME); + + includedToGenericAuthData.remove(PVPConstants.MANDATE_TYPE_NAME); + + includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME); + + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_BPK_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME); + + includedToGenericAuthData.remove(PVPConstants.MANDATE_PROF_REP_DESC_NAME); + includedToGenericAuthData.remove(PVPConstants.MANDATE_PROF_REP_OID_NAME); + } } - } - // set mandate attributes - authData.setMandateReferenceValue(extractor.getSingleAttributeValue(PVPConstants.MANDATE_REFERENCE_VALUE_NAME)); - - if (extractor.containsAttribute(PVPConstants.MANDATE_FULL_MANDATE_NAME)) { - try { - byte[] mandate = Base64Utils.decode( - (extractor.getSingleAttributeValue(PVPConstants.MANDATE_FULL_MANDATE_NAME)), false); + + + + //#################################################### + // set bPK and IdentityLink for Organwalter --> + // Organwalter has a special bPK is received from MIS + if (authData.isUseMandate() && session.isOW() && misMandate != null + && MiscUtil.isNotEmpty(misMandate.getOWbPK())) { + //TODO: if full-mandate is removed in OPB --> OWbPK functionality needs an update!!! + authData.setBPK(misMandate.getOWbPK()); + authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + "OW"); + Logger.trace("Authenticated User is OW: " + misMandate.getOWbPK()); - if (authData.getMISMandate() == null) - authData.setMISMandate(new MISMandate()); - authData.getMISMandate().setMandate(mandate); - authData.getMISMandate().setFullMandateIncluded(true); - authData.setUseMandate(true); - - } catch (Exception e) { - Logger.error("Received Mandate is not valid", e); - throw new AssertionAttributeExtractorExeption(PVPConstants.MANDATE_FULL_MANDATE_NAME); - } - } - - //TODO: build short mandate if full mandate is no included. - if (authData.getMISMandate() == null && - (extractor.containsAttribute(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME) - || extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_BPK_NAME) - || extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME)) ) { - Logger.info("Federated assertion contains no full mandate. Start short mandate generation process ... "); - - MISMandate misMandate = new MISMandate(); - misMandate.setFullMandateIncluded(false); - - Mandate mandateObject = new Mandate(); - Mandator mandator = new Mandator(); - mandateObject.setMandator(mandator); + //TODO: check in case of mandates for business services + if (identityLink != null) + authData.setIdentityLink(identityLink); - //build legal person short mandate - if (extractor.containsAttribute(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME) && - extractor.containsAttribute(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME) && - extractor.containsAttribute(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME)) { - Logger.debug("Build short mandate for legal person ..."); - CorporateBodyType legalperson = new CorporateBodyType(); - IdentificationType legalID = new IdentificationType(); - Value idvalue = new Value(); - legalID.setValue(idvalue ); - legalperson.getIdentification().add(legalID ); - mandator.setCorporateBody(legalperson ); - - legalperson.setFullName(extractor.getSingleAttributeValue(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME)); - legalID.setType(extractor.getSingleAttributeValue(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME)); - idvalue.setValue(extractor.getSingleAttributeValue(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME)); - - //build natural person short mandate - } else if ( (extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME) || - extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_BPK_NAME)) && - extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME) && - extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME) && - extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME)) { - Logger.debug("Build short mandate for natural person ..."); - PhysicalPersonType physPerson = new PhysicalPersonType(); - PersonNameType persName = new PersonNameType(); - mandator.setPhysicalPerson(physPerson ); - physPerson.setName(persName ); - FamilyName familyName = new FamilyName(); - persName.getFamilyName().add(familyName ); - IdentificationType persID = new IdentificationType(); - physPerson.getIdentification().add(persID ); - Value idValue = new Value(); - persID.setValue(idValue ); - - String[] pvp2GivenName = extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME).split(" "); - for(int i=0; i<pvp2GivenName.length; i++) - persName.getGivenName().add(pvp2GivenName[i]); - familyName.setValue(extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME)); - physPerson.setDateOfBirth(extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME)); + else if (idlFromPVPAttr != null){ + authData.setIdentityLink(idlFromPVPAttr); + Logger.debug("Set IdentityLink received from federated IDP for Organwalter"); + + } else + Logger.info("Can NOT set Organwalter IdentityLink. Msg: No IdentityLink found"); + - if (extractor.containsAttribute(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME)) { - persID.setType(Constants.URN_PREFIX_BASEID); - idValue.setValue(extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME)); + //set bPK and IdenityLink for all other + } else { + //build bPK + String pvpbPKValue = getbPKValueFromPVPAttribute(session); + String pvpbPKTypeAttr = getbPKTypeFromPVPAttribute(session); + Pair<String, String> pvpEncbPKAttr = getEncryptedbPKFromPVPAttribute(session, authData, oaParam); + + //check if a unique ID for this citizen exists + if (MiscUtil.isEmpty(authData.getIdentificationValue()) && + MiscUtil.isEmpty(pvpbPKValue) && MiscUtil.isEmpty(authData.getBPK()) && + pvpEncbPKAttr == null) { + Logger.info("Can not build authData, because moaSession include no bPK, encrypted bPK or baseID"); + throw new MOAIDException("builder.08", new Object[]{"No " + PVPConstants.BPK_FRIENDLY_NAME + + " or " + PVPConstants.EID_SOURCE_PIN_FRIENDLY_NAME + + " or " + PVPConstants.ENC_BPK_LIST_FRIENDLY_NAME}); + + } + + // baseID is in MOASesson --> calculate bPK directly + if (MiscUtil.isNotEmpty(authData.getIdentificationValue())) { + Logger.debug("Citizen baseID is in MOASession --> calculate bPK from this."); + Pair<String, String> result = buildOAspecificbPK(protocolRequest, oaParam, authData); + authData.setBPK(result.getFirst()); + authData.setBPKType(result.getSecond()); + + //check if bPK already added to AuthData matches OA + } else if (MiscUtil.isNotEmpty(authData.getBPK()) + && matchsReceivedbPKToOnlineApplication(oaParam, authData.getBPKType()) ) { + Logger.debug("Correct bPK is already included in AuthData."); + + //check if bPK received by PVP-Attribute matches OA + } else if (MiscUtil.isNotEmpty(pvpbPKValue) && + matchsReceivedbPKToOnlineApplication(oaParam, pvpbPKTypeAttr)) { + Logger.debug("Receive correct bPK from PVP-Attribute"); + authData.setBPK(pvpbPKValue); + authData.setBPKType(pvpbPKTypeAttr); + //check if decrypted bPK exists + } else if (pvpEncbPKAttr != null) { + Logger.debug("Receive bPK as encrypted bPK and decryption was possible."); + authData.setBPK(pvpEncbPKAttr.getFirst()); + authData.setBPKType(pvpEncbPKAttr.getSecond()); + + //ask SZR to get bPK } else { - String[] pvp2bPK = extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_BPK_NAME).split(":"); - if (pvp2bPK.length == 2) { - idValue.setValue(pvp2bPK[1]); + String notValidbPK = authData.getBPK(); + String notValidbPKType = authData.getBPKType(); + if (MiscUtil.isEmpty(notValidbPK) && + MiscUtil.isEmpty(notValidbPKType)) { + notValidbPK = pvpbPKValue; + notValidbPKType = pvpbPKTypeAttr; - Pattern pattern = Pattern.compile(MOAIDAuthConstants.REGEX_PATTERN_TARGET); - Matcher matcher = pattern.matcher(pvp2bPK[0]); - if (matcher.matches()) - persID.setType(Constants.URN_PREFIX_CDID + "+" + pvp2bPK[0]); - else - persID.setType(Constants.URN_PREFIX_WBPK + "+" + pvp2bPK[0]); + if (MiscUtil.isEmpty(notValidbPK) && + MiscUtil.isEmpty(notValidbPKType)) { + Logger.fatal("No bPK in MOASession. THIS error should not occur any more."); + throw new NullPointerException("No bPK in MOASession. THIS error should not occur any more."); + } + } + + Pair<String, String> baseIDFromSZR = getbaseIDFromSZR(authData, notValidbPK, notValidbPKType); + if (baseIDFromSZR != null) { + Logger.info("Receive citizen baseID from SRZ. Authentication can be completed"); + authData.setIdentificationValue(baseIDFromSZR.getFirst()); + authData.setIdentificationType(baseIDFromSZR.getSecond()); + Pair<String, String> result = buildOAspecificbPK(protocolRequest, oaParam, authData); + authData.setBPK(result.getFirst()); + authData.setBPKType(result.getSecond()); } else { - Logger.warn("Receive mandator bPK from federation with an unsupported format. " + extractor.getSingleAttributeValue(PVPConstants.MANDATE_NAT_PER_BPK_NAME)); - throw new AssertionAttributeExtractorExeption("Receive mandator bPK from federation with an unsupported format."); + Logger.warn("Can not build authData, because moaSession include no valid bPK, encrypted bPK or baseID"); + throw new MOAIDException("builder.08", new Object[]{"No valid " + PVPConstants.BPK_FRIENDLY_NAME + + " or " + PVPConstants.EID_SOURCE_PIN_FRIENDLY_NAME + + " or " + PVPConstants.ENC_BPK_LIST_FRIENDLY_NAME}); } } - - } else { - Logger.error("Short mandate could not generated. Assertion contains not all attributes which are necessary."); - throw new AssertionAttributeExtractorExeption("Assertion contains not all attributes which are necessary for mandate generation", null); - - } - - try { - JAXBContext jc = JAXBContext.newInstance("at.gv.e_government.reference.namespace.mandates._20040701_"); - Marshaller m = jc.createMarshaller(); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - m.marshal(mandateObject, stream); - misMandate.setMandate(Base64Utils.encode(stream.toByteArray()).getBytes()); - stream.close(); + + //build IdentityLink + if (identityLink != null) + authData.setIdentityLink(buildOAspecificIdentityLink(oaParam, identityLink, authData.getBPK(), authData.getBPKType())); - } catch (JAXBException e) { - Logger.error("Failed to parse short mandate", e); - throw new AssertionAttributeExtractorExeption(); + else if (idlFromPVPAttr != null) { + authData.setIdentityLink(buildOAspecificIdentityLink(oaParam, idlFromPVPAttr, authData.getBPK(), authData.getBPKType())); + Logger.debug("Set IdentityLink received from federated IDP"); - } catch (IOException e) { - Logger.error("Failed to parse short mandate", e); - throw new AssertionAttributeExtractorExeption(); - - } - authData.setUseMandate(true); + } else { + Logger.info("Can NOT set IdentityLink. Msg: No IdentityLink found"); + + } + } - } - - - if (extractor.containsAttribute(PVPConstants.MANDATE_PROF_REP_OID_NAME)) { - if (authData.getMISMandate() == null) - authData.setMISMandate(new MISMandate()); - authData.getMISMandate().setProfRep( - extractor.getSingleAttributeValue(PVPConstants.MANDATE_PROF_REP_OID_NAME)); - } - - //set PVP role attribute - if (extractor.containsAttribute(PVPConstants.ROLES_NAME)) { - String pvpRoles = extractor.getSingleAttributeValue(PVPConstants.ROLES_NAME); - if (MiscUtil.isNotEmpty(pvpRoles)) { - List<String> roles = Arrays.asList(pvpRoles.split(";")); + //################################################################### + //set PVP role attribute (implemented for ISA 1.18 action) + includedToGenericAuthData.remove(PVPConstants.ROLES_NAME); + String pvpAttrRoles = session.getGenericDataFromSession(PVPConstants.ROLES_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpAttrRoles)) { + List<String> roles = Arrays.asList(pvpAttrRoles.split(";")); for (String role : roles) { authData.addAuthenticationRole(AuthenticationRoleFactory.buildFormPVPole(role)); - } - } - } - - //set PVP OU attribute - if (extractor.containsAttribute(PVPConstants.OU_NAME)) { - authData.setPvpAttribute_OU(extractor.getSingleAttributeValue(PVPConstants.OU_NAME)); - Logger.debug("Found PVP 'OU' attribute in response -> " + authData.getPvpAttribute_OU()); - - } - - //set STORK attributes - if (extractor.containsAttribute(PVPConstants.EID_STORK_TOKEN_NAME)) { - try { - authData.setGenericData(AuthenticationSessionStorageConstants.STORK_RESPONSE, - extractor.getSingleAttributeValue(PVPConstants.EID_STORK_TOKEN_NAME)); - authData.setForeigner(true); - } catch (SessionDataStorageException e) { - Logger.warn("STORK Response can not stored into generic authData.", e); + } + } + + + //################################################################### + //set PVP OU attribute (implemented for ISA 1.18 action) + includedToGenericAuthData.remove(PVPConstants.OU_NAME); + String pvpAttrOUName = session.getGenericDataFromSession(PVPConstants.OU_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpAttrOUName)) { + authData.setPvpAttribute_OU(pvpAttrOUName); + Logger.debug("Found PVP 'OU' attribute in response -> " + authData.getPvpAttribute_OU()); - } + } - } - -// if (!extractor.getSTORKAttributes().isEmpty()) { -// authData.setStorkAttributes(extractor.getSTORKAttributes()); -// authData.setForeigner(true); -// -// } + //#################################################################### + //parse AuthBlock signature-verification response + //INFO: this parameters are only required for SAML1 auth. protocol + VerifyXMLSignatureResponse verifyXMLSigResp = session.getXMLVerifySignatureResponse(); + if (verifyXMLSigResp != null) { + authData.setQualifiedCertificate(verifyXMLSigResp + .isQualifiedCertificate()); + authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); + authData.setPublicAuthorityCode(verifyXMLSigResp + .getPublicAuthorityCode()); + + } else { + //set parameters in respect to QAA level + Logger.info("No authBlock signature-verfication response found. Maybe IDP federation is in use."); + if (PVPConstants.STORK_QAA_1_4.equals(authData.getQAALevel())) + authData.setQualifiedCertificate(true); + else + authData.setQualifiedCertificate(false); + authData.setPublicAuthority(false); - authData.setSsoSession(true); - authData.setInterfederatedSSOSession(true); - - if (extractor.getFullAssertion().getAuthnStatements() != null - && extractor.getFullAssertion().getAuthnStatements().size() > 0) { - for (AuthnStatement el : extractor.getFullAssertion().getAuthnStatements()) { - if (el.getSessionNotOnOrAfter() != null) { - authData.setSsoSessionValidTo(el.getSessionNotOnOrAfter().toDate()); - break; - } + } + + //#################################################################### + //copy all generic authentication information, which are not processed before to authData + Iterator<String> copyInterator = includedToGenericAuthData.iterator(); + while (copyInterator.hasNext()) { + String elementKey = copyInterator.next(); + try { + authData.setGenericData(elementKey, session.getGenericDataFromSession(elementKey)); + + } catch (SessionDataStorageException e) { + Logger.warn("Can not add generic authData with key:" + elementKey, e); + + } } - } else { - authData.setSsoSessionValidTo(extractor.getFullAssertion().getConditions().getNotOnOrAfter().toDate()); + } catch (BuildException e) { + throw e; - } + } catch (Throwable ex) { + throw new BuildException("builder.00", new Object[]{ + "AuthenticationData", ex.toString()}, ex); + } - //only for SAML1 - if (PVPConstants.STORK_QAA_1_4.equals(authData.getQAALevel())) - authData.setQualifiedCertificate(true); - else - authData.setQualifiedCertificate(false); - authData.setPublicAuthority(false); } - + /** - * @param oaParam - * @param authData - * @return + * Check a bPK-Type against a Service-Provider configuration <br> + * If bPK-Type is <code>null</code> the result is <code>false</code>. + * + * @param oaParam Service-Provider configuration, never null + * @param bPKType bPK-Type to check + * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise false */ - private boolean matchsReceivedbPKToOnlineApplication( - IOAAuthParameters oaParam, AuthenticationData authData) { - + private boolean matchsReceivedbPKToOnlineApplication(IOAAuthParameters oaParam, String bPKType) { String oaTarget = null; if (oaParam.getBusinessService()) { - if (oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_WBPK) || - oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_STORK)) - oaTarget = oaParam.getIdentityLinkDomainIdentifier(); - - else { - Logger.warn("BusinessIdentifier can not be clearly assigned, because it starts without a prefix."); - return false; - - } - + oaTarget = oaParam.getIdentityLinkDomainIdentifier(); + } else { oaTarget = Constants.URN_PREFIX_CDID + "+" + oaParam.getTarget(); } - - - if (oaTarget.equals(authData.getBPKType())) + + if (oaTarget.equals(bPKType)) return true; else return false; } - private void buildAuthDataFormMOASession(AuthenticationData authData, AuthenticationSession session, - IOAAuthParameters oaParam, IRequest protocolRequest) throws BuildException, ConfigurationException { - - IdentityLink identityLink = session.getIdentityLink(); - - VerifyXMLSignatureResponse verifyXMLSigResp = session.getXMLVerifySignatureResponse(); - - authData.setIssuer(protocolRequest.getAuthURL()); - + private void parseBasicUserInfosFromIDL(AuthenticationData authData, IdentityLink identityLink, Collection<String> includedGenericSessionData) { //baseID or wbpk in case of BusinessService without SSO or BusinessService SSO authData.setIdentificationValue(identityLink.getIdentificationValue()); authData.setIdentificationType(identityLink.getIdentificationType()); @@ -883,144 +841,238 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { authData.setFamilyName(identityLink.getFamilyName()); authData.setDateOfBirth(identityLink.getDateOfBirth()); - if (verifyXMLSigResp != null) { - authData.setQualifiedCertificate(verifyXMLSigResp - .isQualifiedCertificate()); - authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); - authData.setPublicAuthorityCode(verifyXMLSigResp - .getPublicAuthorityCode()); + //remove corresponding keys from genericSessionData if exists + includedGenericSessionData.remove(PVPConstants.PRINCIPAL_NAME_NAME); + includedGenericSessionData.remove(PVPConstants.GIVEN_NAME_NAME); + includedGenericSessionData.remove(PVPConstants.BIRTHDATE_NAME); + includedGenericSessionData.remove(PVPConstants.EID_SOURCE_PIN_NAME); + includedGenericSessionData.remove(PVPConstants.EID_SOURCE_PIN_TYPE_NAME); + + } + + /** + * @param authData + * @param notValidbPK + * @param notValidbPKType + * @return + */ + private Pair<String, String> getbaseIDFromSZR(AuthenticationData authData, String notValidbPK, + String notValidbPKType) { + try { + EgovUtilPropertiesConfiguration eGovClientsConfig = authConfig.geteGovUtilsConfig(); + if (eGovClientsConfig != null) { + Logger.info("bPK in MOASession (bPK-Type:" + notValidbPKType + + " does no match to Service-Provider configuration. --> Request SZR to get correct bPK."); + + SZRClient szrclient = new SZRClient(eGovClientsConfig); + + Logger.debug("Create SZR request to get baseID ... "); + PersonInfoType personInfo = new PersonInfoType(); + at.gv.util.xsd.szr.persondata.PhysicalPersonType person = new at.gv.util.xsd.szr.persondata.PhysicalPersonType(); + personInfo.setPerson(person); + at.gv.util.xsd.szr.persondata.PersonNameType name = new at.gv.util.xsd.szr.persondata.PersonNameType(); + person.setName(name); + at.gv.util.xsd.szr.persondata.IdentificationType idValue = new at.gv.util.xsd.szr.persondata.IdentificationType(); + person.setIdentification(idValue); + + //set bPK or wbPK + idValue.setValue(authData.getBPK()); + idValue.setType(authData.getBPKType()); + + //set person information + name.setGivenName(authData.getGivenName()); + name.setFamilyName(authData.getFamilyName()); + if (authData.getDateOfBirth() != null) + person.setDateOfBirth(authData.getFormatedDateOfBirth()); + + //request szr and store baseID + return Pair.newInstance(szrclient.getStammzahl(personInfo), + Constants.URN_PREFIX_BASEID); + + } else { + Logger.debug("No SZR clieht configuration found."); + return null; + + } + + } catch (SZRException e) { + Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); - } else { - Logger.warn("No signature verfication response found!"); + } catch (at.gv.util.ex.EgovUtilException e) { + Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); } - authData.setBkuURL(session.getBkuURL()); - - //copy all generic authentication information to authData - if (session.getGenericSessionDataStorage() != null && - !session.getGenericSessionDataStorage().isEmpty()) { - Iterator<Entry<String, Object>> copyInterator = session.getGenericSessionDataStorage().entrySet().iterator(); - while (copyInterator.hasNext()) { - Entry<String, Object> element = copyInterator.next(); - try { - authData.setGenericData(element.getKey(), element.getValue()); - - } catch (SessionDataStorageException e) { - Logger.warn("Can not add generic authData with key:" + element.getKey(), e); - - } - } - } + return null; + } + + /** + * Add encrypted bPKs from PVP Attribute 'ENC_BPK_LIST_NAME', which could be exist in + * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.ENC_BPK_LIST_NAME, String.class)</code></pre> + * to <code>authData</code> + * + * @param session MOASession, but never null + * @param authData AuthenticationData DAO + * @param spConfig Service-Provider configuration + * + * @return Pair<bPK, bPKType> which was received by PVP-Attribute and could be decrypted for this Service Provider, + * or <code>null</code> if no attribute exists or can not decrypted + */ + private Pair<String, String> getEncryptedbPKFromPVPAttribute(AuthenticationSession session, + AuthenticationData authData, IOAAuthParameters spConfig) { + //set List of encrypted bPKs to authData DAO + String pvpEncbPKListAttr = session.getGenericDataFromSession(PVPConstants.ENC_BPK_LIST_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpEncbPKListAttr)) { + List<String> encbPKList = Arrays.asList(pvpEncbPKListAttr.split(";")); + authData.setEncbPKList(encbPKList); + + //check if one of this encrypted bPK could be decrypt for this Service-Provider + for (String fullEncbPK : encbPKList) { + int index = fullEncbPK.indexOf("|"); + if (index >= 0) { + String encbPK = fullEncbPK.substring(index+1); + String second = fullEncbPK.substring(0, index); + int secIndex = second.indexOf("+"); + if (secIndex >= 0) { + if (spConfig.getTarget().equals(second.substring(secIndex+1))) { + Logger.debug("Found encrypted bPK for online-application " + + spConfig.getPublicURLPrefix() + + " Start decryption process ..."); + PrivateKey privKey = spConfig.getBPKDecBpkDecryptionKey(); + if (privKey != null) { + try { + String bPK = BPKBuilder.decryptBPK(encbPK, spConfig.getTarget(), privKey); + if (MiscUtil.isNotEmpty(bPK)) { + Logger.info("bPK decryption process finished successfully."); + return Pair.newInstance(bPK, Constants.URN_PREFIX_CDID + "+" + spConfig.getTarget()); + + } else { + Logger.error("bPK decryption FAILED."); + + } + } catch (BuildException e) { + Logger.error("bPK decryption FAILED.", e); + + } + + } else { + Logger.info("bPK decryption FAILED, because no valid decryption key is found."); - authData.setSignerCertificate(session.getEncodedSignerCertificate()); - authData.setAuthBlock(session.getAuthBlock()); + } + + } else { + Logger.info("Found encrypted bPK but " + + "encrypted bPK target does not match to online-application target"); + + } + } + } + } + } - authData.setForeigner(session.isForeigner()); - authData.setQAALevel(session.getQAALevel()); + return null; + } - authData.setIsBusinessService(oaParam.getBusinessService()); - - if (session.isForeigner()) { - try { - //TODO: replace with TSL lookup when TSL is ready! - X509Certificate certificate = new X509Certificate(authData.getSignerCertificate()); - if (certificate != null) { - LdapName ln = new LdapName(certificate.getIssuerDN() - .getName()); - for (Rdn rdn : ln.getRdns()) { - if (rdn.getType().equalsIgnoreCase("C")) { - Logger.info("C is: " + rdn.getValue()); - authData.setCcc(rdn.getValue().toString()); - break; - } - } - } - - } catch (Exception e) { - Logger.error("Failed to extract country code from certificate with message: " + e.getMessage()); + /** + * Get bPK from PVP Attribute 'BPK_NAME', which could be exist in + * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class)</code></pre> + * + * @param session MOASession, but never null + * @return bPK, which was received by PVP-Attribute, or <code>null</code> if no attribute exists + */ + private String getbPKValueFromPVPAttribute(AuthenticationSession session) { + String pvpbPKValueAttr = session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpbPKValueAttr)) { + + //fix a wrong bPK-value prefix, which was used in some PVP Standardportal implementations + if (pvpbPKValueAttr.startsWith("bPK:")) { + Logger.warn("Attribute " + PVPConstants.BPK_NAME + + " contains a not standardize prefix! Staring attribute value correction process ..."); + pvpbPKValueAttr = pvpbPKValueAttr.substring("bPK:".length()); } - if (MiscUtil.isEmpty(authData.getCcc())) { - String storkCCC = authData.getGenericData( - AuthenticationSessionStorageConstants.STORK_CCC, String.class); + String[] spitted = pvpbPKValueAttr.split(":"); + if (spitted.length != 2) { + Logger.warn("Attribute " + PVPConstants.BPK_NAME + " has a wrong encoding and can NOT be USED!" + + " Value:" + pvpbPKValueAttr); + return null; - if (MiscUtil.isNotEmpty(storkCCC)) { - authData.setCcc(storkCCC); - Logger.info("Can not extract country from certificate -> Use country:" + storkCCC + " from STORK request."); - - } - } - - } else { - authData.setCcc("AT"); + Logger.debug("Find PVP-Attr: " + PVPConstants.BPK_FRIENDLY_NAME); + return spitted[1]; } - try { - authData.setSsoSession(protocolRequest.needSingleSignOnFunctionality()); + return null; + } + + /** + * Get bPK-Type from PVP Attribute 'EID_SECTOR_FOR_IDENTIFIER_NAME', which could be exist in + * MOASession as 'GenericData' <br> <pre><code>session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class)</code></pre> + * + * @param session MOASession, but never null + * @return bPKType, which was received by PVP-Attribute, or <code>null</code> if no attribute exists + */ + private String getbPKTypeFromPVPAttribute(AuthenticationSession session) { + String pvpbPKTypeAttr = session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class); + if (MiscUtil.isNotEmpty(pvpbPKTypeAttr)) { - //set max. SSO session time - if (authData.isSsoSession()) { - long maxSSOSessionTime = authConfig.getSSOCreatedTimeOut() * 1000; - Date ssoSessionValidTo = new Date(session.getSessionCreated().getTime() + maxSSOSessionTime); - authData.setSsoSessionValidTo(ssoSessionValidTo); - - } else { - //set valid to 5 min - Date ssoSessionValidTo = new Date(new Date().getTime() + 5 * 60 * 1000); - authData.setSsoSessionValidTo(ssoSessionValidTo); + //fix a wrong bPK-Type encoding, which was used in some PVP Standardportal implementations + if (pvpbPKTypeAttr.startsWith(Constants.URN_PREFIX_CDID) && + !pvpbPKTypeAttr.substring(Constants.URN_PREFIX_CDID.length(), + Constants.URN_PREFIX_CDID.length() + 1).equals("+")) { + Logger.warn("Receive uncorrect encoded bBKType attribute " + pvpbPKTypeAttr + " Starting attribute value correction ... "); + pvpbPKTypeAttr = Constants.URN_PREFIX_CDID + "+" + pvpbPKTypeAttr.substring(Constants.URN_PREFIX_CDID.length() + 1); } - - - /* TODO: Support SSO Mandate MODE! - * Insert functionality to translate mandates in case of SSO - */ + Logger.debug("Find PVP-Attr: " + PVPConstants.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME); + return pvpbPKTypeAttr; + } + + return null; - - MISMandate mandate = session.getMISMandate(); - authData.setMISMandate(mandate); - authData.setUseMandate(session.getUseMandate()); - authData.setMandateReferenceValue(session.getMandateReferenceValue()); - - if (session.getUseMandate() && session.isOW() - && mandate != null && MiscUtil.isNotEmpty(mandate.getOWbPK())) { - authData.setBPK(mandate.getOWbPK()); - authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + "OW"); - - //TODO: check in case of mandates for business services - authData.setIdentityLink(identityLink); - Logger.trace("Authenticated User is OW: " + mandate.getOWbPK()); - } else { - buildOAspecificbPK(protocolRequest, oaParam, authData, - identityLink.getIdentificationValue(), - identityLink.getIdentificationType()); - - buildOAspecificIdentityLink(oaParam, authData, identityLink); - - } - - - } catch (Throwable ex) { - throw new BuildException("builder.00", new Object[]{ - "AuthenticationData", ex.toString()}, ex); - } + /* + * INFO: This code could be used to extract the bPKType from 'PVPConstants.BPK_NAME', + * because the prefix of BPK_NAME attribute contains the postfix of the bPKType + * + * Now, all PVP Standardportals should be able to send 'EID_SECTOR_FOR_IDENTIFIER' + * PVP attributes + */ +// String pvpbPKValueAttr = session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class); +// String[] spitted = pvpbPKValueAttr.split(":"); +// if (MiscUtil.isEmpty(authData.getBPKType())) { +// Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " + +// "Starting target extraction from bPK/wbPK prefix ..."); +// //exract bPK/wbPK type from bpk attribute value prefix if type is +// //not transmitted as single attribute +// Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?"); +// Matcher matcher = pattern.matcher(spitted[0]); +// if (matcher.matches()) { +// //find public service bPK +// authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]); +// Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType()); +// +// } else { +// //find business service wbPK +// authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]); +// Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType()); +// +// } +// } } - - private void buildOAspecificIdentityLink(IOAAuthParameters oaParam, AuthenticationData authData, IdentityLink idl) throws MOAIDException { + + private IdentityLink buildOAspecificIdentityLink(IOAAuthParameters oaParam, IdentityLink idl, String bPK, String bPKType) throws MOAIDException { if (oaParam.getBusinessService()) { Element idlassertion = idl.getSamlAssertion(); //set bpk/wpbk; Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); - prIdentification.getFirstChild().setNodeValue(authData.getBPK()); + prIdentification.getFirstChild().setNodeValue(bPK); //set bkp/wpbk type Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH); - prIdentificationType.getFirstChild().setNodeValue(authData.getBPKType()); + prIdentificationType.getFirstChild().setNodeValue(bPKType); IdentityLinkAssertionParser idlparser = new IdentityLinkAssertionParser(idlassertion); IdentityLink businessServiceIdl = idlparser.parseIdentityLink(); @@ -1035,62 +1087,70 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { resignedilAssertion = businessServiceIdl.getSamlAssertion(); } IdentityLinkAssertionParser resignedIDLParser = new IdentityLinkAssertionParser(resignedilAssertion); - IdentityLink resignedIDL = resignedIDLParser.parseIdentityLink(); + return resignedIDLParser.parseIdentityLink(); - authData.setIdentityLink(resignedIDL); - } else - authData.setIdentityLink(idl); + return idl; } - - private void buildOAspecificbPK(IRequest protocolRequest, IOAAuthParameters oaParam, AuthenticationData authData, String baseID, String baseIDType) throws BuildException { - - if (oaParam.getBusinessService()) { - //since we have foreigner, wbPK is not calculated in BKU - if (baseIDType.equals(Constants.URN_PREFIX_BASEID)) { - String registerAndOrdNr = oaParam.getIdentityLinkDomainIdentifier(); - authData.setBPK(new BPKBuilder().buildbPKorwbPK(baseID, registerAndOrdNr)); - authData.setBPKType(registerAndOrdNr); - - } else { - authData.setBPK(baseID); - authData.setBPKType(baseIDType); - } - - Logger.trace("Authenticate user with wbPK " + authData.getBPK()); - - } else { - if (baseIDType.equals(Constants.URN_PREFIX_BASEID)) { - // only compute bPK if online application is a public service and we have the Stammzahl - String target = null; - Object saml1Requst = null; - try { - saml1Requst = Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl").newInstance(); - - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | java.lang.SecurityException ex) { - - - } - - if (saml1Requst != null && protocolRequest.getClass().isInstance(saml1Requst)) - target = protocolRequest.getGenericData( - MOAIDAuthConstants.AUTHPROCESS_DATA_TARGET, String.class); - else - target = oaParam.getTarget(); - - String bpkBase64 = new BPKBuilder().buildBPK(baseID, target); - authData.setBPK(bpkBase64); - authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + target); - } + private Pair<String, String> buildOAspecificbPK(IRequest pendingReq, IOAAuthParameters oaParam, AuthenticationData authData) throws BuildException { + + String bPK; + String bPKType; - Logger.trace("Authenticate user with bPK " + authData.getBPK()); - } + String baseID = authData.getIdentificationValue(); + String baseIDType = authData.getIdentificationType(); + + String eIDASOutboundCountry = pendingReq.getGenericData(RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, String.class); + if (Constants.URN_PREFIX_BASEID.equals(baseIDType)) { + if (MiscUtil.isNotEmpty(eIDASOutboundCountry) && !COUNTRYCODE_AUSTRIA.equals(eIDASOutboundCountry)) { + Pair<String, String> eIDASID = new BPKBuilder().buildeIDASIdentifer(baseIDType, baseID, + COUNTRYCODE_AUSTRIA, eIDASOutboundCountry); + Logger.trace("Authenticate user with bPK:" + eIDASID.getFirst() + " Type:" + eIDASID.getSecond()); + return eIDASID; + + } else if (oaParam.getBusinessService()) { + //is Austrian private-service application + String registerAndOrdNr = oaParam.getIdentityLinkDomainIdentifier(); + bPK = new BPKBuilder().buildbPKorwbPK(baseID, registerAndOrdNr); + bPKType = registerAndOrdNr; + + } else { + // only compute bPK if online application is a public service and we have the Stammzahl + String target = null; + Class<?> saml1RequstTemplate = null; + try { + saml1RequstTemplate = Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl"); + if (saml1RequstTemplate != null && + saml1RequstTemplate.isInstance(pendingReq)) { + target = (String) pendingReq.getClass().getMethod("getTarget").invoke(pendingReq); + + } + + } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | java.lang.SecurityException | InvocationTargetException | NoSuchMethodException ex) { } + + if (MiscUtil.isEmpty(target)) + target = oaParam.getTarget(); + + bPK = new BPKBuilder().buildBPK(baseID, target); + bPKType = Constants.URN_PREFIX_CDID + "+" + target; + + } + + } else { + Logger.warn("!!!baseID-element does not include a baseID. This should not be happen any more!!!"); + bPK = baseID; + bPKType = baseIDType; + + } + Logger.trace("Authenticate user with bPK:" + bPK + " Type:" + bPKType); + return Pair.newInstance(bPK, bPKType); + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java index 1cf6929e6..9e4e36fec 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java @@ -46,13 +46,6 @@ package at.gv.egovernment.moa.id.auth.builder; -import at.gv.egovernment.moa.id.auth.data.IdentityLink; -import at.gv.egovernment.moa.id.auth.exception.BuildException; -import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.util.Base64Utils; -import at.gv.egovernment.moa.util.Constants; -import at.gv.egovernment.moa.util.MiscUtil; - import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -66,6 +59,13 @@ import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.data.Pair; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; + /** * Builder for the bPK, as defined in * <code>"Ableitung f¨r die bereichsspezifische Personenkennzeichnung"</code> @@ -203,73 +203,42 @@ public class BPKBuilder { /** * Builds the storkeid from the given parameters. * - * @param identityLink identity link - * @param destinationCountry destination country code (2 chars) - * @return storkid in a BASE64 encoding - * @throws BuildException if an error occurs on building the wbPK - */ - public String buildStorkeIdentifier(IdentityLink identityLink, String destinationCountry) - throws BuildException { - return buildStorkbPK(identityLink.getIdentificationValue(), - identityLink.getIdentificationType(), "AT", destinationCountry); - } - - /** - * Builds the storkeid from the given parameters. - * - * @param identityLink identity link - * @param destinationCountry destination country code (2 chars) - * @return storkid in a BASE64 encoding - * @throws BuildException if an error occurs on building the wbPK - */ - public String buildStorkeIdentifier(String identificationType, String identificationValue, String destinationCountry) - throws BuildException { - return buildStorkbPK(identificationValue, identificationType, "AT", destinationCountry); - } - - /** - * Builds the storkeid from the given parameters. - * - * @param identityLink identity link - * @param sourceCountry source country code (2 chars) - * @param destinationCountry destination country code (2 chars) - * @return storkid in a BASE64 encoding + * @param baseID baseID of the citizen + * @param baseIDType Type of the baseID + * @param sourceCountry CountryCode of that country, which build the eIDAs ID + * @param destinationCountry CountryCode of that country, which receives the eIDAs ID + * + * @return Pair<eIDAs, bPKType> in a BASE64 encoding * @throws BuildException if an error occurs on building the wbPK */ - public String buildStorkbPK(String baseID, String baseIDType, String sourceCountry, String destinationCountry) - throws BuildException { - String identificationValue = null; - + public Pair<String, String> buildeIDASIdentifer(String baseID, String baseIDType, String sourceCountry, String destinationCountry) + throws BuildException { + String bPK = null; + String bPKType = null; + // check if we have been called by public sector application - if (baseIDType.startsWith(Constants.URN_PREFIX_BASEID)) { - identificationValue = calculateStorkeIdentifierBase(baseID, sourceCountry, destinationCountry); + if (baseIDType.startsWith(Constants.URN_PREFIX_BASEID)) { + bPKType = Constants.URN_PREFIX_EIDAS + "+" + sourceCountry + "+" + destinationCountry; + Logger.debug("Building eIDAS identification from: [identValue]+" + bPKType); + bPK = calculatebPKwbPK(baseID + "+" + bPKType); } else { // if not, sector identification value is already calculated by BKU - Logger.debug("STORK eIdentifier already provided by BKU"); - identificationValue = baseID; + Logger.debug("eIDAS eIdentifier already provided by BKU"); + bPK = baseID; } - if ((identificationValue == null || - identificationValue.length() == 0 || - destinationCountry == null || - destinationCountry.length() == 0 || - sourceCountry == null || - sourceCountry.length() == 0)) { + if ((MiscUtil.isEmpty(bPK) || + MiscUtil.isEmpty(sourceCountry) || + MiscUtil.isEmpty(destinationCountry))) { throw new BuildException("builder.00", - new Object[]{"storkid", "Unvollständige Parameterangaben: identificationValue=" + - identificationValue + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry}); + new Object[]{"eIDAS-ID", "Unvollständige Parameterangaben: identificationValue=" + + bPK + ", Zielland=" + destinationCountry + ", Ursprungsland=" + sourceCountry}); } - Logger.info("Building STORK identification from: " + sourceCountry+"/"+destinationCountry+"/" + "[identValue]"); - String eIdentifier = sourceCountry+"/"+destinationCountry+"/"+identificationValue; - - return eIdentifier; - } - - private String calculateStorkeIdentifierBase(String baseID, String sourceCountry, String destinationCountry) throws BuildException { - String basisbegriff = baseID + "+" + Constants.URN_PREFIX_STORK + "+" + sourceCountry + "+" + destinationCountry; - Logger.debug("Building STORK identification from: [identValue]+" + Constants.URN_PREFIX_STORK + "+" + sourceCountry + "+" + destinationCountry); - return calculatebPKwbPK(basisbegriff); + Logger.debug("Building eIDAS identification from: " + sourceCountry+"/"+destinationCountry+"/" + "[identValue]"); + String eIdentifier = sourceCountry + "/" + destinationCountry + "/" + bPK; + + return Pair.newInstance(eIdentifier, baseIDType); } private String calculatebPKwbPK(String basisbegriff) throws BuildException { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java index 79b09503f..8c0de1121 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java @@ -38,6 +38,7 @@ import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; /** * @author tlenz @@ -45,65 +46,35 @@ import at.gv.egovernment.moa.util.Constants; */ public class DynamicOAAuthParameterBuilder { - public static IOAAuthParameters buildFromAttributeQuery(List<Attribute> reqAttributes, InterfederationSessionStore interfIDP) throws DynamicOABuildException { + public static IOAAuthParameters buildFromAttributeQuery(List<Attribute> reqAttributes) throws DynamicOABuildException { Logger.debug("Build dynamic OAConfiguration from AttributeQuery and interfederation information"); - try { - DynamicOAAuthParameters dynamicOA = new DynamicOAAuthParameters(); - - for (Attribute attr : reqAttributes) { - //get Target or BusinessService from request - if (attr.getName().equals(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) { - String attrValue = attr.getAttributeValues().get(0).getDOM().getTextContent(); - if (attrValue.startsWith(Constants.URN_PREFIX_CDID)) { - dynamicOA.setBusinessService(false); - dynamicOA.setTarget(attrValue.substring((Constants.URN_PREFIX_CDID + "+").length())); - - } else if( attrValue.startsWith(Constants.URN_PREFIX_WBPK) || - attrValue.startsWith(Constants.URN_PREFIX_STORK) ) { - dynamicOA.setBusinessService(true); - dynamicOA.setTarget(attrValue); - - } else { - Logger.error("Sector identification " + attrValue + " is not a valid Target or BusinessServiceArea"); - throw new DynamicOABuildException("Sector identification " + attrValue + " is not a valid Target or BusinessServiceArea", null); - - } - - } + DynamicOAAuthParameters dynamicOA = new DynamicOAAuthParameters(); - } - - if (interfIDP != null) { - //load interfederated IDP informations - OAAuthParameter idp = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(interfIDP.getIdpurlprefix()); - if (idp == null) { - Logger.warn("Interfederated IDP configuration is not loadable."); - throw new DynamicOABuildException("Interfederated IDP configuration is not loadable.", null); + for (Attribute attr : reqAttributes) { + //get Target or BusinessService from request + if (attr.getName().equals(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) { + String attrValue = attr.getAttributeValues().get(0).getDOM().getTextContent(); + if (attrValue.startsWith(Constants.URN_PREFIX_CDID)) { + dynamicOA.setBusinessService(false); + dynamicOA.setTarget(attrValue.substring((Constants.URN_PREFIX_CDID + "+").length())); + + } else if( attrValue.startsWith(Constants.URN_PREFIX_WBPK) || + attrValue.startsWith(Constants.URN_PREFIX_STORK) ) { + dynamicOA.setBusinessService(true); + dynamicOA.setTarget(attrValue); + + } else { + Logger.error("Sector identification " + attrValue + " is not a valid Target or BusinessServiceArea"); + throw new DynamicOABuildException("Sector identification " + attrValue + " is not a valid Target or BusinessServiceArea", null); } - - dynamicOA.setApplicationID(idp.getPublicURLPrefix()); - dynamicOA.setInderfederatedIDP(idp.isInderfederationIDP()); - dynamicOA.setIDPQueryURL(idp.getIDPAttributQueryServiceURL()); - //check if IDP service area policy. BusinessService IDPs can only request wbPKs - if (!dynamicOA.getBusinessService() && !idp.isIDPPublicService()) { - Logger.error("Interfederated IDP " + idp.getPublicURLPrefix() - + " has a BusinessService-IDP but requests PublicService attributes."); - throw new DynamicOABuildException("Interfederated IDP " + idp.getPublicURLPrefix() - + " has a BusinessService-IDP but requests PublicService attributes.", null); - - } } - return dynamicOA; - - } catch (ConfigurationException e) { - Logger.warn("Internel server errror. Basic configuration load failed.", e); - throw new DynamicOABuildException("Basic configuration load failed.", null); - } + } + return dynamicOA; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java index 196415ddc..7873fb96d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java @@ -86,7 +86,7 @@ public class AuthenticationSession implements Serializable { /** * Use mandate */ - private boolean useMandate; + private boolean useMandates; private boolean isOW = false; @@ -371,19 +371,22 @@ public class AuthenticationSession implements Serializable { */ public void setUseMandate(String useMandate) { if (useMandate.compareToIgnoreCase("true") == 0) - this.useMandate = true; + this.useMandates = true; else - this.useMandate = false; + this.useMandates = false; + + } + + public void setUseMandates(boolean useMandates) { + this.useMandates = useMandates; } /** - * Returns if mandate is used or not - * * @return */ - public boolean getUseMandate() { - return this.useMandate; + public boolean isMandateUsed() { + return this.useMandates; } /** @@ -502,6 +505,7 @@ public class AuthenticationSession implements Serializable { return genericSessionDataStorate; } + /** * Returns a generic session-data object with is stored with a specific identifier * @@ -579,7 +583,5 @@ public class AuthenticationSession implements Serializable { Logger.trace("Add generic session-data with key:" + key + " to session."); genericSessionDataStorate.put(key, object); - } - - + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java index 648dcf6f1..4a764e362 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSessionStorageConstants.java @@ -38,5 +38,7 @@ public class AuthenticationSessionStorageConstants { public static final String eIDAS_ATTRIBUTELIST = PREFIX_eIDAS + "attributeList"; public static final String eIDAS_RESPONSE = PREFIX_eIDAS + "response"; + + public static final String FEDERATION_RESPONSE_VALIDE_TO = "federationRespValidTo"; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java index b7e95785b..a4abbbcfa 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/StartAuthentificationParameterParser.java @@ -78,20 +78,20 @@ public class StartAuthentificationParameterParser extends MOAIDAuthConstants{ //check UseMandate flag - String useMandateString = null; - boolean useMandateBoolean = false; + String useMISMandateString = null; + boolean useMISMandateBoolean = false; if ((useMandate != null) && (useMandate.compareTo("") != 0)) { - useMandateString = useMandate; + useMISMandateString = useMandate; } else { - useMandateString = "false"; + useMISMandateString = "false"; } - if (useMandateString.compareToIgnoreCase("true") == 0) - useMandateBoolean = true; + if (useMISMandateString.compareToIgnoreCase("true") == 0) + useMISMandateBoolean = true; else - useMandateBoolean = false; + useMISMandateBoolean = false; - moasession.setUseMandate(useMandateString); + moasession.setUseMandate(useMISMandateString); //load OnlineApplication configuration @@ -155,7 +155,7 @@ public class StartAuthentificationParameterParser extends MOAIDAuthConstants{ } else { Logger.debug("Service-Provider is of type 'PrivateService' with DomainIdentifier:" + oaParam.getIdentityLinkDomainIdentifier()); - if (useMandateBoolean) { + if (useMISMandateBoolean) { Logger.error("Online-Mandate Mode for business application not supported."); throw new AuthenticationException("auth.17", null); } @@ -213,6 +213,12 @@ public class StartAuthentificationParameterParser extends MOAIDAuthConstants{ protocolReq.setNeedSingleSignOnFunctionality(false); } + if (protocolReq.needSingleSignOnFunctionality() && useMISMandateBoolean) { + Logger.info("Usage of MIS-MandateService does not allow Single Sign-On. --> SSO is disabled for this request."); + protocolReq.setNeedSingleSignOnFunctionality(false); + + } + } public void parse(ExecutionContext ec, HttpServletRequest req, diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java index 36390ba62..d5fc90023 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java @@ -74,7 +74,7 @@ public abstract class AbstractController extends MOAIDAuthConstants { private static final String HTMLTEMPLATESDIR = "htmlTemplates/"; private static final String HTMLTEMPLATEFULL = "error_message.html"; - private static String CONTEXTPATH = "#CONTEXTPATH#"; + private static String CONTEXTPATH = "contextPath"; @Autowired protected StatisticLogger statisticLogger; @Autowired protected IRequestStorage requestStorage; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GUILayoutBuilderServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GUILayoutBuilderServlet.java index 1d9a57b48..3f9093a21 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GUILayoutBuilderServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GUILayoutBuilderServlet.java @@ -103,19 +103,21 @@ public class GUILayoutBuilderServlet extends AbstractController { } private IRequest extractPendingRequest(HttpServletRequest req) { - try { - String authURL = HTTPUtils.extractAuthURLFromRequest(req); + try { String pendingReqID = StringEscapeUtils.escapeHtml( req.getParameter(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID)); - if (MiscUtil.isNotEmpty(pendingReqID) && authConfig.getPublicURLPrefix().contains(authURL)) { + if (MiscUtil.isNotEmpty(pendingReqID)) { IRequest pendingReq = requestStorage.getPendingRequest(pendingReqID); - if (pendingReq != null) + if (pendingReq != null) { + Logger.trace("GUI-Layout builder: Pending-request:" + + pendingReqID + " found -> Build specific template"); return pendingReq; - + + } } - Logger.info("Prohibit GUI-Layout builder-request. No pending-request or wrong auth-URL."); + Logger.trace("GUI-Layout builder: No pending-request found -> Use default templates"); } catch (Exception e) { Logger.warn("GUI-Layout builder-servlet has an error during request-preprocessing.", e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java index 427bb9464..9397f1132 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java @@ -111,10 +111,8 @@ public class IDPSingleLogOutServlet extends AbstractController { else context.put("errorMsg", MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); - - context.put(SSOManager.CONTEXTPATH, authURL); - ssoManager.printSingleLogOutInfo(context, resp); + ssoManager.printSingleLogOutInfo(context, resp, authURL); } catch (MOAIDException e) { handleErrorNoRedirect(e, req, resp, false); @@ -209,7 +207,7 @@ public class IDPSingleLogOutServlet extends AbstractController { MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); try { - ssoManager.printSingleLogOutInfo(context, resp); + ssoManager.printSingleLogOutInfo(context, resp, authURL); } catch (MOAIDException e) { e.printStackTrace(); @@ -223,7 +221,7 @@ public class IDPSingleLogOutServlet extends AbstractController { context.put("successMsg", MOAIDMessageProvider.getInstance().getMessage("slo.02", null)); try { - ssoManager.printSingleLogOutInfo(context, resp); + ssoManager.printSingleLogOutInfo(context, resp, authURL); } catch (MOAIDException e) { e.printStackTrace(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java index 53be0881b..aa9a0824d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java @@ -147,8 +147,8 @@ public class AuthenticationData implements IAuthData, Serializable { private boolean ssoSession = false; private Date ssoSessionValidTo = null; - private boolean interfederatedSSOSession = false; - private String interfederatedIDP = null; +// private boolean interfederatedSSOSession = false; +// private String interfederatedIDP = null; private String sessionIndex = null; private String nameID = null; @@ -255,16 +255,18 @@ public class AuthenticationData implements IAuthData, Serializable { } /** - * Returns the identificationValue. - * @return String + * Holds the baseID of a citizen + * + * @return baseID */ public String getIdentificationValue() { return identificationValue; } /** - * Returns the identificationType - * @return String + * Holds the type of the baseID + * + * @return baseID-Type */ public String getIdentificationType() { return identificationType; @@ -439,6 +441,10 @@ public class AuthenticationData implements IAuthData, Serializable { } public Element getMandate() { + if (mandate == null) + return null; + + //parse Element from mandate XML try { byte[] byteMandate = mandate.getMandate(); String stringMandate = new String(byteMandate); @@ -579,7 +585,9 @@ public class AuthenticationData implements IAuthData, Serializable { } /** - * @return the ccc + * CountryCode of the citizen which is identified and authenticated + * + * @return the CountryCode <pre>like. AT, SI, ...</pre> */ public String getCcc() { return ccc; @@ -635,33 +643,33 @@ public class AuthenticationData implements IAuthData, Serializable { this.nameIDFormat = nameIDFormat; } - /** - * @return the interfederatedSSOSession - */ - public boolean isInterfederatedSSOSession() { - return interfederatedSSOSession; - } - - /** - * @param interfederatedSSOSession the interfederatedSSOSession to set - */ - public void setInterfederatedSSOSession(boolean interfederatedSSOSession) { - this.interfederatedSSOSession = interfederatedSSOSession; - } - - /** - * @return the interfederatedIDP - */ - public String getInterfederatedIDP() { - return interfederatedIDP; - } - - /** - * @param interfederatedIDP the interfederatedIDP to set - */ - public void setInterfederatedIDP(String interfederatedIDP) { - this.interfederatedIDP = interfederatedIDP; - } +// /** +// * @return the interfederatedSSOSession +// */ +// public boolean isInterfederatedSSOSession() { +// return interfederatedSSOSession; +// } +// +// /** +// * @param interfederatedSSOSession the interfederatedSSOSession to set +// */ +// public void setInterfederatedSSOSession(boolean interfederatedSSOSession) { +// this.interfederatedSSOSession = interfederatedSSOSession; +// } +// +// /** +// * @return the interfederatedIDP +// */ +// public String getInterfederatedIDP() { +// return interfederatedIDP; +// } +// +// /** +// * @param interfederatedIDP the interfederatedIDP to set +// */ +// public void setInterfederatedIDP(String interfederatedIDP) { +// this.interfederatedIDP = interfederatedIDP; +// } /** * @return the ssoSessionValidTo diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java index 91d40fcc3..c32564679 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/IAuthData.java @@ -40,7 +40,7 @@ public interface IAuthData { boolean isBusinessService(); boolean isSsoSession(); - boolean isInterfederatedSSOSession(); + //boolean isInterfederatedSSOSession(); boolean isUseMandate(); String getFamilyName(); @@ -53,7 +53,7 @@ public interface IAuthData { Date getSsoSessionValidTo(); - String getInterfederatedIDP(); + //String getInterfederatedIDP(); String getIdentificationValue(); String getIdentificationType(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MISMandate.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MISMandate.java index 12fe3c948..81157994e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MISMandate.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MISMandate.java @@ -79,7 +79,7 @@ public class MISMandate implements Serializable{ private String oid = null; private byte[] mandate = null; private String owBPK = null; - private boolean isFullMandateIncluded = false; +// private boolean isFullMandateIncluded = false; public String getProfRep() { return oid; @@ -144,18 +144,18 @@ public class MISMandate implements Serializable{ } } - /** - * @return the isFullMandateIncluded - */ - public boolean isFullMandateIncluded() { - return isFullMandateIncluded; - } - /** - * @param isFullMandateIncluded the isFullMandateIncluded to set - */ - public void setFullMandateIncluded(boolean isFullMandateIncluded) { - this.isFullMandateIncluded = isFullMandateIncluded; - } +// /** +// * @return the isFullMandateIncluded +// */ +// public boolean isFullMandateIncluded() { +// return isFullMandateIncluded; +// } +// /** +// * @param isFullMandateIncluded the isFullMandateIncluded to set +// */ +// public void setFullMandateIncluded(boolean isFullMandateIncluded) { +// this.isFullMandateIncluded = isFullMandateIncluded; +// } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Pair.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Pair.java new file mode 100644 index 000000000..0b46345d3 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Pair.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.data; + +public class Pair<P1, P2> { + private final P1 first; + private final P2 second; + + private Pair(final P1 newFirst, final P2 newSecond) { + this.first = newFirst; + this.second = newSecond; + } + + public P1 getFirst() { + return this.first; + } + + public P2 getSecond() { + return this.second; + } + + public static <P1, P2> Pair<P1, P2> newInstance(final P1 newFirst, final P2 newSecond) { + return new Pair<P1, P2>(newFirst, newSecond); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Trible.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Trible.java new file mode 100644 index 000000000..78e8be452 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/Trible.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.data; + +public class Trible<P1, P2, P3> { + private final P1 first; + private final P2 second; + private final P3 third; + + private Trible(final P1 newFirst, final P2 newSecond, final P3 newThird) { + this.first = newFirst; + this.second = newSecond; + this.third = newThird; + } + + public P1 getFirst() { + return this.first; + } + + public P2 getSecond() { + return this.second; + } + + public P3 getThird() { + return this.third; + } + + public static <P1, P2, P3> Trible<P1, P2, P3> newInstance(final P1 newFirst, final P2 newSecond, final P3 newThird) { + return new Trible<P1, P2, P3>(newFirst, newSecond, newThird); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index 73d682c21..f065bbc56 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -70,8 +70,9 @@ import at.gv.egovernment.moa.id.process.api.ExecutionContext; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.SingleLogOutBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.MOASAMLSOAPClient; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngineSP; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.id.storage.ITransactionStorage; @@ -99,7 +100,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { @Autowired private MOAReversionLogger revisionsLogger; @Autowired protected AuthConfiguration authConfig; @Autowired private SingleLogOutBuilder sloBuilder; - @Autowired private SAMLVerificationEngine samlVerificationEngine; + @Autowired private SAMLVerificationEngineSP samlVerificationEngine; public void performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq) throws MOAIDException { @@ -499,7 +500,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { } else { samlVerificationEngine.verifySLOResponse(sloResp, - TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); } @@ -554,8 +555,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { context.put("redirectURLs", sloReqList); context.put("timeoutURL", timeOutURL); context.put("timeout", SLOTIMEOUT); - context.put(SSOManager.CONTEXTPATH, authURL); - ssoManager.printSingleLogOutInfo(context, httpResp); + ssoManager.printSingleLogOutInfo(context, httpResp, authURL); } else { @@ -575,7 +575,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { else context.put("errorMsg", MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); - ssoManager.printSingleLogOutInfo(context, httpResp); + ssoManager.printSingleLogOutInfo(context, httpResp, authURL); } @@ -593,7 +593,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { VelocityContext context = new VelocityContext(); context.put("errorMsg", MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); - ssoManager.printSingleLogOutInfo(context, httpResp); + ssoManager.printSingleLogOutInfo(context, httpResp, authURL); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IRequest.java index e1edb6b77..d5d0e6c48 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IRequest.java @@ -22,6 +22,8 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.moduls; +import java.util.Collection; + import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; @@ -189,4 +191,12 @@ public interface IRequest { * @param b true, if the user has abort the authentication process, otherwise false */ public void setAbortedByUser(boolean isAborted); + + /** + * This method get a Set of PVP 2.1 attribute, which are request by this pending-request. + * + * @return A set of PVP attribute names or null if no attributes are requested + * or the Service Provider, which sends this request needs no attributes + */ + public Collection<String> getRequestedAttributes(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java index 4dade61fa..aec5ad124 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java @@ -49,6 +49,9 @@ public abstract class RequestImpl implements IRequest, Serializable{ public static final String DATAID_INTERFEDERATIOIDP_URL = "interIDPURL"; public static final String DATAID_INTERFEDERATIOIDP_RESPONSE = "interIDPResponse"; public static final String DATAID_REQUESTED_ATTRIBUTES = "requestedAttributes"; + public static final String DATAID_INTERFEDERATIOIDP_ENTITYID = "interIDPEntityID"; + + public static final String eIDAS_GENERIC_REQ_DATA_COUNTRY = "country"; private static final long serialVersionUID = 1L; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java index 856410d7b..db4022cdc 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java @@ -64,7 +64,7 @@ import at.gv.egovernment.moa.util.MiscUtil; public class SSOManager { private static final String HTMLTEMPLATESDIR = "htmlTemplates/"; private static final String HTMLTEMPLATEFULL = "slo_template.html"; - public static String CONTEXTPATH = "#CONTEXTPATH#"; + public static String CONTEXTPATH = "contextPath"; private static final String SSOCOOKIE = "MOA_ID_SSO"; private static final String SSOINTERFEDERATION = "MOA_INTERFEDERATION_SSO"; @@ -150,12 +150,11 @@ public class SSOManager { return false; } - //check if request starts an interfederated SSO session + //check if stored SSO session is a federated SSO session if (protocolRequest != null && - protocolRequest instanceof RequestImpl && - storedSession.isInterfederatedSSOSession() && - !storedSession.isAuthenticated()) { - + storedSession.isInterfederatedSSOSession()) { + //in case of federated SSO session, jump to federated IDP for authentication + String interfederationIDP = protocolRequest.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class); @@ -164,6 +163,7 @@ public class SSOManager { if (selectedIDP != null) { //no local SSO session exist -> request interfederated IDP + Logger.info("SSO Session refer to federated IDP: " + selectedIDP.getIdpurlprefix()); protocolRequest.setGenericDataToSession( RequestImpl.DATAID_INTERFEDERATIOIDP_URL, selectedIDP.getIdpurlprefix()); @@ -313,9 +313,10 @@ public class SSOManager { } - public void printSingleLogOutInfo(VelocityContext context, HttpServletResponse httpResp) throws MOAIDException { + public void printSingleLogOutInfo(VelocityContext context, HttpServletResponse httpResp, String authURL) throws MOAIDException { try { Logger.trace("Initialize VelocityEngine..."); + context.put(CONTEXTPATH, authURL); InputStream is = null; String pathLocation = null; @@ -362,7 +363,7 @@ public class SSOManager { BufferedReader reader = new BufferedReader(new InputStreamReader(is )); //set default elements to velocity context - context.put("contextpath", authConfig.getPublicURLPrefix()); + //context.put(CONTEXTPATH, authConfig.getPublicURLPrefix()); StringWriter writer = new StringWriter(); //velocityEngine.evaluate(context, writer, "SLO_Template", reader); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java index a9fc994ec..0ab630dc2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/ProtocolFinalizationController.java @@ -67,10 +67,12 @@ public class ProtocolFinalizationController extends AbstractAuthProtocolModulCon try { //load stored exception from database Throwable throwable = transactionStorage.get(errorid, Throwable.class); - transactionStorage.remove(errorid); - + if (throwable != null) { - if (pendingReq != null) { + //remove exception if it was found + transactionStorage.remove(errorid); + + if (pendingReq != null) { revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR); //build protocol-specific error message if possible diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/BirthdateAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/BirthdateAttributeBuilder.java index 7cbdeca66..0e6dc1838 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/BirthdateAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/BirthdateAttributeBuilder.java @@ -26,7 +26,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSourcePIN.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSourcePIN.java index 0437cd687..69f0c3088 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSourcePIN.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EIDSourcePIN.java @@ -23,7 +23,6 @@ package at.gv.egovernment.moa.id.protocols.builder.attributes; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributePolicyException; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/HolderOfKey.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/HolderOfKey.java new file mode 100644 index 000000000..4def39d54 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/HolderOfKey.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.protocols.builder.attributes; + +import java.io.IOException; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.UnavailableAttributeException; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; + +public class HolderOfKey implements IPVPAttributeBuilder { + + public String getName() { + return PVP_HOLDEROFKEY_NAME; + } + + public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, + IAttributeGenerator<ATT> g) throws AttributeException { + + try { + byte[] certEncoded = authData.getGenericData( + MOAIDAuthConstants.MOASESSION_DATA_HOLDEROFKEY_CERTIFICATE, + byte[].class); + + if (certEncoded != null) { + return g.buildStringAttribute(PVP_HOLDEROFKEY_FRIENDLY_NAME, PVP_HOLDEROFKEY_NAME, + Base64Utils.encode(certEncoded)); + + } + + } + catch (IOException e) { + Logger.info("Encode AuthBlock BASE64 failed."); + } + throw new UnavailableAttributeException(PVP_HOLDEROFKEY_NAME); + + } + + public <ATT> ATT buildEmpty(IAttributeGenerator<ATT> g) { + return g.buildEmptyAttribute(PVP_HOLDEROFKEY_NAME, PVP_HOLDEROFKEY_NAME); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateFullMandateAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateFullMandateAttributeBuilder.java index 27d3845ff..ca66700a2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateFullMandateAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateFullMandateAttributeBuilder.java @@ -26,10 +26,7 @@ import java.io.IOException; import javax.xml.transform.TransformerException; -import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; @@ -48,7 +45,7 @@ public class MandateFullMandateAttributeBuilder implements IPVPAttributeBuilder if (authData.isUseMandate()) { //only provide full mandate if it is included. //In case of federation only a short mandate could be include - if (authData.getMandate() != null && authData.getMISMandate().isFullMandateIncluded()) { + if (authData.getMandate() != null) { String fullMandate; try { fullMandate = DOMUtils.serializeNode(authData diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonFullNameAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonFullNameAttributeBuilder.java index 7144ebe6d..67eb92d9b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonFullNameAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonFullNameAttributeBuilder.java @@ -27,12 +27,12 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateLegalPersonFullNameAttributeBuilder implements IPVPAttributeBuilder { @@ -43,22 +43,32 @@ public class MandateLegalPersonFullNameAttributeBuilder implements IPVPAttribute public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); - if (corporation == null) { - Logger.error("No corporation mandate"); - throw new NoMandateDataAttributeException(); - } + //get PVP attribute directly, if exists + String fullName = authData.getGenericData(MANDATE_LEG_PER_FULL_NAME_NAME, String.class); + + if (MiscUtil.isEmpty(fullName)) { + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + + } + CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); + if (corporation == null) { + Logger.error("No corporation mandate"); + throw new NoMandateDataAttributeException(); + + } + fullName = corporation.getFullName(); + } return g.buildStringAttribute(MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, MANDATE_LEG_PER_FULL_NAME_NAME, - corporation.getFullName()); + fullName); + } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinAttributeBuilder.java index 12dc8877b..9474cd832 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinAttributeBuilder.java @@ -26,14 +26,13 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateLegalPersonSourcePinAttributeBuilder implements IPVPAttributeBuilder { @@ -44,36 +43,39 @@ public class MandateLegalPersonSourcePinAttributeBuilder implements IPVPAttribu public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { if(authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if(mandate == null) { - throw new NoMandateDataAttributeException(); + + //get PVP attribute directly, if exists + String sourcePin = authData.getGenericData(MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class); + + if (MiscUtil.isEmpty(sourcePin)) { + Element mandate = authData.getMandate(); + if(mandate == null) { + throw new NoMandateDataAttributeException(); + + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if(mandateObject == null) { + throw new NoMandateDataAttributeException(); + + } + CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); + if(corporation == null) { + Logger.error("No corporation mandate"); + throw new NoMandateDataAttributeException(); + + } + if(corporation.getIdentification().size() == 0) { + Logger.error("Failed to generate IdentificationType"); + throw new NoMandateDataAttributeException(); + + } + + sourcePin = corporation.getIdentification().get(0).getValue().getValue(); + } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if(mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); - if(corporation == null) { - Logger.error("No corporation mandate"); - throw new NoMandateDataAttributeException(); - } - IdentificationType id = null; - if(corporation.getIdentification().size() == 0) { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAttributeException(); - } - id = corporation.getIdentification().get(0); - /*if(authSession.getBusinessService()) { - id = MandateBuilder.getWBPKIdentification(corporation); - } else { - id = MandateBuilder.getBPKIdentification(corporation); - }*/ - /*if(id == null) { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAttributeException(); - }*/ + return g.buildStringAttribute(MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, - MANDATE_LEG_PER_SOURCE_PIN_NAME, id.getValue().getValue()); + MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePin); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinTypeAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinTypeAttributeBuilder.java index a7a9a757b..8391c8230 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinTypeAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateLegalPersonSourcePinTypeAttributeBuilder.java @@ -26,14 +26,13 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType; -import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateLegalPersonSourcePinTypeAttributeBuilder implements IPVPAttributeBuilder { @@ -44,32 +43,37 @@ public class MandateLegalPersonSourcePinTypeAttributeBuilder implements IPVPAttr public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); + //get PVP attribute directly, if exists + String sourcePinType = authData.getGenericData(MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class); + + if (MiscUtil.isEmpty(sourcePinType)) { + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + + } + CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); + if (corporation == null) { + Logger.error("No corporate mandate"); + throw new NoMandateDataAttributeException(); + + } + if (corporation.getIdentification().size() == 0) { + Logger.error("Failed to generate IdentificationType"); + throw new NoMandateDataAttributeException(); + + } + sourcePinType = corporation.getIdentification().get(0).getType(); + } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); - if (corporation == null) { - Logger.error("No corporate mandate"); - throw new NoMandateDataAttributeException(); - } - IdentificationType id = null; - if (corporation.getIdentification().size() == 0) { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAttributeException(); - } - id = corporation.getIdentification().get(0); - /* - * id = MandateBuilder.getBPKIdentification(corporate); if (id == null) { - * Logger.error("Failed to generate IdentificationType"); throw new - * NoMandateDataAttributeException(); } - */ + return g.buildStringAttribute(MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, - id.getType()); + sourcePinType); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBPKAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBPKAttributeBuilder.java index be6372913..df077a631 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBPKAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBPKAttributeBuilder.java @@ -30,13 +30,13 @@ import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPers import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateNaturalPersonBPKAttributeBuilder implements IPVPAttributeBuilder { @@ -45,49 +45,53 @@ public class MandateNaturalPersonBPKAttributeBuilder implements IPVPAttributeBui } public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, - IAttributeGenerator<ATT> g) throws AttributeException { - if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); - if (physicalPerson == null) { - Logger.error("No physicalPerson mandate"); - throw new NoMandateDataAttributeException(); - } - IdentificationType id = null; - id = physicalPerson.getIdentification().get(0); - if (id == null) { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAttributeException(); - } + IAttributeGenerator<ATT> g) throws AttributeException { + if (authData.isUseMandate()) { - String bpk; - try { + //get PVP attribute directly, if exists + String bpk = authData.getGenericData(MANDATE_NAT_PER_BPK_NAME, String.class); + + if (MiscUtil.isEmpty(bpk)) { + //read bPK from mandate if it is not directly included + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + } + PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); + if (physicalPerson == null) { + Logger.error("No physicalPerson mandate"); + throw new NoMandateDataAttributeException(); + } + IdentificationType id = null; + id = physicalPerson.getIdentification().get(0); + if (id == null) { + Logger.error("Failed to generate IdentificationType"); + throw new NoMandateDataAttributeException(); + } - if (id.getType().equals(Constants.URN_PREFIX_BASEID)) { - if (oaParam.getBusinessService()) { - bpk = new BPKBuilder().buildWBPK(id.getValue().getValue(), oaParam.getIdentityLinkDomainIdentifier()); + try { + if (id.getType().equals(Constants.URN_PREFIX_BASEID)) { + if (oaParam.getBusinessService()) { + bpk = new BPKBuilder().buildWBPK(id.getValue().getValue(), oaParam.getIdentityLinkDomainIdentifier()); + + } else { + bpk = new BPKBuilder().buildBPK(id.getValue().getValue(), oaParam.getTarget()); + + } - } + } else + bpk = id.getValue().getValue(); - else { - bpk = new BPKBuilder().buildBPK(id.getValue().getValue(), oaParam.getTarget()); - - } + } + catch (BuildException e) { + Logger.error("Failed to generate IdentificationType"); + throw new NoMandateDataAttributeException(); - } else - bpk = id.getValue().getValue(); - - } - catch (BuildException e) { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAttributeException(); + } } return g.buildStringAttribute(MANDATE_NAT_PER_BPK_FRIENDLY_NAME, MANDATE_NAT_PER_BPK_NAME, bpk); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBirthDateAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBirthDateAttributeBuilder.java index e644f49e4..663e927fc 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBirthDateAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonBirthDateAttributeBuilder.java @@ -32,13 +32,13 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.InvalidDateFormatAttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateNaturalPersonBirthDateAttributeBuilder implements IPVPAttributeBuilder { @@ -49,33 +49,56 @@ public class MandateNaturalPersonBirthDateAttributeBuilder implements IPVPAttrib public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); - if (physicalPerson == null) { - Logger.error("No physicalPerson mandate"); - throw new NoMandateDataAttributeException(); - } - String dateOfBirth = physicalPerson.getDateOfBirth(); - try { - DateFormat mandateFormat = new SimpleDateFormat(MandateBuilder.MANDATE_DATE_OF_BIRTH_FORMAT); - Date date = mandateFormat.parse(dateOfBirth); - DateFormat pvpDateFormat = new SimpleDateFormat(MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN); - String dateString = pvpDateFormat.format(date); + //get PVP attribute directly, if exists + String birthDayString = authData.getGenericData(MANDATE_NAT_PER_BIRTHDATE_NAME, String.class); + + if (MiscUtil.isEmpty(birthDayString)) { + //read bPK from mandate if it is not directly included + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + } + PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); + if (physicalPerson == null) { + Logger.error("No physicalPerson mandate"); + throw new NoMandateDataAttributeException(); + } + + String dateOfBirth = physicalPerson.getDateOfBirth(); + try { + DateFormat mandateFormat = new SimpleDateFormat(MandateBuilder.MANDATE_DATE_OF_BIRTH_FORMAT); + mandateFormat.setLenient(false); + Date date = mandateFormat.parse(dateOfBirth); + DateFormat pvpDateFormat = new SimpleDateFormat(MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN); + birthDayString = pvpDateFormat.format(date); + + } + catch (ParseException e) { + Logger.warn("MIS mandate birthday has an incorrect formt. (Value:" + dateOfBirth, e); + throw new InvalidDateFormatAttributeException(); + + } + + } else { + try { + DateFormat pvpDateFormat = new SimpleDateFormat(MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN); + pvpDateFormat.setLenient(false); + pvpDateFormat.parse(birthDayString); + + } catch (ParseException e) { + Logger.warn("Format of direct included PVP Attribute " + MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME + + " has an incorrect formt. (Value:" + birthDayString, e); + throw new InvalidDateFormatAttributeException(); + } - return g.buildStringAttribute(MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, MANDATE_NAT_PER_BIRTHDATE_NAME, dateString); - } - catch (ParseException e) { - e.printStackTrace(); - throw new InvalidDateFormatAttributeException(); } + + return g.buildStringAttribute(MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, MANDATE_NAT_PER_BIRTHDATE_NAME, birthDayString); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonFamilyNameAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonFamilyNameAttributeBuilder.java index fa3ad691d..dd49b2a1e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonFamilyNameAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonFamilyNameAttributeBuilder.java @@ -30,12 +30,12 @@ import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateNaturalPersonFamilyNameAttributeBuilder implements IPVPAttributeBuilder { @@ -46,29 +46,38 @@ public class MandateNaturalPersonFamilyNameAttributeBuilder implements IPVPAttr public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { if(authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if(mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if(mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); - if(physicalPerson == null) { - Logger.error("No physicalPerson mandate"); - throw new NoMandateDataAttributeException(); - } - StringBuilder sb = new StringBuilder(); - Iterator<FamilyName> fNamesit = physicalPerson.getName().getFamilyName().iterator(); + //get PVP attribute directly, if exists + String familyName = authData.getGenericData(MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class); - while(fNamesit.hasNext()) { - sb.append(" " + fNamesit.next().getValue()); + if (MiscUtil.isEmpty(familyName)) { + //read mandator familyName from mandate if it is not directly included + Element mandate = authData.getMandate(); + if(mandate == null) { + throw new NoMandateDataAttributeException(); + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if(mandateObject == null) { + throw new NoMandateDataAttributeException(); + } + PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); + if(physicalPerson == null) { + Logger.error("No physicalPerson mandate"); + throw new NoMandateDataAttributeException(); + } + + StringBuilder sb = new StringBuilder(); + Iterator<FamilyName> fNamesit = physicalPerson.getName().getFamilyName().iterator(); + + while(fNamesit.hasNext()) + sb.append(" " + fNamesit.next().getValue()); + + familyName = sb.toString(); + } return g.buildStringAttribute(MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, - MANDATE_NAT_PER_FAMILY_NAME_NAME, sb.toString()); + MANDATE_NAT_PER_FAMILY_NAME_NAME, familyName); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonGivenNameAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonGivenNameAttributeBuilder.java index 4c725c1c5..55c864335 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonGivenNameAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateNaturalPersonGivenNameAttributeBuilder.java @@ -29,12 +29,12 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateNaturalPersonGivenNameAttributeBuilder implements IPVPAttributeBuilder { @@ -44,29 +44,36 @@ public class MandateNaturalPersonGivenNameAttributeBuilder implements IPVPAttrib public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { - if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); - if (physicalPerson == null) { - Logger.error("No physicalPerson mandate"); - throw new NoMandateDataAttributeException(); - } - - StringBuilder sb = new StringBuilder(); - Iterator<String> gNamesit = physicalPerson.getName().getGivenName().iterator(); + if (authData.isUseMandate()) { + //get PVP attribute directly, if exists + String givenName = authData.getGenericData(MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class); - while (gNamesit.hasNext()) { - sb.append(" " + gNamesit.next()); + if (MiscUtil.isEmpty(givenName)) { + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + } + PhysicalPersonType physicalPerson = mandateObject.getMandator().getPhysicalPerson(); + if (physicalPerson == null) { + Logger.error("No physicalPerson mandate"); + throw new NoMandateDataAttributeException(); + } + + StringBuilder sb = new StringBuilder(); + Iterator<String> gNamesit = physicalPerson.getName().getGivenName().iterator(); + + while (gNamesit.hasNext()) + sb.append(" " + gNamesit.next()); + + givenName = sb.toString(); + } - return g.buildStringAttribute(MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, MANDATE_NAT_PER_GIVEN_NAME_NAME, sb.toString()); + return g.buildStringAttribute(MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, MANDATE_NAT_PER_GIVEN_NAME_NAME, givenName); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepDescAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepDescAttributeBuilder.java index e70326114..d1da36aa3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepDescAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepDescAttributeBuilder.java @@ -26,7 +26,6 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; @@ -42,35 +41,37 @@ public class MandateProfRepDescAttributeBuilder implements IPVPAttributeBuilder public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { - if(authData.isUseMandate()) { - String text = null; + if(authData.isUseMandate()) { + String profRepName = authData.getGenericData(MANDATE_PROF_REP_DESC_NAME, String.class); - MISMandate misMandate = authData.getMISMandate(); - - if(misMandate == null) { - throw new NoMandateDataAttributeException(); - } - - text = misMandate.getTextualDescriptionOfOID(); - - if (MiscUtil.isEmpty(text)) { - Element mandate = authData.getMandate(); - if (mandate == null) { + if (MiscUtil.isEmpty(profRepName)) { + MISMandate misMandate = authData.getMISMandate(); + + if(misMandate == null) { throw new NoMandateDataAttributeException(); } - Mandate mandateObject = MandateBuilder.buildMandate(authData.getMandate()); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } - - text = mandateObject.getAnnotation(); + profRepName = misMandate.getTextualDescriptionOfOID(); + + if (MiscUtil.isEmpty(profRepName)) { + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + } + Mandate mandateObject = MandateBuilder.buildMandate(authData.getMandate()); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + } + + profRepName = mandateObject.getAnnotation(); + + } } - if(MiscUtil.isNotEmpty(text)) + if(MiscUtil.isNotEmpty(profRepName)) return g.buildStringAttribute(MANDATE_PROF_REP_DESC_FRIENDLY_NAME, - MANDATE_PROF_REP_DESC_NAME, text); + MANDATE_PROF_REP_DESC_NAME, profRepName); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepOIDAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepOIDAttributeBuilder.java index 89e9198b6..3cfc40d22 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepOIDAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateProfRepOIDAttributeBuilder.java @@ -23,7 +23,6 @@ package at.gv.egovernment.moa.id.protocols.builder.attributes; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; @@ -38,19 +37,23 @@ public class MandateProfRepOIDAttributeBuilder implements IPVPAttributeBuilder { public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { - if (authData.isUseMandate()) { + if (authData.isUseMandate()) { + String profRepOID = authData.getGenericData(MANDATE_PROF_REP_OID_NAME, String.class); - MISMandate mandate = authData.getMISMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); + if (MiscUtil.isEmpty(profRepOID)) { + MISMandate mandate = authData.getMISMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + } + + profRepOID = mandate.getProfRep(); + } - - String oid = mandate.getProfRep(); - if(MiscUtil.isEmpty(oid)) + if(MiscUtil.isEmpty(profRepOID)) return null; else - return g.buildStringAttribute(MANDATE_PROF_REP_OID_FRIENDLY_NAME, MANDATE_PROF_REP_OID_NAME, oid); + return g.buildStringAttribute(MANDATE_PROF_REP_OID_FRIENDLY_NAME, MANDATE_PROF_REP_OID_NAME, profRepOID); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateTypeAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateTypeAttributeBuilder.java index 040174e26..573f0584a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateTypeAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/MandateTypeAttributeBuilder.java @@ -26,11 +26,11 @@ import org.w3c.dom.Element; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.util.MandateBuilder; +import at.gv.egovernment.moa.util.MiscUtil; public class MandateTypeAttributeBuilder implements IPVPAttributeBuilder { @@ -40,17 +40,26 @@ public class MandateTypeAttributeBuilder implements IPVPAttributeBuilder { public <ATT> ATT build(IOAAuthParameters oaParam, IAuthData authData, IAttributeGenerator<ATT> g) throws AttributeException { - if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if (mandate == null) { - throw new NoMandateDataAttributeException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if (mandateObject == null) { - throw new NoMandateDataAttributeException(); - } + if (authData.isUseMandate()) { + //get PVP attribute directly, if exists + String mandateType = authData.getGenericData(MANDATE_TYPE_NAME, String.class); - return g.buildStringAttribute(MANDATE_TYPE_FRIENDLY_NAME, MANDATE_TYPE_NAME, mandateObject.getAnnotation()); + if (MiscUtil.isEmpty(mandateType)) { + Element mandate = authData.getMandate(); + if (mandate == null) { + throw new NoMandateDataAttributeException(); + + } + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if (mandateObject == null) { + throw new NoMandateDataAttributeException(); + + } + mandateType = mandateObject.getAnnotation(); + + } + + return g.buildStringAttribute(MANDATE_TYPE_FRIENDLY_NAME, MANDATE_TYPE_NAME, mandateType); } return null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java index bd6399377..142810d45 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -41,18 +42,29 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder; +import at.gv.egovernment.moa.id.auth.builder.DynamicOAAuthParameterBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; +import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; +import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; +import at.gv.egovernment.moa.id.data.Trible; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AuthResponseBuilder; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder; -import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.logging.Logger; @@ -63,9 +75,10 @@ import at.gv.egovernment.moa.logging.Logger; @Service("AttributQueryAction") public class AttributQueryAction implements IAction { - @Autowired IAuthenticationSessionStoreage authenticationSessionStorage; + @Autowired private IAuthenticationSessionStoreage authenticationSessionStorage; @Autowired private AuthenticationDataBuilder authDataBuilder; @Autowired private IDPCredentialProvider pvpCredentials; + @Autowired private AuthConfiguration authConfig; private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList( new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); @@ -80,41 +93,55 @@ public class AttributQueryAction implements IAction { * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @Override - public SLOInformationInterface processRequest(IRequest req, + public SLOInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { - if (req instanceof PVPTargetConfiguration && - ((PVPTargetConfiguration) req).getRequest() instanceof MOARequest && - ((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest() instanceof AttributeQuery) { + if (pendingReq instanceof PVPTargetConfiguration && + ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest && + ((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest() instanceof AttributeQuery) { - AttributeQuery attrQuery = (AttributeQuery)((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest(); - - //load moaSession - String nameID = attrQuery.getSubject().getNameID().getValue(); - - AuthenticationSession session = authenticationSessionStorage.getSessionWithUserNameID(nameID); - if (session == null) { - Logger.warn("AttributeQuery nameID does not match to an active single sign-on session."); - throw new AttributQueryException("AttributeQuery nameID does not match to an active single sign-on session.", null); - - } - + //set time reference DateTime date = new DateTime(); - //generate authData - authData = authDataBuilder.buildAuthenticationData(req, session, attrQuery.getAttributes()); - - //add default attributes in case of mandates or STORK is in use - List<String> attrList = addDefaultAttributes(attrQuery, authData); - - //build PVP 2.1 assertion - Assertion assertion = PVP2AssertionBuilder.buildAssertion(req, attrQuery, attrList, authData, date, authData.getSessionIndex()); - - //build PVP 2.1 response - Response authResponse = AuthResponseBuilder.buildResponse(req.getAuthURL(), attrQuery, date, assertion); - try { + //get Single Sign-On information for the Service-Provider + // which sends the Attribute-Query request + AuthenticationSession moaSession = authenticationSessionStorage.getSession(pendingReq.getMOASessionIdentifier()); + if (moaSession == null) { + Logger.warn("No MOASession with ID:" + pendingReq.getMOASessionIdentifier() + " FOUND."); + throw new MOAIDException("auth.02", new Object[]{pendingReq.getMOASessionIdentifier()}); + } + + InterfederationSessionStore nextIDPInformation = + authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID()); + + AttributeQuery attrQuery = + (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest(); + + //build PVP 2.1 response-attribute information for this AttributQueryRequest + Trible<List<Attribute>, Date, String> responseInfo = + buildResponseInformationForAttributQuery(pendingReq, moaSession, attrQuery.getAttributes(), nextIDPInformation); + + Logger.debug("AttributQuery return " + responseInfo.getFirst().size() + + " attributes with QAA-Level:" + responseInfo.getThird() + + " validTo:" + responseInfo.getSecond().toString()); + + //build PVP 2.1 assertion + + String issuerEntityID = pendingReq.getAuthURL(); + if (issuerEntityID.endsWith("/")) + issuerEntityID = issuerEntityID.substring(0, issuerEntityID.length()-1); + + Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID, + attrQuery, responseInfo.getFirst(), date, new DateTime(responseInfo.getSecond().getTime()), + responseInfo.getThird(), authData.getSessionIndex()); + + //build PVP 2.1 response + Response authResponse = AuthResponseBuilder.buildResponse( + MOAMetadataProvider.getInstance(), issuerEntityID, attrQuery, date, + assertion, authConfig.isPVP2AssertionEncryptionActive()); + SoapBinding decoder = new SoapBinding(); decoder.encodeRespone(httpReq, httpResp, authResponse, null, null, pvpCredentials.getIDPAssertionSigningCredential()); @@ -128,6 +155,11 @@ public class AttributQueryAction implements IAction { Logger.error("Security exception", e); throw new MOAIDException("pvp2.01", null, e); + } catch (MOADatabaseException e) { + Logger.error("MOASession with SessionID=" + pendingReq.getMOASessionIdentifier() + + " is not found in Database", e); + throw new MOAIDException("init.04", new Object[] { pendingReq.getMOASessionIdentifier() }); + } } else { @@ -153,32 +185,143 @@ public class AttributQueryAction implements IAction { public String getDefaultActionName() { return PVP2XProtocol.ATTRIBUTEQUERY; } + + private Trible<List<Attribute>, Date, String> buildResponseInformationForAttributQuery(IRequest pendingReq, + AuthenticationSession session, List<Attribute> reqAttributes, InterfederationSessionStore nextIDPInformation) throws MOAIDException { + try { + //mark AttributeQuery as used if it exists + OASessionStore activeOA = authenticationSessionStorage.searchActiveOASSOSession(session, pendingReq.getOAURL(), pendingReq.requestedModule()); + if (activeOA != null) { + //mark + if ( pendingReq instanceof PVPTargetConfiguration && + ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest && + ((PVPTargetConfiguration) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) { + try { + activeOA.setAttributeQueryUsed(true); + MOASessionDBUtils.saveOrUpdate(activeOA); + + } catch (MOADatabaseException e) { + Logger.error("MOASession interfederation information can not stored to database.", e); + + } + } + } + + //build OnlineApplication dynamic from requested attributes (AttributeQuerry Request) and configuration + IOAAuthParameters spConfig = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes); + + //search federated IDP information for this MOASession + if (nextIDPInformation != null) { + Logger.info("Find active federated IDP information." + + ". --> Request next IDP:" + nextIDPInformation.getIdpurlprefix() + + " for authentication information."); + + //load configuration of next IDP + OAAuthParameter idp = authConfig.getOnlineApplicationParameter(nextIDPInformation.getIdpurlprefix()); + if (idp == null) { + Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix() + + "is not loadable."); + throw new MOAIDException("auth.32", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } - private List<String> addDefaultAttributes(AttributeQuery query, IAuthData authData) { + //check if next IDP config allows inbound messages + if (!idp.isInboundSSOInterfederationAllowed()) { + Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix() + + "disallow inbound authentication messages."); + throw new MOAIDException("auth.33", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } + + //check next IDP service area policy. BusinessService IDPs can only request wbPKs + if (!spConfig.getBusinessService() && !idp.isIDPPublicService()) { + Logger.error("Interfederated IDP " + idp.getPublicURLPrefix() + + " has a BusinessService-IDP but requests PublicService attributes."); + throw new MOAIDException("auth.34", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } + + //validation complete --> start AttributeQuery Request + AssertionAttributeExtractor extractor = authDataBuilder.getAuthDataFromAttributeQuery(reqAttributes, + nextIDPInformation.getUserNameID(), idp); + + try { + //mark attribute request as used + if (nextIDPInformation.isStoreSSOInformation()) { + nextIDPInformation.setAttributesRequested(true); + MOASessionDBUtils.saveOrUpdate(nextIDPInformation); + + //delete federated IDP from Session + } else { + MOASessionDBUtils.delete(nextIDPInformation); + + } + + } catch (MOADatabaseException e) { + Logger.error("MOASession interfederation information can not stored to database.", e); + + } + + return Trible.newInstance( + extractor.getAllResponseAttributesFromFirstAttributeStatement(), + extractor.getAssertionNotOnOrAfter(), + extractor.getQAALevel()); + + } else { + Logger.debug("Build authData for AttributQuery from local MOASession."); + IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq, session, spConfig); + + //add default attributes in case of mandates or STORK is in use + List<String> attrList = addDefaultAttributes(reqAttributes, authData); - List<String> reqAttributs = new ArrayList<String>(); + //build Set of response attributes + List<Attribute> respAttr = PVPAttributeBuilder.buildSetOfResponseAttributes(authData, attrList); + + return Trible.newInstance(respAttr, authData.getSsoSessionValidTo(), authData.getQAALevel()); + + } + + } catch (MOAIDException e) { + throw e; + } + } + + /** + * Add additional PVP Attribute-Names in respect to current MOASession. + *<br><br> + * <pre>As example: if current MOASession includes mandates but mandate attributes are not requested, + * this method a a minimum set of mandate attribute-names</pre> + * + * @param reqAttr From Service Provider requested attributes + * @param authData AuthenticationData + * @return List of PVP attribute-names + */ + private List<String> addDefaultAttributes(List<Attribute> reqAttr, IAuthData authData) { - for (Attribute attr : query.getAttributes()) { - reqAttributs.add(attr.getName()); + List<String> reqAttributeNames = new ArrayList<String>(); + + for (Attribute attr : reqAttr) { + reqAttributeNames.add(attr.getName()); } //add default STORK attributes if it is a STORK authentication - if (authData.isForeigner() && !reqAttributs.containsAll(DEFAULTSTORKATTRIBUTES)) { + if (authData.isForeigner() && !reqAttributeNames.containsAll(DEFAULTSTORKATTRIBUTES)) { for (String el : DEFAULTSTORKATTRIBUTES) { - if (!reqAttributs.contains(el)) - reqAttributs.add(el); + if (!reqAttributeNames.contains(el)) + reqAttributeNames.add(el); } } //add default mandate attributes if it is a authentication with mandates - if (authData.isUseMandate() && !reqAttributs.containsAll(DEFAULTMANDATEATTRIBUTES)) { + if (authData.isUseMandate() && !reqAttributeNames.containsAll(DEFAULTMANDATEATTRIBUTES)) { for (String el : DEFAULTMANDATEATTRIBUTES) { - if (!reqAttributs.contains(el)) - reqAttributs.add(el); + if (!reqAttributeNames.contains(el)) + reqAttributeNames.add(el); } } - return reqAttributs; + return reqAttributeNames; } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java index 2882f20e1..a214dad9d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java @@ -38,6 +38,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationImpl; import at.gv.egovernment.moa.id.data.SLOInformationInterface; @@ -50,6 +51,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AuthResponseBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; @@ -57,6 +59,7 @@ import at.gv.egovernment.moa.logging.Logger; @Service("PVPAuthenticationRequestAction") public class AuthenticationAction implements IAction { @Autowired IDPCredentialProvider pvpCredentials; + @Autowired AuthConfiguration authConfig; public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { @@ -77,12 +80,18 @@ public class AuthenticationAction implements IAction { SLOInformationImpl sloInformation = new SLOInformationImpl(); - + //change to entity value from entity name to IDP EntityID (URL) + String issuerEntityID = pvpRequest.getAuthURL(); + if (issuerEntityID.endsWith("/")) + issuerEntityID = issuerEntityID.substring(0, issuerEntityID.length()-1); + //build Assertion - Assertion assertion = PVP2AssertionBuilder.buildAssertion(pvpRequest, authnRequest, authData, + Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID, pvpRequest, authnRequest, authData, peerEntity, date, consumerService, sloInformation); - Response authResponse = AuthResponseBuilder.buildResponse(pvpRequest.getAuthURL(), authnRequest, date, assertion); + Response authResponse = AuthResponseBuilder.buildResponse( + MOAMetadataProvider.getInstance(), issuerEntityID, authnRequest, + date, assertion, authConfig.isPVP2AssertionEncryptionActive()); IEncoder binding = null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java index 08d9f67b6..8065af1a6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java @@ -57,6 +57,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException; @@ -67,6 +68,7 @@ import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.moduls.NoPassivAuthenticationException; import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOAURICompare; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding; @@ -83,11 +85,12 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SLOException; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.CheckMandateAttributes; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.id.protocols.pvp2x.validation.AuthnRequestValidator; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngineSP; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; import at.gv.egovernment.moa.id.util.ErrorResponseUtils; import at.gv.egovernment.moa.id.util.HTTPUtils; @@ -100,7 +103,7 @@ import at.gv.egovernment.moa.util.MiscUtil; public class PVP2XProtocol extends AbstractAuthProtocolModulController { @Autowired IDPCredentialProvider pvpCredentials; - @Autowired SAMLVerificationEngine samlVerificationEngine; + @Autowired SAMLVerificationEngineSP samlVerificationEngine; public static final String NAME = PVP2XProtocol.class.getName(); public static final String PATH = "id_pvp2x"; @@ -188,9 +191,11 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { req.getRemoteAddr()); //get POST-Binding decoder implementation - InboundMessage msg = (InboundMessage) new PostBinding().decode(req, resp, false); + InboundMessage msg = (InboundMessage) new PostBinding().decode( + req, resp, MOAMetadataProvider.getInstance(), false, + new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); - + //preProcess Message preProcess(req, resp, pendingReq); @@ -236,7 +241,9 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { req.getRemoteAddr()); //get POST-Binding decoder implementation - InboundMessage msg = (InboundMessage) new RedirectBinding().decode(req, resp, false); + InboundMessage msg = (InboundMessage) new RedirectBinding().decode( + req, resp, MOAMetadataProvider.getInstance(), false, + new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); //preProcess Message @@ -261,9 +268,59 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { } + //PVP2.x IDP SOAP-Binding end-point + @RequestMapping(value = "/pvp2/soap", method = {RequestMethod.POST}) + public void PVPIDPSOAPRequest(HttpServletRequest req, HttpServletResponse resp) throws MOAIDException { + if (!authConfig.getAllowedProtocols().isPVP21Active()) { + Logger.info("PVP2.1 is deaktivated!"); + throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }); + + } + + try { + //create pendingRequest object + PVPTargetConfiguration pendingReq = applicationContext.getBean(PVPTargetConfiguration.class); + pendingReq.initialize(req); + pendingReq.setModule(NAME); + + revisionsLogger.logEvent(MOAIDEventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier()); + revisionsLogger.logEvent(MOAIDEventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier()); + revisionsLogger.logEvent( + pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), + MOAIDEventConstants.TRANSACTION_IP, + req.getRemoteAddr()); + + //get POST-Binding decoder implementation + InboundMessage msg = (InboundMessage) new SoapBinding().decode( + req, resp, MOAMetadataProvider.getInstance(), false, + new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); + pendingReq.setRequest(msg); + + //preProcess Message + preProcess(req, resp, pendingReq); + + } catch (SecurityPolicyException e) { + String samlRequest = req.getParameter("SAMLRequest"); + Logger.warn("Receive INVALID protocol request: " + samlRequest, e); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); + + } catch (SecurityException e) { + String samlRequest = req.getParameter("SAMLRequest"); + Logger.warn("Receive INVALID protocol request: " + samlRequest, e); + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); + + } catch (Throwable e) { + String samlRequest = req.getParameter("SAMLRequest"); + Logger.warn("Receive INVALID protocol request: " + samlRequest, e); + + throw new MOAIDException(e.getMessage(), new Object[] {}); + } + } + - public void preProcess(HttpServletRequest request, + private void preProcess(HttpServletRequest request, HttpServletResponse response, PVPTargetConfiguration pendingReq) throws Throwable { InboundMessage msg = pendingReq.getRequest(); @@ -274,7 +331,8 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { } if(!msg.isVerified()) { - samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + samlVerificationEngine.verify(msg, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); msg.setVerified(true); } @@ -521,7 +579,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { throw new WrongParametersException("StartAuthentication", PARAM_OA, "auth.12"); - OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(moaRequest.getEntityID()); + OAAuthParameter oa = authConfig.getOnlineApplicationParameter(moaRequest.getEntityID()); if (!oa.isInderfederationIDP()) { Logger.warn("AttributeQuery requests are only allowed for interfederation IDPs."); throw new AttributQueryException("AttributeQuery requests are only allowed for interfederation IDPs.", null); @@ -533,18 +591,31 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { throw new AttributQueryException("Interfederation IDP does not allow outgoing SSO interfederation.", null); } + + //check active MOASession + String nameID = attrQuery.getSubject().getNameID().getValue(); + AuthenticationSession session = authenticatedSessionStorage.getSessionWithUserNameID(nameID); + if (session == null) { + Logger.warn("AttributeQuery nameID does not match to an active single sign-on session."); + throw new AttributQueryException("auth.31", null); + } + + //set preProcessed information into pending-request pendingReq.setRequest(moaRequest); pendingReq.setOAURL(moaRequest.getEntityID()); pendingReq.setOnlineApplicationConfiguration(oa); pendingReq.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); - //Attribute-Query Request needs authentication - pendingReq.setNeedAuthentication(true); - + //Attribute-Query Request needs authentication, because session MUST be already authenticated + pendingReq.setNeedAuthentication(false); + //set protocol action, which should be executed after authentication pendingReq.setAction(AttributQueryAction.class.getName()); - + + //add moasession + pendingReq.setMOASessionIdentifier(session.getSessionID()); + //write revisionslog entry revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROTOCOL_PVP_REQUEST_ATTRIBUTQUERY); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java index dc0cab8c3..c2b61aaa7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java @@ -274,4 +274,8 @@ public interface PVPConstants { public static final String CHARGE_CODE_NAME = URN_OID_PREFIX + CHARGE_CODE_OID; public static final String CHARGE_CODE_FRIENDLY_NAME = "CHARGE-CODE"; public static final int CHARGE_CODE_MAX_LENGTH = 32767; + + public static final String PVP_HOLDEROFKEY_OID = "1.2.40.0.10.2.1.1.261.xx.xx"; + public static final String PVP_HOLDEROFKEY_NAME = URN_OID_PREFIX + PVP_HOLDEROFKEY_OID; + public static final String PVP_HOLDEROFKEY_FRIENDLY_NAME = "HOLDER-OF-KEY-CERTIFICATE"; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java index 27773a248..b8ced1198 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java @@ -46,6 +46,10 @@ import at.gv.egovernment.moa.logging.Logger; @Scope(value = BeanDefinition.SCOPE_PROTOTYPE) public class PVPTargetConfiguration extends RequestImpl { + public static final String DATAID_INTERFEDERATION_MINIMAL_FRONTCHANNEL_RESP = "useMinimalFrontChannelResponse"; + public static final String DATAID_INTERFEDERATION_NAMEID = "federatedNameID"; + public static final String DATAID_INTERFEDERATION_QAALEVEL = "federatedQAALevel"; + private static final long serialVersionUID = 4889919265919638188L; InboundMessage request; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java index 6619876dc..71c5a46a4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java @@ -25,6 +25,8 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.binding; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.opensaml.common.binding.decoding.URIComparator; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.xml.security.SecurityException; @@ -33,7 +35,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface public interface IDecoder { public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, boolean isSPEndPoint) + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, SecurityException, PVP2Exception; public boolean handleDecode(String action, HttpServletRequest req); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java index ebb4b2991..46381fcc2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java @@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.velocity.app.VelocityEngine; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; @@ -37,6 +38,7 @@ import org.opensaml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.ws.message.encoder.MessageEncodingException; import org.opensaml.ws.security.SecurityPolicyResolver; @@ -48,18 +50,14 @@ import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.Credential; -import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap; -import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.validation.MOAPVPSignedRequestPolicyRule; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; -import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -146,35 +144,30 @@ public class PostBinding implements IDecoder, IEncoder { } public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, boolean isSPEndPoint) throws MessageDecodingException, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, SecurityException { HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); messageContext .setInboundMessageTransport(new HttpServletRequestAdapter(req)); - try { - //set metadata descriptor type - if (isSPEndPoint) { - messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); - decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getSPSSOPostService(HTTPUtils.extractAuthURLFromRequest(req)))); - - } else { - messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); - decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(HTTPUtils.extractAuthURLFromRequest(req)))); - } - - } catch (ConfigurationException e) { - throw new SecurityException(e); + //set metadata descriptor type + if (isSPEndPoint) { + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + + } else { + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); } - messageContext.setMetadataProvider(MOAMetadataProvider.getInstance()); + messageContext.setMetadataProvider(metadataProvider); //set security policy context BasicSecurityPolicy policy = new BasicSecurityPolicy(); policy.getPolicyRules().add( - new MOAPVPSignedRequestPolicyRule( - TrustEngineFactory.getSignatureKnownKeysTrustEngine(), + new MOAPVPSignedRequestPolicyRule(metadataProvider, + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider), messageContext.getPeerEntityRole())); SecurityPolicyResolver secResolver = new StaticSecurityPolicyResolver(policy); messageContext.setSecurityPolicyResolver(secResolver); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java index 0ff18d903..1d13cbd07 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder; import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; @@ -38,6 +39,7 @@ import org.opensaml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.ws.message.encoder.MessageEncodingException; import org.opensaml.ws.security.SecurityPolicyResolver; @@ -49,17 +51,14 @@ import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.Credential; -import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap; -import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; -import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -133,7 +132,7 @@ public class RedirectBinding implements IDecoder, IEncoder { } public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, boolean isSPEndPoint) throws MessageDecodingException, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, SecurityException { HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( @@ -143,26 +142,20 @@ public class RedirectBinding implements IDecoder, IEncoder { messageContext .setInboundMessageTransport(new HttpServletRequestAdapter(req)); - try { - //set metadata descriptor type - if (isSPEndPoint) { - messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); - decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getSPSSORedirectService(HTTPUtils.extractAuthURLFromRequest(req)))); - - } else { - messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); - decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getIDPSSORedirectService(HTTPUtils.extractAuthURLFromRequest(req)))); - } - - } catch (ConfigurationException e) { - throw new SecurityException(e); + //set metadata descriptor type + if (isSPEndPoint) { + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); + } else { + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + decode.setURIComparator(comparator); } - messageContext.setMetadataProvider(MOAMetadataProvider.getInstance()); + messageContext.setMetadataProvider(metadataProvider); SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( - TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule(); BasicSecurityPolicy policy = new BasicSecurityPolicy(); policy.getPolicyRules().add(signatureRule); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java index cc3553551..25b22f0ad 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java @@ -29,11 +29,13 @@ import javax.servlet.http.HttpServletResponse; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.StatusResponseType; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.ws.message.encoder.MessageEncodingException; import org.opensaml.ws.soap.soap11.Envelope; @@ -63,7 +65,7 @@ public class SoapBinding implements IDecoder, IEncoder { @Autowired private IDPCredentialProvider credentialProvider; public InboundMessageInterface decode(HttpServletRequest req, - HttpServletResponse resp, boolean isSPEndPoint) throws MessageDecodingException, + HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, SecurityException, PVP2Exception { HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = @@ -71,7 +73,7 @@ public class SoapBinding implements IDecoder, IEncoder { messageContext .setInboundMessageTransport(new HttpServletRequestAdapter( req)); - messageContext.setMetadataProvider(MOAMetadataProvider.getInstance()); + messageContext.setMetadataProvider(metadataProvider); //TODO: update in a futher version: // requires a special SignedSOAPRequestPolicyRole because diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java index 24c2626e3..aea3c2ee7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java @@ -23,7 +23,6 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.builder; import java.util.ArrayList; -import java.util.Date; import java.util.List; import org.joda.time.DateTime; @@ -38,6 +37,7 @@ import org.opensaml.saml2.core.Response; import org.opensaml.saml2.encryption.Encrypter; import org.opensaml.saml2.encryption.Encrypter.KeyPlacement; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.security.MetadataCredentialResolver; import org.opensaml.security.MetadataCriteria; import org.opensaml.xml.encryption.EncryptionException; @@ -52,11 +52,8 @@ import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory; import org.opensaml.xml.security.x509.X509Credential; import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; -import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionEncryptionException; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; @@ -66,15 +63,12 @@ import at.gv.egovernment.moa.logging.Logger; */ public class AuthResponseBuilder { - public static Response buildResponse(String authURL, RequestAbstractType req, DateTime date, Assertion assertion) throws InvalidAssertionEncryptionException, ConfigurationException { + public static Response buildResponse(MetadataProvider metadataProvider, String issuerEntityID, RequestAbstractType req, DateTime date, Assertion assertion, boolean enableEncryption) throws InvalidAssertionEncryptionException, ConfigurationException { Response authResponse = SAML2Utils.createSAMLObject(Response.class); Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); - //change to entity value from entity name to IDP EntityID (URL) - if (authURL.endsWith("/")) - authURL = authURL.substring(0, authURL.length()-1); - nissuer.setValue(authURL); + nissuer.setValue(issuerEntityID); nissuer.setFormat(NameID.ENTITY); authResponse.setIssuer(nissuer); authResponse.setInResponseTo(req.getID()); @@ -91,7 +85,7 @@ public class AuthResponseBuilder { //check, if metadata includes an encryption key MetadataCredentialResolver mdCredResolver = - new MetadataCredentialResolver(MOAMetadataProvider.getInstance()); + new MetadataCredentialResolver(metadataProvider); CriteriaSet criteriaSet = new CriteriaSet(); criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) ); @@ -107,9 +101,8 @@ public class AuthResponseBuilder { throw new InvalidAssertionEncryptionException(); } - - boolean isEncryptionActive = AuthConfigurationProviderFactory.getInstance().isPVP2AssertionEncryptionActive(); - if (encryptionCredentials != null && isEncryptionActive) { + + if (encryptionCredentials != null && enableEncryption) { //encrypt SAML2 assertion try { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java index 23ea4d7ee..c48caed29 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java @@ -23,30 +23,29 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.builder; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import org.opensaml.saml2.core.Attribute; - -import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder; -import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator; +import org.opensaml.saml2.metadata.RequestedAttribute; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.data.IAuthData; - +import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder; +import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.SamlAttributeGenerator; - import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.InvalidDateFormatAttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.NoMandateDataAttributeException; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.UnavailableAttributeException; - import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidDateFormatException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMandateDataAvailableException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.UnprovideableAttributeException; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; public class PVPAttributeBuilder { @@ -148,4 +147,61 @@ public class PVPAttributeBuilder { return attributes; } + public static RequestedAttribute buildReqAttribute(String name, String friendlyName, boolean required) { + RequestedAttribute attribute = SAML2Utils.createSAMLObject(RequestedAttribute.class); + attribute.setIsRequired(required); + attribute.setName(name); + attribute.setFriendlyName(friendlyName); + attribute.setNameFormat(Attribute.URI_REFERENCE); + return attribute; + } + + /** + * Build a set of PVP Response-Attributes + * <br><br> + * <b>INFO:</b> If a specific attribute can not be build, a info is logged, but no execpetion is thrown. + * Therefore, the return List must not include all requested attributes. + * + * @param authData AuthenticationData <code>IAuthData</code> which is used to build the attribute values, but never <code>null</code> + * @param reqAttributenName List of PVP attribute names which are requested, but never <code>null</code> + * @return List of PVP attributes, but never <code>null</code> + */ + public static List<Attribute> buildSetOfResponseAttributes(IAuthData authData, + Collection<String> reqAttributenName) { + List<Attribute> attrList = new ArrayList<Attribute>(); + if (reqAttributenName != null) { + Iterator<String> it = reqAttributenName.iterator(); + while (it.hasNext()) { + String reqAttributName = it.next(); + try { + Attribute attr = PVPAttributeBuilder.buildAttribute( + reqAttributName, null, authData); + if (attr == null) { + Logger.info( + "Attribute generation failed! for " + + reqAttributName); + + } else { + attrList.add(attr); + + } + + } catch (PVP2Exception e) { + Logger.info( + "Attribute generation failed! for " + + reqAttributName); + + } catch (Exception e) { + Logger.warn( + "General Attribute generation failed! for " + + reqAttributName, e); + + } + } + } + + return attrList; + } + + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java index 312bb823d..d5d84dd51 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java @@ -33,9 +33,11 @@ import org.opensaml.saml2.core.AuthnContextClassRef; import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.saml2.core.Issuer; +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.Subject; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.ws.message.encoder.MessageEncodingException; @@ -51,6 +53,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AuthnRequestBuildExce import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; /** * @author tlenz @@ -98,15 +101,23 @@ public class PVPAuthnRequestBuilder { if (endpoint == null) { Logger.warn("Building AuthnRequest FAILED: > Requested IDP " + idpEntity.getEntityID() + " does not support POST or Redirect Binding."); - throw new AuthnRequestBuildException("sp.pvp2.00", new Object[]{idpEntity.getEntityID()}); + throw new AuthnRequestBuildException("sp.pvp2.00", new Object[]{config.getSPNameForLogging(), idpEntity.getEntityID()}); } else authReq.setDestination(endpoint.getLocation()); //set basic AuthnRequest information - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - authReq.setID(gen.generateIdentifier()); + String reqID = config.getRequestID(); + if (MiscUtil.isNotEmpty(reqID)) + authReq.setID(reqID); + + else { + SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + authReq.setID(gen.generateIdentifier()); + + } + authReq.setIssueInstant(new DateTime()); //set isPassive flag @@ -148,7 +159,26 @@ public class PVPAuthnRequestBuilder { reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); authReq.setRequestedAuthnContext(reqAuthContext); } - + + //set request Subject element + if (MiscUtil.isNotEmpty(config.getSubjectNameID())) { + Subject reqSubject = SAML2Utils.createSAMLObject(Subject.class); + NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); + + subjectNameID.setValue(config.getSubjectNameID()); + if (MiscUtil.isNotEmpty(config.getSubjectNameIDQualifier())) + subjectNameID.setNameQualifier(config.getSubjectNameIDQualifier()); + + if (MiscUtil.isNotEmpty(config.getSubjectNameIDFormat())) + subjectNameID.setFormat(config.getSubjectNameIDFormat()); + else + subjectNameID.setFormat(NameID.TRANSIENT); + + reqSubject.setNameID(subjectNameID); + authReq.setSubject(reqSubject ); + + } + //TODO: implement requested attributes //maybe: config.getRequestedAttributes(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java index af22a2d7e..7a7044ebf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java @@ -66,7 +66,6 @@ import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationImpl; -import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder; @@ -86,45 +85,24 @@ import at.gv.egovernment.moa.util.MiscUtil; public class PVP2AssertionBuilder implements PVPConstants { - public static Assertion buildAssertion(IRequest pendingReq, AttributeQuery attrQuery, - List<String> reqAttributes, IAuthData authData, DateTime date, String sessionIndex) throws ConfigurationException { - - + /** + * Build a PVP assertion as response for a SAML2 AttributeQuery request + * + * @param issuerEntityID EnitiyID, which should be used for this IDP response + * @param attrQuery AttributeQuery request from Service-Provider + * @param attrList List of PVP response attributes + * @param now Current time + * @param validTo ValidTo time of the assertion + * @param qaaLevel QAA level of the authentication + * @param sessionIndex SAML2 SessionIndex, which should be included * + * @return PVP 2.1 Assertion + * @throws ConfigurationException + */ + public static Assertion buildAssertion(String issuerEntityID, AttributeQuery attrQuery, + List<Attribute> attrList, DateTime now, DateTime validTo, String qaaLevel, String sessionIndex) throws ConfigurationException { + AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - authnContextClassRef.setAuthnContextClassRef(authData.getQAALevel()); - - List<Attribute> attrList = new ArrayList<Attribute>(); - if (reqAttributes != null) { - Iterator<String> it = reqAttributes.iterator(); - while (it.hasNext()) { - String reqAttributName = it.next(); - try { - Attribute attr = PVPAttributeBuilder.buildAttribute( - reqAttributName, null, authData); - if (attr == null) { - Logger.error( - "Attribute generation failed! for " - + reqAttributName); - - } else { - attrList.add(attr); - - } - - } catch (PVP2Exception e) { - Logger.error( - "Attribute generation failed! for " - + reqAttributName); - - } catch (Exception e) { - Logger.error( - "General Attribute generation failed! for " - + reqAttributName, e); - - } - } - } - + authnContextClassRef.setAuthnContextClassRef(qaaLevel); NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat()); @@ -132,17 +110,31 @@ public class PVP2AssertionBuilder implements PVPConstants { SubjectConfirmationData subjectConfirmationData = null; - return buildGenericAssertion(pendingReq.getAuthURL(), attrQuery.getIssuer().getValue(), date, + return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, - new DateTime(authData.getSsoSessionValidTo().getTime())); + validTo); } - - public static Assertion buildAssertion(PVPTargetConfiguration pendingReq, AuthnRequest authnRequest, + + + /** + * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest + * + * @param issuerEntityID EnitiyID, which should be used for this IDP response + * @param pendingReq Current processed pendingRequest DAO + * @param authnRequest Current processed PVP AuthnRequest + * @param authData AuthenticationData of the user, which is already authenticated + * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response + * @param date TimeStamp + * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used + * @param sloInformation Single LogOut information DAO + * @return + * @throws MOAIDException + */ + public static Assertion buildAssertion(String issuerEntityID, PVPTargetConfiguration pendingReq, AuthnRequest authnRequest, IAuthData authData, EntityDescriptor peerEntity, DateTime date, AssertionConsumerService assertionConsumerService, SLOInformationImpl sloInformation) throws MOAIDException { - RequestedAuthnContext reqAuthnContext = authnRequest .getRequestedAuthnContext(); @@ -282,36 +274,74 @@ public class PVP2AssertionBuilder implements PVPConstants { } NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - + //build nameID and nameID Format from moasession + //TODO: nameID generation if (authData.isUseMandate()) { - Element mandate = authData.getMandate(); - if(mandate == null) { - throw new NoMandateDataAvailableException(); - } - Mandate mandateObject = MandateBuilder.buildMandate(mandate); - if(mandateObject == null) { - throw new NoMandateDataAvailableException(); - } - CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); - PhysicalPersonType pysicalperson = mandateObject.getMandator().getPhysicalPerson(); + String bpktype = null; + String bpk = null; - IdentificationType id; - if(corporation != null && corporation.getIdentification().size() > 0) - id = corporation.getIdentification().get(0); - + Element mandate = authData.getMandate(); + if(mandate != null) { + Mandate mandateObject = MandateBuilder.buildMandate(mandate); + if(mandateObject == null) { + throw new NoMandateDataAvailableException(); + } + CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody(); + PhysicalPersonType pysicalperson = mandateObject.getMandator().getPhysicalPerson(); - else if (pysicalperson != null && pysicalperson.getIdentification().size() > 0) - id = pysicalperson.getIdentification().get(0); + IdentificationType id; + if(corporation != null && corporation.getIdentification().size() > 0) + id = corporation.getIdentification().get(0); + + + else if (pysicalperson != null && pysicalperson.getIdentification().size() > 0) + id = pysicalperson.getIdentification().get(0); + + else { + Logger.error("Failed to generate IdentificationType"); + throw new NoMandateDataAvailableException(); + } + + bpktype = id.getType(); + bpk = id.getValue().getValue(); + + } else { + Logger.debug("Read mandatpr bPK|baseID from PVP attributes ... "); + bpk = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME, String.class); + bpktype = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME, String.class); - else { - Logger.error("Failed to generate IdentificationType"); - throw new NoMandateDataAvailableException(); + if (MiscUtil.isEmpty(bpk)) { + //no sourcePin is included --> search for bPK + bpk = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_BPK_NAME, String.class); + + //set bPK-Type from configuration, because it MUST be equal to service-provider type + if (oaParam.getBusinessService()) { + if (oaParam.getIdentityLinkDomainIdentifier().startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) + bpktype = oaParam.getIdentityLinkDomainIdentifier(); + else + bpktype = Constants.URN_PREFIX_WBPK + "+" + oaParam.getIdentityLinkDomainIdentifier(); + + } else { + if (oaParam.getTarget().startsWith(Constants.URN_PREFIX_CDID + "+")) + bpktype = oaParam.getTarget(); + else + bpktype = Constants.URN_PREFIX_CDID + "+" + oaParam.getTarget(); + + } + + } else { + //sourcePin is include --> check sourcePinType + if (MiscUtil.isEmpty(bpktype)) + bpktype = Constants.URN_PREFIX_BASEID; + + } } - - String bpktype = id.getType(); - String bpk = id.getValue().getValue(); + if (MiscUtil.isEmpty(bpk) || MiscUtil.isEmpty(bpktype)) { + throw new NoMandateDataAvailableException(); + + } if (bpktype.equals(Constants.URN_PREFIX_BASEID)) { if (oaParam.getBusinessService()) { @@ -334,7 +364,7 @@ public class PVP2AssertionBuilder implements PVPConstants { subjectNameID.setNameQualifier(bpktype); subjectNameID.setValue(bpk); } - + } else { subjectNameID.setNameQualifier(authData.getBPKType()); subjectNameID.setValue(authData.getBPK()); @@ -395,7 +425,10 @@ public class PVP2AssertionBuilder implements PVPConstants { subjectNameID.setValue(authData.getNameID()); sessionIndex = authData.getSessionIndex(); - } else + } + + // + if (MiscUtil.isEmpty(sessionIndex)) sessionIndex = SAML2Utils.getSecureIdentifier(); SubjectConfirmationData subjectConfirmationData = SAML2Utils @@ -410,7 +443,7 @@ public class PVP2AssertionBuilder implements PVPConstants { sloInformation.setNameIDFormat(subjectNameID.getFormat()); sloInformation.setSessionIndex(sessionIndex); - return buildGenericAssertion(pendingReq.getAuthURL(), peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter()); + return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter()); } /** diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IDPPVPMetadataConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IDPPVPMetadataConfiguration.java index e0994ff19..9a51e75e4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IDPPVPMetadataConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IDPPVPMetadataConfiguration.java @@ -285,4 +285,12 @@ public class IDPPVPMetadataConfiguration implements IPVPMetadataBuilderConfigura return null; } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPMetadataBuilderConfiguration#getSPNameForLogging() + */ + @Override + public String getSPNameForLogging() { + return "MOA-ID-Auth"; + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java index d51231044..6e1798ed1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java @@ -33,6 +33,13 @@ import org.opensaml.xml.security.credential.Credential; public interface IPVPAuthnRequestBuilderConfiguruation { /** + * Defines a unique name for this PVP Service-provider, which is used for logging + * + * @return + */ + public String getSPNameForLogging(); + + /** * If true, the SAML2 isPassive flag is set in the AuthnRequest * * @return @@ -110,5 +117,30 @@ public interface IPVPAuthnRequestBuilderConfiguruation { * @return SubjectNameID, or null if no SubjectNameID should be used */ public String getSubjectNameID(); + + /** + * Define the qualifier of the <code>SubjectNameID</code> + * <br><br> + * Like: 'urn:publicid:gv.at:cdid+BF' + * + * @return qualifier, or null if no qualifier should be set + */ + public String getSubjectNameIDQualifier(); + + /** + * Define the format of the subjectNameID, which is included in authn-request + * + * + * @return nameIDFormat, of SAML2 'transient' if nothing is defined + */ + public String getSubjectNameIDFormat(); + + /** + * Define a SP specific SAMK2 requestID + * + * @return requestID, or null if the requestID should be generated automatically + */ + public String getRequestID(); + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPMetadataBuilderConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPMetadataBuilderConfiguration.java index 52096fd19..56274535b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPMetadataBuilderConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPMetadataBuilderConfiguration.java @@ -40,6 +40,13 @@ public interface IPVPMetadataBuilderConfiguration { /** + * Defines a unique name for this PVP Service-provider, which is used for logging + * + * @return + */ + public String getSPNameForLogging(); + + /** * Set metadata valid area * * @return valid until in hours [h] diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java index bbf395a6f..58210a72c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java @@ -28,7 +28,6 @@ import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -92,18 +91,18 @@ public class PVPConfiguration { private static String moaIDVersion = null; //PVP2 generalpvpconfigdb; - Properties props; - String rootDir = null; + //Properties props; + //String rootDir = null; private PVPConfiguration() { - try { - //generalpvpconfigdb = AuthConfigurationProvider.getInstance().getGeneralPVP2DBConfig(); - props = AuthConfigurationProviderFactory.getInstance().getGeneralPVP2ProperiesConfig(); - rootDir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir(); - - } catch (ConfigurationException e) { - e.printStackTrace(); - } +// try { +// //generalpvpconfigdb = AuthConfigurationProvider.getInstance().getGeneralPVP2DBConfig(); +// //props = AuthConfigurationProviderFactory.getInstance().getGeneralPVP2ProperiesConfig(); +// //rootDir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir(); +// +// } catch (ConfigurationException e) { +// e.printStackTrace(); +// } } public List<String> getIDPPublicPath() throws ConfigurationException { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java new file mode 100644 index 000000000..3da4dc18a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.protocols.pvp2x.metadata; + +/** + * @author tlenz + * + */ +public interface IMOARefreshableMetadataProvider { + + /** + * Refresh a entity or load a entity in a metadata provider + * + * @param entityID + * @return true, if refresh is success, otherwise false + */ + public boolean refreshMetadataProvider(String entityID); +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java index 03fa686f9..618346485 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java @@ -31,12 +31,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Timer; -import javax.net.ssl.SSLHandshakeException; import javax.xml.namespace.QName; -import org.apache.commons.httpclient.MOAHttpClient; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.RoleDescriptor; @@ -47,20 +44,13 @@ import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; -import org.opensaml.xml.parse.BasicParserPool; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; -import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; -import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; -import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; -import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.InterfederatedIDPPublicServiceFilter; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.PVPMetadataFilterChain; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter; @@ -68,7 +58,8 @@ import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.MiscUtil; -public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbageCollectorProcessing { +public class MOAMetadataProvider extends SimpleMOAMetadataProvider + implements ObservableMetadataProvider, IGarbageCollectorProcessing, IMOARefreshableMetadataProvider { private static MOAMetadataProvider instance = null; private static Object mutex = new Object(); @@ -127,6 +118,7 @@ public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbage MetadataProvider internalProvider; + @Override public boolean refreshMetadataProvider(String entityID) { try { OAAuthParameter oaParam = @@ -151,10 +143,9 @@ public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbage String oaFriendlyName = oaParam.getFriendlyName(); ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL, - cert, oaFriendlyName, - buildMetadataFilterChain(oaParam, metadataURL, - cert)); + HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL, + buildMetadataFilterChain(oaParam, metadataURL, cert), + oaFriendlyName); chainProvider.addMetadataProvider(newMetadataProvider); @@ -264,11 +255,9 @@ public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbage Logger.info("Loading metadata for: " + oaFriendlyName); httpProvider = createNewHTTPMetaDataProvider( - metadataurl, - cert, - oaFriendlyName, - buildMetadataFilterChain(oaParam, metadataurl, - cert)); + metadataurl, + buildMetadataFilterChain(oaParam, metadataurl, cert), + oaFriendlyName); if (httpProvider != null) providersinuse.put(metadataurl, httpProvider); @@ -389,10 +378,8 @@ public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbage if (!providersinuse.containsKey(metadataurl)) { httpProvider = createNewHTTPMetaDataProvider( metadataurl, - cert, - oaFriendlyName, - buildMetadataFilterChain(oaParam, metadataurl, - cert)); + buildMetadataFilterChain(oaParam, metadataurl, cert), + oaFriendlyName); if (httpProvider != null) providersinuse.put(metadataurl, httpProvider); @@ -450,86 +437,7 @@ public class MOAMetadataProvider implements ObservableMetadataProvider, IGarbage return filterChain; } - - private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, byte[] certificate, String oaName, PVPMetadataFilterChain filter) { - HTTPMetadataProvider httpProvider = null; - Timer timer= null; - MOAHttpClient httpClient = null; - try { - httpClient = new MOAHttpClient(); - - if (metadataURL.startsWith("https:")) { - try { - MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory( - PVPConstants.SSLSOCKETFACTORYNAME, - AuthConfigurationProviderFactory.getInstance().getCertstoreDirectory(), - AuthConfigurationProviderFactory.getInstance().getTrustedCACertificates(), - null, - AuthConfiguration.DEFAULT_X509_CHAININGMODE, - AuthConfigurationProviderFactory.getInstance().isTrustmanagerrevoationchecking()); - - httpClient.setCustomSSLTrustStore(metadataURL, protoSocketFactory); - - } catch (MOAHttpProtocolSocketFactoryException e) { - Logger.warn("MOA SSL-TrustStore can not initialized. Use default Java TrustStore."); - - } - } - - timer = new Timer(); - httpProvider = new HTTPMetadataProvider(timer, httpClient, - metadataURL); - httpProvider.setParserPool(new BasicParserPool()); - httpProvider.setRequireValidMetadata(true); - httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes - httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours - //httpProvider.setRefreshDelayFactor(0.1F); - - if (filter == null) { - filter = new PVPMetadataFilterChain(metadataURL, certificate); - } - httpProvider.setMetadataFilter(filter); - httpProvider.initialize(); - - httpProvider.setRequireValidMetadata(true); - - return httpProvider; - - } catch (Throwable e) { - if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { - Logger.warn("SSL-Server certificate for metadata " - + metadataURL + " not trusted.", e); - - } if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) { - Logger.warn("Signature verification for metadata" - + metadataURL + " FAILED.", e); - - } if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) { - Logger.warn("Schema validation for metadata " - + metadataURL + " FAILED.", e); - } - - Logger.error( - "Failed to add Metadata file for " - + oaName + "[ " - + e.getMessage() + " ]", e); - - if (httpProvider != null) { - Logger.debug("Destroy failed Metadata provider"); - httpProvider.destroy(); - } - - if (timer != null) { - Logger.debug("Destroy Timer."); - timer.cancel(); - } - - - } - return null; - } - public boolean requireValidMetadata() { return internalProvider.requireValidMetadata(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java new file mode 100644 index 000000000..6d646c609 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java @@ -0,0 +1,135 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.protocols.pvp2x.metadata; + +import java.util.Timer; + +import javax.net.ssl.SSLHandshakeException; + +import org.apache.commons.httpclient.MOAHttpClient; +import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.xml.parse.BasicParserPool; + +import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; +import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ + + /** + * Create a single SAML2 HTTP metadata provider + * + * @param metadataURL URL, where the metadata should be loaded + * @param filter Filters, which should be used to validate the metadata + * @param IdForLogging Id, which is used for Logging + * + * @return SAML2 Metadata Provider + */ + protected HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, MetadataFilter filter, String IdForLogging ) { + HTTPMetadataProvider httpProvider = null; + Timer timer= null; + MOAHttpClient httpClient = null; + try { + httpClient = new MOAHttpClient(); + + if (metadataURL.startsWith("https:")) { + try { + MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory( + PVPConstants.SSLSOCKETFACTORYNAME, + AuthConfigurationProviderFactory.getInstance().getCertstoreDirectory(), + AuthConfigurationProviderFactory.getInstance().getTrustedCACertificates(), + null, + AuthConfiguration.DEFAULT_X509_CHAININGMODE, + AuthConfigurationProviderFactory.getInstance().isTrustmanagerrevoationchecking()); + + httpClient.setCustomSSLTrustStore(metadataURL, protoSocketFactory); + + } catch (MOAHttpProtocolSocketFactoryException e) { + Logger.warn("MOA SSL-TrustStore can not initialized. Use default Java TrustStore."); + + } + } + + timer = new Timer(); + httpProvider = new HTTPMetadataProvider(timer, httpClient, + metadataURL); + httpProvider.setParserPool(new BasicParserPool()); + httpProvider.setRequireValidMetadata(true); + httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes + httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours + //httpProvider.setRefreshDelayFactor(0.1F); + + httpProvider.setMetadataFilter(filter); + httpProvider.initialize(); + + httpProvider.setRequireValidMetadata(true); + + return httpProvider; + + } catch (Throwable e) { + if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { + Logger.warn("SSL-Server certificate for metadata " + + metadataURL + " not trusted.", e); + + } if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) { + Logger.warn("Signature verification for metadata" + + metadataURL + " FAILED.", e); + + } if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) { + Logger.warn("Schema validation for metadata " + + metadataURL + " FAILED.", e); + } + + Logger.error( + "Failed to load Metadata file for " + + IdForLogging + "[ " + + e.getMessage() + " ]", e); + + if (httpProvider != null) { + Logger.debug("Destroy failed Metadata provider"); + httpProvider.destroy(); + } + + if (timer != null) { + Logger.debug("Destroy Timer."); + timer.cancel(); + } + + + } + + return null; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java index 9c294245f..106be8a09 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java @@ -24,9 +24,12 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.utils; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Attribute; @@ -51,9 +54,18 @@ public class AssertionAttributeExtractor { private final List<String> minimalAttributeNameList = Arrays.asList( PVPConstants.PRINCIPAL_NAME_NAME, - PVPConstants.GIVEN_NAME_NAME); - - + PVPConstants.GIVEN_NAME_NAME, + PVPConstants.ENC_BPK_LIST_NAME, + PVPConstants.BPK_NAME); + + /** + * Parse the SAML2 Response element and extracts included information + * <br><br> + * <b>INFO:</b> Actually, only the first SAML2 Assertion of the SAML2 Response is used! + * + * @param samlResponse SAML2 Response + * @throws AssertionAttributeExtractorExeption + */ public AssertionAttributeExtractor(StatusResponseType samlResponse) throws AssertionAttributeExtractorExeption { if (samlResponse != null && samlResponse instanceof Response) { List<Assertion> assertions = ((Response) samlResponse).getAssertions(); @@ -95,6 +107,27 @@ public class AssertionAttributeExtractor { } /** + * Get all SAML2 attributes from first SAML2 AttributeStatement element + * + * @return List of SAML2 Attributes + */ + public List<Attribute> getAllResponseAttributesFromFirstAttributeStatement() { + return assertion.getAttributeStatements().get(0).getAttributes(); + + } + + /** + * Get all SAML2 attributes of specific SAML2 AttributeStatement element + * + * @param attrStatementID List ID of the AttributeStatement element + * @return List of SAML2 Attributes + */ + public List<Attribute> getAllResponseAttributes(int attrStatementID) { + return assertion.getAttributeStatements().get(attrStatementID).getAttributes(); + + } + + /** * check attributes from assertion with minimal required attribute list * @return */ @@ -105,33 +138,33 @@ public class AssertionAttributeExtractor { /** * check attributes from assertion with attributeNameList - * bPK or enc_bPK is always needed + * bPK or enc_bPK are always needed * * @param List of attributes which are required * * @return */ - public boolean containsAllRequiredAttributes(List<String> attributeNameList) { + public boolean containsAllRequiredAttributes(Collection<String> attributeNameList) { //first check if a bPK or an encrypted bPK is available - if (attributs.containsKey(PVPConstants.ENC_BPK_LIST_NAME) || - (attributs.containsKey(PVPConstants.BPK_NAME))) { - boolean flag = true; - for (String attr : attributeNameList) { - if (!attributs.containsKey(attr)) { - flag = false; - Logger.debug("Assertion contains no Attribute " + attr); - - } - + boolean flag = true; + for (String attr : attributeNameList) { + if (!attributs.containsKey(attr)) { + flag = false; + Logger.debug("Assertion contains no Attribute " + attr); + } - - return flag; - + } - Logger.debug("Assertion contains no bPK or encryptedbPK."); - return false; + if (flag) + return flag; + + else { + Logger.debug("Assertion contains no bPK or encryptedbPK."); + return false; + + } } public boolean containsAttribute(String attributeName) { @@ -152,6 +185,16 @@ public class AssertionAttributeExtractor { } + /** + * Return all include PVP attribute names + * + * @return + */ + public Set<String> getAllIncludeAttributeNames() { + return attributs.keySet(); + + } + // public PersonalAttributeList getSTORKAttributes() { // return storkAttributes; // } @@ -206,6 +249,29 @@ public class AssertionAttributeExtractor { return assertion; } + + /** + * Get the Assertion validTo period + * + * Primarily, the 'SessionNotOnOrAfter' attribute in the SAML2 'AuthnStatment' element is used. + * If this is empty, this method returns value of SAML 'Conditions' element. + * + * @return Date, until this SAML2 assertion is valid + */ + public Date getAssertionNotOnOrAfter() { + if (getFullAssertion().getAuthnStatements() != null + && getFullAssertion().getAuthnStatements().size() > 0) { + for (AuthnStatement el : getFullAssertion().getAuthnStatements()) { + if (el.getSessionNotOnOrAfter() != null) + return (el.getSessionNotOnOrAfter().toDate()); + } + + } + + return getFullAssertion().getConditions().getNotOnOrAfter().toDate(); + + } + private AuthnStatement getAuthnStatement() throws AssertionAttributeExtractorExeption { List<AuthnStatement> authnList = assertion.getAuthnStatements(); if (authnList.size() == 0) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java index f62410656..86ca591ee 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java @@ -139,7 +139,7 @@ public abstract class AbstractRequestSignedSecurityPolicyRule implements Securit throw new SecurityPolicyException("Signature validation FAILED."); } - Logger.debug("PVP AuthnRequest signature valid."); + Logger.debug("PVP message signature valid."); } catch (org.opensaml.xml.security.SecurityException e) { Logger.info("PVP2x message signature validation FAILED. Message:" + e.getMessage()); @@ -148,7 +148,7 @@ public abstract class AbstractRequestSignedSecurityPolicyRule implements Securit } } else { - throw new SecurityPolicyException("Request is not signed."); + throw new SecurityPolicyException("PVP Message is not signed."); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java index 932f3b818..7b3f890e9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java @@ -25,10 +25,12 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.validation; import javax.xml.namespace.QName; import org.opensaml.common.SignableSAMLObject; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.xml.XMLObject; import org.opensaml.xml.signature.SignatureTrustEngine; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IMOARefreshableMetadataProvider; +import at.gv.egovernment.moa.logging.Logger; /** * @author tlenz @@ -37,13 +39,19 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; public class MOAPVPSignedRequestPolicyRule extends AbstractRequestSignedSecurityPolicyRule { + private IMOARefreshableMetadataProvider metadataProvider = null; + /** + * @param metadataProvider * @param trustEngine * @param peerEntityRole */ - public MOAPVPSignedRequestPolicyRule(SignatureTrustEngine trustEngine, + public MOAPVPSignedRequestPolicyRule(MetadataProvider metadataProvider, SignatureTrustEngine trustEngine, QName peerEntityRole) { super(trustEngine, peerEntityRole); + if (metadataProvider instanceof IMOARefreshableMetadataProvider) + this.metadataProvider = (IMOARefreshableMetadataProvider) metadataProvider; + } /* (non-Javadoc) @@ -51,7 +59,10 @@ public class MOAPVPSignedRequestPolicyRule extends */ @Override protected boolean refreshMetadataProvider(String entityID) { - return MOAMetadataProvider.getInstance().refreshMetadataProvider(entityID); + if (metadataProvider != null) + return metadataProvider.refreshMetadataProvider(entityID); + + return false; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java index 5e44c9057..f384dd511 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java @@ -22,50 +22,30 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.verification; -import java.util.ArrayList; -import java.util.List; - import javax.xml.namespace.QName; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.Validator; -import org.joda.time.DateTime; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.common.xml.SAMLSchemaBuilder; -import org.opensaml.saml2.core.Conditions; -import org.opensaml.saml2.core.EncryptedAssertion; import org.opensaml.saml2.core.RequestAbstractType; -import org.opensaml.saml2.core.Response; -import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusResponseType; -import org.opensaml.saml2.encryption.Decrypter; -import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver; import org.opensaml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.security.MetadataCriteria; import org.opensaml.security.SAMLSignatureProfileValidator; -import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver; -import org.opensaml.xml.encryption.DecryptionException; -import org.opensaml.xml.encryption.InlineEncryptedKeyResolver; -import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver; import org.opensaml.xml.security.CriteriaSet; -import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.security.credential.UsageType; import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.criteria.UsageCriteria; -import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.validation.ValidationException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException; -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; -import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SchemaValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; @@ -77,8 +57,6 @@ import at.gv.egovernment.moa.util.MiscUtil; @Service("SAMLVerificationEngine") public class SAMLVerificationEngine { - @Autowired AuthConfiguration authConfig; - public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { try { if (msg instanceof MOARequest && @@ -181,111 +159,8 @@ public class SAMLVerificationEngine { throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); } } - - public void validateAssertion(Response samlResp, boolean validateDestination, Credential assertionDecryption) throws AssertionValidationExeption { - try { - if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { - List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); - - //validate destination URL - List<String> allowedPublicURLPrefix = authConfig.getPublicURLPrefix(); - boolean isValidDestination = false; - for (String allowedPreFix : allowedPublicURLPrefix) { - if (validateDestination && samlResp.getDestination().startsWith( - allowedPreFix)) { - isValidDestination = true; - break; - - } - } - if (!isValidDestination && validateDestination) { - Logger.warn("PVP 2.1 assertion destination does not match to IDP URL"); - throw new AssertionValidationExeption("PVP 2.1 assertion destination does not match to IDP URL", null); - - } - - //check encrypted Assertion - List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions(); - if (encryAssertionList != null && encryAssertionList.size() > 0) { - //decrypt assertions - - Logger.debug("Found encryped assertion. Start decryption ..."); - - StaticKeyInfoCredentialResolver skicr = - new StaticKeyInfoCredentialResolver(assertionDecryption); - - ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); - encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() ); - encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() ); - encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() ); - - Decrypter samlDecrypter = - new Decrypter(null, skicr, encryptedKeyResolver); - - for (EncryptedAssertion encAssertion : encryAssertionList) { - saml2assertions.add(samlDecrypter.decrypt(encAssertion)); - - } - - Logger.debug("Assertion decryption finished. "); - - } else { - saml2assertions.addAll(samlResp.getAssertions()); - - } - - List<org.opensaml.saml2.core.Assertion> validatedassertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); - for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { - - try { - performSchemaValidation(saml2assertion.getDOM()); - - Conditions conditions = saml2assertion.getConditions(); - DateTime notbefore = conditions.getNotBefore().minusMinutes(5); - DateTime notafter = conditions.getNotOnOrAfter(); - if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) { - Logger.warn("PVP2 Assertion is out of Date. " - + "{ Current : " + new DateTime() - + " NotBefore: " + notbefore - + " NotAfter : " + notafter - + " }");; - - } else { - validatedassertions.add(saml2assertion); - - } - - } catch (SchemaValidationException e) { - - } - } - - if (validatedassertions.isEmpty()) { - Logger.info("No valid PVP 2.1 assertion received."); - throw new AssertionValidationExeption("No valid PVP 2.1 assertion received.", null); - } - - samlResp.getAssertions().clear(); - samlResp.getEncryptedAssertions().clear(); - samlResp.getAssertions().addAll(validatedassertions); - - } else { - Logger.info("PVP 2.1 assertion includes an error. Receive errorcode " - + samlResp.getStatus().getStatusCode().getValue()); - throw new AssertionValidationExeption("PVP 2.1 assertion includes an error. Receive errorcode " - + samlResp.getStatus().getStatusCode().getValue(), null); - } - - } catch (DecryptionException e) { - Logger.warn("Assertion decrypt FAILED.", e); - throw new AssertionValidationExeption("Assertion decrypt FAILED.", null, e); - - } catch (ConfigurationException e) { - throw new AssertionValidationExeption("pvp.12", null, e); - } - } - - private void performSchemaValidation(Element source) throws SchemaValidationException { + + protected void performSchemaValidation(Element source) throws SchemaValidationException { String err = null; try { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java new file mode 100644 index 000000000..cd80d8c24 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java @@ -0,0 +1,161 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.protocols.pvp2x.verification; + +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.DateTime; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.EncryptedAssertion; +import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.encryption.Decrypter; +import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver; +import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver; +import org.opensaml.xml.encryption.DecryptionException; +import org.opensaml.xml.encryption.InlineEncryptedKeyResolver; +import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SchemaValidationException; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@Service("SAMLVerificationEngineSP") +public class SAMLVerificationEngineSP extends SAMLVerificationEngine { + + @Autowired AuthConfiguration authConfig; + + public void validateAssertion(Response samlResp, boolean validateDestination, Credential assertionDecryption) throws AssertionValidationExeption { + try { + if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); + + //validate destination URL + List<String> allowedPublicURLPrefix = authConfig.getPublicURLPrefix(); + boolean isValidDestination = false; + for (String allowedPreFix : allowedPublicURLPrefix) { + if (validateDestination && samlResp.getDestination().startsWith( + allowedPreFix)) { + isValidDestination = true; + break; + + } + } + if (!isValidDestination && validateDestination) { + Logger.warn("PVP 2.1 assertion destination does not match to IDP URL"); + throw new AssertionValidationExeption("PVP 2.1 assertion destination does not match to IDP URL", null); + + } + + //check encrypted Assertion + List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions(); + if (encryAssertionList != null && encryAssertionList.size() > 0) { + //decrypt assertions + + Logger.debug("Found encryped assertion. Start decryption ..."); + + StaticKeyInfoCredentialResolver skicr = + new StaticKeyInfoCredentialResolver(assertionDecryption); + + ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); + encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() ); + + Decrypter samlDecrypter = + new Decrypter(null, skicr, encryptedKeyResolver); + + for (EncryptedAssertion encAssertion : encryAssertionList) { + saml2assertions.add(samlDecrypter.decrypt(encAssertion)); + + } + + Logger.debug("Assertion decryption finished. "); + + } else { + saml2assertions.addAll(samlResp.getAssertions()); + + } + + List<org.opensaml.saml2.core.Assertion> validatedassertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); + for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { + + try { + performSchemaValidation(saml2assertion.getDOM()); + + Conditions conditions = saml2assertion.getConditions(); + DateTime notbefore = conditions.getNotBefore().minusMinutes(5); + DateTime notafter = conditions.getNotOnOrAfter(); + if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) { + Logger.warn("PVP2 Assertion is out of Date. " + + "{ Current : " + new DateTime() + + " NotBefore: " + notbefore + + " NotAfter : " + notafter + + " }");; + + } else { + validatedassertions.add(saml2assertion); + + } + + } catch (SchemaValidationException e) { + + } + } + + if (validatedassertions.isEmpty()) { + Logger.info("No valid PVP 2.1 assertion received."); + throw new AssertionValidationExeption("No valid PVP 2.1 assertion received.", null); + } + + samlResp.getAssertions().clear(); + samlResp.getEncryptedAssertions().clear(); + samlResp.getAssertions().addAll(validatedassertions); + + } else { + Logger.info("PVP 2.1 assertion includes an error. Receive errorcode " + + samlResp.getStatus().getStatusCode().getValue()); + throw new AssertionValidationExeption("PVP 2.1 assertion includes an error. Receive errorcode " + + samlResp.getStatus().getStatusCode().getValue(), null); + } + + } catch (DecryptionException e) { + Logger.warn("Assertion decrypt FAILED.", e); + throw new AssertionValidationExeption("Assertion decrypt FAILED.", null, e); + + } catch (ConfigurationException e) { + throw new AssertionValidationExeption("pvp.12", null, e); + } + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/TrustEngineFactory.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/TrustEngineFactory.java index 67a91f6e1..3ea124db6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/TrustEngineFactory.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/TrustEngineFactory.java @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.verification; import java.util.ArrayList; import java.util.List; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.security.MetadataCredentialResolver; import org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver; import org.opensaml.xml.security.keyinfo.KeyInfoCredentialResolver; @@ -35,8 +36,6 @@ import org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine; //import org.opensaml.xml.signature.impl.PKIXSignatureTrustEngine; - -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; //import edu.internet2.middleware.shibboleth.common.security.MetadataPKIXValidationInformationResolver; public class TrustEngineFactory { @@ -65,11 +64,10 @@ public class TrustEngineFactory { // } // } - public static SignatureTrustEngine getSignatureKnownKeysTrustEngine() { + public static SignatureTrustEngine getSignatureKnownKeysTrustEngine(MetadataProvider provider) { MetadataCredentialResolver resolver; - resolver = new MetadataCredentialResolver( - MOAMetadataProvider.getInstance()); + resolver = new MetadataCredentialResolver(provider); List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); keyInfoProvider.add(new DSAKeyValueProvider()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java new file mode 100644 index 000000000..f67c475bb --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java @@ -0,0 +1,130 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata; + +import java.io.IOException; +import java.io.StringWriter; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.provider.FilterException; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.xml.XMLObject; + +import at.gv.egovernment.moa.id.auth.builder.SignatureVerificationUtils; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class MOASPMetadataSignatureFilter implements MetadataFilter { + + private String trustProfileID = null; + + /** + * + */ + public MOASPMetadataSignatureFilter(String trustProfileID) { + this.trustProfileID = trustProfileID; + + } + + + /* (non-Javadoc) + * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) + */ + @Override + public void doFilter(XMLObject metadata) throws FilterException { + if (metadata instanceof EntityDescriptor) { + if (((EntityDescriptor) metadata).isSigned()) { + EntityDescriptor entityDes = (EntityDescriptor) metadata; + //check signature; + try { + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult sr = new StreamResult(sw); + DOMSource source = new DOMSource(metadata.getDOM()); + transformer.transform(source, sr); + sw.close(); + String metadataXML = sw.toString(); + + SignatureVerificationUtils sigVerify = + new SignatureVerificationUtils(); + VerifyXMLSignatureResponse result = sigVerify.verify( + metadataXML.getBytes(), trustProfileID); + + //check signature-verification result + if (result.getSignatureCheckCode() != 0) { + Logger.warn("Metadata signature-verification FAILED!" + + " Metadata: " + entityDes.getEntityID() + + " StatusCode:" + result.getSignatureCheckCode()); + throw new FilterException("Metadata signature-verification FAILED!" + + " Metadata: " + entityDes.getEntityID() + + " StatusCode:" + result.getSignatureCheckCode()); + + } + + if (result.getCertificateCheckCode() != 0) { + Logger.warn("Metadata certificate-verification FAILED!" + + " Metadata: " + entityDes.getEntityID() + + " StatusCode:" + result.getCertificateCheckCode()); + throw new FilterException("Metadata certificate-verification FAILED!" + + " Metadata: " + entityDes.getEntityID() + + " StatusCode:" + result.getCertificateCheckCode()); + + } + + + } catch (MOAIDException | TransformerFactoryConfigurationError | TransformerException | IOException e) { + Logger.error("Metadata verification has an interal error.", e); + throw new FilterException("Metadata verification has an interal error." + + " Message:" + e.getMessage()); + + } + + + } else { + Logger.warn("Metadata root-element MUST be signed."); + throw new FilterException("Metadata root-element MUST be signed.'"); + + } + + } else { + Logger.warn("Metadata root-element is not of type 'EntityDescriptor'"); + throw new FilterException("Metadata root-element is not of type 'EntityDescriptor'"); + + } + + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/SchemaValidationFilter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/SchemaValidationFilter.java index 1aca587c9..69fe0ee6a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/SchemaValidationFilter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/SchemaValidationFilter.java @@ -22,16 +22,13 @@ */ package at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata; -import org.opensaml.saml2.metadata.provider.FilterException; -import org.opensaml.saml2.metadata.provider.MetadataFilter; -import org.opensaml.xml.XMLObject; - import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.Validator; import org.opensaml.common.xml.SAMLSchemaBuilder; - +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.xml.XMLObject; import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.config.ConfigurationException; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java index cfdb4426b..10594d6fc 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java @@ -53,9 +53,7 @@ import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.EncryptedData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IRequest; -import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; -import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SessionEncrytionUtil; @@ -95,9 +93,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt Date now = new Date(); dbsession.setCreated(now); dbsession.setUpdated(now); - - dbsession.setPendingRequestID(target.getRequestID()); - + //set additional session informations AuthenticationSessionExtensions sessionExt = new AuthenticationSessionExtensions(); sessionExt.setUniqueSessionId(target.getUniqueSessionIdentifier()); @@ -461,7 +457,6 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt dbsession.setSSOSession(true); dbsession.setSSOsessionid(SSOSessionID); dbsession.setAuthenticated(false); - dbsession.setPendingRequestID("empty"); //Store MOASession session.saveOrUpdate(dbsession); @@ -751,7 +746,8 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } } - public void createInterfederatedSession(IRequest req, boolean isAuthenticated) throws MOADatabaseException, AssertionAttributeExtractorExeption, BuildException { + @Override + public void addFederatedSessionInformation(IRequest req, String idpEntityID, AssertionAttributeExtractor extractor) throws MOADatabaseException, AssertionAttributeExtractorExeption, BuildException { AuthenticatedSessionStore dbsession = null; Date now = new Date(); @@ -766,23 +762,27 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt throw e; } } + + dbsession.setUpdated(now); + //decrypt MOASession AuthenticationSession session = decryptSession(dbsession); - //set Session parameters - session.setAuthenticated(isAuthenticated); - dbsession.setAuthenticated(isAuthenticated); - dbsession.setInterfederatedSSOSession(true); - dbsession.setUpdated(now); - + //federated Session are never authenticated locally, + // because they get always authentication information from federated IDP + session.setAuthenticated(false); + dbsession.setAuthenticated(false); + + //encrypt MOASession encryptSession(session, dbsession); + + //mark as federated SSO session + dbsession.setInterfederatedSSOSession(true); //add interfederation information List<InterfederationSessionStore> idpList = dbsession.getInderfederation(); - - MOAResponse interfederationResp = req.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_RESPONSE, MOAResponse.class); - String interFedEntityID = interfederationResp.getEntityID(); - + + //check if federated IDP is already stored InterfederationSessionStore idp = null; if (idpList == null) { idpList = new ArrayList<InterfederationSessionStore>(); @@ -791,7 +791,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } else { for (InterfederationSessionStore el : idpList) { //resue old entry if interfederation IDP is reused for authentication - if (el.getIdpurlprefix().equals(interFedEntityID)) + if (el.getIdpurlprefix().equals(idpEntityID)) idp = el; } @@ -801,7 +801,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt if (idp == null) { idp = new InterfederationSessionStore(); idp.setCreated(now); - idp.setIdpurlprefix(interFedEntityID); + idp.setIdpurlprefix(idpEntityID); idp.setAuthURL(req.getAuthURL()); OAAuthParameter oa = authConfig.getOnlineApplicationParameter(idp.getIdpurlprefix()); @@ -809,12 +809,11 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt idp.setMoasession(dbsession); idpList.add(idp); - } - AssertionAttributeExtractor extract = new AssertionAttributeExtractor(interfederationResp.getResponse()); - idp.setSessionIndex(extract.getSessionIndex()); - idp.setUserNameID(extract.getNameID()); + } + idp.setSessionIndex(extractor.getSessionIndex()); + idp.setUserNameID(extractor.getNameID()); idp.setAttributesRequested(false); - idp.setQAALevel(extract.getQAALevel()); + idp.setQAALevel(extractor.getQAALevel()); //store AssertionStore element to Database try { @@ -828,9 +827,9 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } @Override - public InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(AuthenticationSession moaSession) { - MiscUtil.assertNotNull(moaSession, "MOASession"); - Logger.trace("Get interfederated IDP for AttributeQuery with sessionID " + moaSession.getSessionID() + " from database."); + public InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(String moaSessionID) { + MiscUtil.assertNotNull(moaSessionID, "MOASessionID"); + Logger.trace("Get interfederated IDP for AttributeQuery with sessionID " + moaSessionID + " from database."); Session session = MOASessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; @@ -839,7 +838,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt synchronized (session) { tx = session.beginTransaction(); Query query = session.getNamedQuery("getInterfederatedIDPForAttributeQueryWithSessionID"); - query.setParameter("sessionID", moaSession.getSessionID()); + query.setParameter("sessionID", moaSessionID); result = query.list(); //send transaction @@ -1024,4 +1023,5 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt throw e; } } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java index 2fd540a67..666511425 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java @@ -36,6 +36,7 @@ import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; /** * @author tlenz @@ -238,24 +239,24 @@ public interface IAuthenticationSessionStoreage { /** - * Create a MOASession from interfederation information + * Add information of the federated IDP to MOASession * - * @param req Pending request - * @param isAuthenticated true if the session should be marked as authenticated, otherwise false + * @param req Pending request of the service-provider request, never null + * @param idpEntityID The SAML2 EntityID of the federated IDP, never null + * @param extractor <code>AssertionAttributeExtractor</code> which holds the SAML2 response of the federated IDP, never null * @throws MOADatabaseException * @throws AssertionAttributeExtractorExeption * @throws BuildException */ - @Deprecated - public void createInterfederatedSession(IRequest req, boolean isAuthenticated) throws MOADatabaseException, AssertionAttributeExtractorExeption, BuildException; + public void addFederatedSessionInformation(IRequest req, String idpEntityID, AssertionAttributeExtractor extractor) throws MOADatabaseException, AssertionAttributeExtractorExeption, BuildException; /** * Search an active federation IDP which could be used for federated Single Sign-On by using an AttributeQuery * - * @param moaSession MOASession data object + * @param moaSessionID ID of a active MOASession * @return Information of the federated IDP, or null if no active federated IDP is found */ - public InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(AuthenticationSession moaSession); + public InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(String moaSessionID); /** * Remove an active federation IDP from MOASession diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java index 22a021d99..07679999b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/Random.java @@ -47,10 +47,17 @@ package at.gv.egovernment.moa.id.util; -import iaik.security.random.SeedGenerator; - import java.nio.ByteBuffer; import java.security.SecureRandom; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.commons.codec.binary.Hex; + +import com.google.common.primitives.Bytes; + +import iaik.security.random.SeedGenerator; /** @@ -60,37 +67,97 @@ import java.security.SecureRandom; */ public class Random { + + private final static char[] allowedPreFix = + {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; + private static final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM"); + /** random number generator used */ //private static SecureRandom random = new SecureRandom(); private static SecureRandom random; - private static SeedGenerator seedgenerator; - + private static SeedGenerator seedgenerator; + static { random = iaik.security.random.SHA256FIPS186Random.getDefault(); seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault(); - } + + /** + * Generate a unique process reference-value [160bit], which always starts with a letter + * <br> + * This unique ID consists of single letter, a 64bit date String[yyyyddMM], + * and a 88bit random value. + * + * @return 160bit ID, which is hex encoded + */ + public static String nextProcessReferenceValue() { + //pre-process all three parts of a unique reference value + String now = dateFormater.format(new Date()); //8 bytes = 64bit + byte[] randValue = nextByteRandom(11); + char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)]; + + //generate ID + return preFix + new String(Hex.encodeHex(Bytes.concat(now.getBytes(), randValue), true)); // 20 bytes = 160 bits + + } + + + + /** + * Creates a new random number [256bit], and encode it as hex value. + * + * @return random hex encoded value [256bit] + */ + public static String nextHexRandom() { + return new String(Hex.encodeHex(nextByteRandom(32), true)); // 32 bytes = 256 bits + + } + + /** + * Creates a new random number [64bit], to be used as an ID. + * + * @return random long as a String [64bit] + */ + public static String nextLongRandom() { + return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits + + } + /** * Creates a new random number, to be used as an ID. * - * @return random long as a String + * @return random long as a String [64bit] */ - public static String nextRandom() { - - byte[] b = new byte[32]; // 32 bytes = 256 bits - random.nextBytes(b); - - ByteBuffer bb = ByteBuffer.wrap(b); - long l = bb.getLong(); + @Deprecated + public static String nextRandom() { + long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits return "" + Math.abs(l); - } + public static void seedRandom() { if (seedgenerator.seedAvailable()) random.setSeed(seedgenerator.getSeed()); } + + private static long generateLongRandom(int size) { + return ByteBuffer.wrap(nextByteRandom(size)).getLong(); + } + + /** + * Generate a new random number + * + * @param size Size of random number in bits + * @return + */ + private static byte[] nextByteRandom(int size) { + byte[] b = new byte[size]; + random.nextBytes(b); + return b; + + } } diff --git a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder index bb98bcc6f..8e5d6ee3c 100644 --- a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder +++ b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeBuilder @@ -28,3 +28,4 @@ at.gv.egovernment.moa.id.protocols.builder.attributes.MandateReferenceValueAttri at.gv.egovernment.moa.id.protocols.builder.attributes.MandateTypeAttributeBuilder at.gv.egovernment.moa.id.protocols.builder.attributes.PrincipalNameAttributeBuilder at.gv.egovernment.moa.id.protocols.builder.attributes.PVPVersionAttributeBuilder +at.gv.egovernment.moa.id.protocols.builder.attributes.HolderOfKey diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 50d01ce2f..a53d7e920 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -44,10 +44,14 @@ auth.23=Das BKU-Selektion Template entspricht nicht der Spezifikation von MOA-ID auth.24=Das Send-Assertion Template entspricht nicht der Spezifikation von MOA-ID 2.x.
auth.25=Fehler beim validieren der SZR-Gateway Response.
auth.26=SessionID unbekannt.
-auth.27=Federated authentication FAILED! Assertion from {0} IDP is not valid.
+auth.27=Federated authentication FAILED! Assertion from {0} IDP is not valid. (Msg:{1})
auth.28=Transaktion {0} kann nicht weitergef\u00FChrt werden. Wahrscheinlich wurde ein TimeOut erreicht.
auth.29=Federated authentication FAILED! Can not build authentication request for IDP {0}
auth.30=No valid Single Sign-On session found. Authentication process is aborted.
+auth.31=Federated authentication FAILED. No information for AttributeQuery, maybe a timeout occures.
+auth.32=Federated authentication FAILED. No configuration for IDP {0}
+auth.33=Federated authentication FAILED. Configuration of IDP {0} does not allow inbound messages.
+auth.34=Federated authentication FAILED. Configuration of IDP {0} is marked as BusinessService-IDP, but Public-Service attributes are requested.
init.00=MOA ID Authentisierung wurde erfolgreich gestartet
init.01=Fehler beim Aktivieren des IAIK-JCE/JSSE/JDK1.3 Workaround\: SSL ist m\u00F6glicherweise nicht verf\u00FCgbar
@@ -82,6 +86,7 @@ config.22=F\u00FCr den Interfederation-Gateway mit der ID {0} ist kein Endpunkt config.23=Fehler beim initialisieren von OpenSAML
config.24=MOA-ID-Auth Configfile {1} does not start with {0} prefix.
config.25=Der verwendete IDP PublicURLPrefix {0} ist nicht erlaubt.
+config.26=Federated IDP {0} contains no AttributeQuery URL.
parser.00=Leichter Fehler beim Parsen: {0}
parser.01=Fehler beim Parsen: {0}
@@ -100,6 +105,7 @@ builder.04=Die Personenbindung konnte nicht neu signiert werden und wird aus die builder.05=Beim resignieren der Personenbindung ist ein allgemeiner Fehler aufgetreten und wird aus diesem Grund nicht ausgeliefert.
builder.06=Fehler beim generieren der Anmeldedaten aus SSO IDP Interfederation Informationen.
builder.07=Fehlerhaftes SecurityLayer Template.
+builder.08=Authentication process could NOT completed. Reason: {0}
service.00=Fehler beim Aufruf des Web Service: {0}
service.01=Fehler beim Aufruf des Web Service: kein Endpoint
@@ -112,6 +118,8 @@ service.07=Der SZR-Gateway ist unter {0} nicht erreichbar. service.08=Die Eintragung der ausländischen Person am SZR-Gateway ist fehlgeschlagen.
service.09=Der SZR-Gateway Client konnte nicht initialisiert werden.
+service.10=Die Verwendung des Service {0} ist nicht m\u00f6glich. Ursache: {1}
+
cleaner.00=AuthenticationSessionCleaner wurde gestartet
cleaner.01=Fehler im AuthenticationSessionCleaner
cleaner.02=Abgelaufene MOASession {0} wurde aus dem Speicher entfernt
@@ -213,6 +221,8 @@ validator.70=Das einmale Tokken im signierten AuthBlock ({0}) stimmt nicht mit d validator.71=Das Signaturzertifikat ist nicht qualifiziert.
validator.72=Das Signaturzertifikat ist nicht qualifiziert und es wurde keine OID f\u00FCr Test Identit\u00E4ten gefunden.
+validator.73=Das MIS-Vollmachtenservice und das ELGA-Vollmachtenservice k\u00f6nnen nicht in einem Anmeldevorgang verwendet werden.
+
ssl.01=Validierung des SSL-Server-Endzertifikates hat fehlgeschlagen
stork.00=STORK SAML AuthnRequest konnte nicht signiert werden
@@ -272,12 +282,16 @@ pvp2.23={0} ist keine gueltige AssertionConsumerServiceURL oder entspricht nicht ##add status codes!!!!
-sp.pvp2.00=Can not build PVP AuthnRequest for IDP {0}. No valid SingleSignOnService endpoint found.
-sp.pvp2.01=Can not build PVP AuthnRequest for IDP {0}. IDP is not allowed for federated authentication.
-sp.pvp2.02=Can not build PVP AuthnRequest for IDP {0}. IDP has no (valid) metadata.
-sp.pvp2.03=Receive PVP Response from IDP with unsupported Binding.
-sp.pvp2.04=Receive invalid PVP Response from IDP. No PVP metadata found.
-sp.pvp2.04=Receive invalid PVP Response from IDP {0}. StatusCode {1}.
+sp.pvp2.00=Can not build PVP AuthnRequest for {0} {1}. No valid SingleSignOnService endpoint found.
+sp.pvp2.01=Can not build PVP AuthnRequest for {0} {0}. IDP is not allowed for federated authentication.
+sp.pvp2.02=Can not build PVP AuthnRequest for {0} {0}. IDP has no (valid) metadata.
+sp.pvp2.03=Receive PVP Response from {0} with unsupported Binding.
+sp.pvp2.04=Receive invalid PVP Response from {0}. No PVP metadata found.
+sp.pvp2.05=Receive invalid PVP Response from {0} {1}. StatusCode:{2} Msg:{3}.
+sp.pvp2.06=Receive invalid PVP Response from {0}. Assertion does not contain all required attributes.
+sp.pvp2.07=Receive invalid PVP Response from {0}. Attribute {1} is not valid.
+sp.pvp2.08=Receive invalid PVP Response from {0}. Response issuer {1} is not valid or allowed.
+sp.pvp2.09=Receive invalid PVP Response from {0} {1}. StatusCodes:{2} {3} Msg:{4}
oauth20.01=Fehlerhafte redirect url
oauth20.02=Fehlender oder ung\u00FCltiger Parameter "{0}"
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties index 0b00b2d29..a81540e2b 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties @@ -28,6 +28,10 @@ auth.27=4401 auth.28=1100 auth.29=4401 auth.30=1110 +auth.31=TODO +auth.32=TODO +auth.33=TODO +auth.34=TODO init.00=9199 init.01=9199 @@ -62,6 +66,7 @@ config.22=9008 config.23=9199 config.24=9199 config.25=9199 +config.26=TODO parser.00=1101 parser.01=1101 @@ -80,6 +85,7 @@ builder.04=Die Personenbindung konnte nicht neu signiert werden und wird aus die builder.05=Beim resignieren der Personenbindung ist ein allgemeiner Fehler aufgetreten und wird aus diesem Grund nicht ausgeliefert. builder.06=4400 builder.07=9002 +builder.08=TODO service.00=4300 service.03=4300 @@ -90,6 +96,22 @@ service.07=4200 service.08=4201 service.09=9007 +service.10=TODO + +process.01=TODO +process.02=TODO + +sp.pvp2.00=TODO +sp.pvp2.01=TODO +sp.pvp2.02=TODO +sp.pvp2.03=TODO +sp.pvp2.04=TODO +sp.pvp2.05=TODO +sp.pvp2.06=TODO +sp.pvp2.07=TODO +sp.pvp2.08=TODO +sp.pvp2.09=TODO + validator.00=1102 validator.01=1102 validator.02=1102 @@ -158,6 +180,9 @@ validator.69=1106 validator.70=1106 validator.71=1105 +validator.72=TODO +validator.73=TODO + ssl.01=1107 stork.00=1200 diff --git a/id/server/idserverlib/src/main/resources/resources/templates/error_message.html b/id/server/idserverlib/src/main/resources/resources/templates/error_message.html index 6cc8b99e2..4fd4d63cd 100644 --- a/id/server/idserverlib/src/main/resources/resources/templates/error_message.html +++ b/id/server/idserverlib/src/main/resources/resources/templates/error_message.html @@ -1,7 +1,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> - <link rel="stylesheet" href="#CONTEXTPATH#/css/buildCSS" /> + <link rel="stylesheet" href="$contextPath/css/buildCSS" /> <title>An error arise ... </title> </head> diff --git a/id/server/idserverlib/src/main/resources/resources/templates/slo_template.html b/id/server/idserverlib/src/main/resources/resources/templates/slo_template.html index 220dd980a..b3eb18082 100644 --- a/id/server/idserverlib/src/main/resources/resources/templates/slo_template.html +++ b/id/server/idserverlib/src/main/resources/resources/templates/slo_template.html @@ -3,7 +3,7 @@ <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <!-- MOA-ID 2.x BKUSelection Layout CSS --> - <link rel="stylesheet" href="#CONTEXTPATH#/css/buildCSS" /> + <link rel="stylesheet" href="$contextPath/css/buildCSS" /> #if($timeoutURL) <script type="text/javascript"> diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java index 6d43bcdc6..125d83d6d 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java @@ -22,6 +22,8 @@ */ package at.gv.egovernment.moa.id.module.test; +import java.util.Collection; + import at.gv.egovernment.moa.id.auth.exception.SessionDataStorageException; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.moduls.IRequest; @@ -247,6 +249,15 @@ public class TestRequestImpl implements IRequest { // TODO Auto-generated method stub } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.moduls.IRequest#getRequestedAttributes() + */ + @Override + public Collection<String> getRequestedAttributes() { + // TODO Auto-generated method stub + return null; + } |