From 9fe8db82075de8780feec90f94063e708e521391 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 2 May 2014 13:16:29 +0200 Subject: add interfederation attribute query --- .../auth/src/main/webapp/WEB-INF/urlrewrite.xml | 6 +- .../moa/id/advancedlogging/StatisticLogger.java | 56 +-- .../AuthenticationBlockAssertionBuilder.java | 3 +- .../AuthenticationDataAssertionBuilder.java | 1 + .../id/auth/builder/AuthenticationDataBuilder.java | 423 +++++++++++++++++++-- .../builder/DynamicOAAuthParameterBuilder.java | 109 ++++++ .../auth/builder/GetIdentityLinkFormBuilder.java | 4 +- .../moa/id/auth/builder/LoginFormBuilder.java | 7 +- .../id/auth/exception/DynamicOABuildException.java | 40 ++ .../moa/id/auth/servlet/LogOutServlet.java | 2 +- .../id/auth/servlet/SSOSendAssertionServlet.java | 2 +- .../id/config/auth/AuthConfigurationProvider.java | 16 +- .../moa/id/config/auth/IOAAuthParameters.java | 133 +++++++ .../moa/id/config/auth/OAAuthParameter.java | 146 +++++-- .../config/auth/data/DynamicOAAuthParameters.java | 359 +++++++++++++++++ .../moa/id/data/AuthenticationData.java | 85 ++++- .../at/gv/egovernment/moa/id/data/IAuthData.java | 7 + .../moa/id/data/SLOInformationImpl.java | 23 +- .../moa/id/data/SLOInformationInterface.java | 5 + .../moa/id/entrypoints/DispatcherServlet.java | 46 ++- .../at/gv/egovernment/moa/id/moduls/IRequest.java | 5 + .../gv/egovernment/moa/id/moduls/SSOManager.java | 95 ++++- .../attributes/OAuth20AttributeBuilder.java | 37 ++ .../oauth20/protocol/OAuth20AuthAction.java | 2 +- .../oauth20/protocol/OAuth20AuthRequest.java | 47 ++- .../oauth20/protocol/OAuth20Protocol.java | 11 + .../id/protocols/pvp2x/AttributQueryAction.java | 178 +++++++++ .../id/protocols/pvp2x/AuthenticationAction.java | 1 + .../moa/id/protocols/pvp2x/PVP2XProtocol.java | 233 ++++++++---- .../moa/id/protocols/pvp2x/PVPConstants.java | 2 + .../id/protocols/pvp2x/PVPTargetConfiguration.java | 77 +++- .../id/protocols/pvp2x/binding/PostBinding.java | 3 +- .../id/protocols/pvp2x/binding/SoapBinding.java | 39 +- .../pvp2x/builder/AttributQueryBuilder.java | 185 +++++++++ .../pvp2x/builder/AuthResponseBuilder.java | 152 ++++++++ .../pvp2x/builder/PVPAttributeBuilder.java | 16 + .../builder/assertion/PVP2AssertionBuilder.java | 157 ++++++-- .../EIDIssuingNationAttributeBuilder.java | 38 +- .../pvp2x/builder/attributes/EIDSTORKTOKEN.java | 13 +- .../protocols/pvp2x/config/PVPConfiguration.java | 13 +- .../AssertionAttributeExtractorExeption.java | 50 +++ .../exceptions/AssertionValidationExeption.java | 49 +++ .../pvp2x/exceptions/AttributQueryException.java | 44 +++ .../id/protocols/pvp2x/messages/MOARequest.java | 7 +- .../pvp2x/requestHandler/ArtifactResolution.java | 13 +- .../pvp2x/requestHandler/AuthnRequestHandler.java | 146 +------ .../pvp2x/requestHandler/IRequestHandler.java | 5 +- .../pvp2x/requestHandler/RequestManager.java | 3 +- .../moa/id/protocols/pvp2x/utils/SAML2Utils.java | 13 + .../pvp2x/verification/SAMLVerificationEngine.java | 110 +++++- .../moa/id/protocols/saml1/GetArtifactAction.java | 4 +- .../protocols/saml1/SAML1AuthenticationData.java | 2 - .../moa/id/protocols/saml1/SAML1Protocol.java | 27 +- .../moa/id/protocols/saml1/SAML1RequestImpl.java | 36 +- .../id/protocols/stork2/AttributeCollector.java | 2 +- .../id/protocols/stork2/AuthenticationRequest.java | 3 +- .../moa/id/protocols/stork2/ConsentEvaluator.java | 4 +- .../moa/id/storage/AssertionStorage.java | 2 +- .../id/storage/AuthenticationSessionStoreage.java | 294 ++++++++++++-- .../moa/id/storage/DBExceptionStoreImpl.java | 2 +- .../resources/properties/id_messages_de.properties | 3 +- .../db/dao/session/AuthenticatedSessionStore.java | 25 +- .../id/commons/db/dao/session/OASessionStore.java | 36 ++ .../id/commons/db/dao/statistic/StatisticLog.java | 18 + .../src/main/resources/config/moaid_config_2.0.xsd | 7 + 65 files changed, 3174 insertions(+), 508 deletions(-) create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/DynamicOABuildException.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IOAAuthParameters.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java (limited to 'id/server') diff --git a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml index 6f451ec79..6da7396a1 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml @@ -48,9 +48,13 @@ /dispatcher?mod=id_pvp2x&action=Post&%{query-string} - ^/PVP2Soap$ + ^/pvp2/Soap$ /dispatcher?mod=id_pvp2x&action=Soap + + ^/pvp2/attributequery$ + /dispatcher?mod=id_pvp2x&action=AttributeQuery + ^/stork2/StartAuthentication$ 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 d4b5d1c05..0e5f9bcc3 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 @@ -51,7 +51,8 @@ import at.gv.egovernment.moa.id.commons.db.dao.statistic.StatisticLog; 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.AuthConfigurationProvider; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate; @@ -97,9 +98,9 @@ public class StatisticLogger { } } - public void logSuccessOperation(IRequest protocolRequest, AuthenticationSession moasession, boolean isSSOSession) { + public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession) { - if ( isAktive && protocolRequest != null && moasession != null) { + if ( isAktive && protocolRequest != null && authData != null) { OnlineApplication dbOA = ConfigurationDBRead.getOnlineApplication(protocolRequest.getOAURL()); @@ -128,9 +129,18 @@ public class StatisticLogger { dblog.setOatarget(dbOA.getAuthComponentOA().getIdentificationNumber().getValue()); else dblog.setOatarget(dbOA.getTarget()); + + dblog.setInterfederatedSSOSession(authData.isInterfederatedSSOSession()); - dblog.setBkuurl(moasession.getBkuURL()); - dblog.setBkutype(findBKUType(moasession.getBkuURL(), dbOA)); + if (authData.isInterfederatedSSOSession()) { + dblog.setBkutype(IOAAuthParameters.INDERFEDERATEDIDP); + dblog.setBkuurl(authData.getInterfederatedIDP()); + + } else { + dblog.setBkuurl(authData.getBkuURL()); + dblog.setBkutype(findBKUType(authData.getBkuURL(), dbOA)); + + } dblog.setProtocoltype(protocolRequest.requestedModule()); dblog.setProtocolsubtype(protocolRequest.requestedAction()); @@ -138,10 +148,10 @@ public class StatisticLogger { //log MandateInforamtion - if (moasession.getUseMandate()) { - dblog.setMandatelogin(moasession.getUseMandate()); + if (authData.isUseMandate()) { + dblog.setMandatelogin(authData.isUseMandate()); - MISMandate mandate = moasession.getMISMandate(); + MISMandate mandate = authData.getMISMandate(); if (mandate != null) { if (MiscUtil.isNotEmpty(mandate.getProfRep())) { @@ -333,13 +343,13 @@ public class StatisticLogger { BKUURLS bkuurls = oaAuth.getBKUURLS(); if (bkuurls != null) { if (bkuURL.equals(bkuurls.getHandyBKU())) - return OAAuthParameter.HANDYBKU; + return IOAAuthParameters.HANDYBKU; if (bkuURL.equals(bkuurls.getLocalBKU())) - return OAAuthParameter.LOCALBKU; + return IOAAuthParameters.LOCALBKU; if (bkuURL.equals(bkuurls.getOnlineBKU())) - return OAAuthParameter.ONLINEBKU; + return IOAAuthParameters.ONLINEBKU; } } } @@ -348,14 +358,14 @@ public class StatisticLogger { try { AuthConfigurationProvider authconfig = AuthConfigurationProvider.getInstance(); - if (bkuURL.equals(authconfig.getDefaultBKUURL(OAAuthParameter.ONLINEBKU))) - return OAAuthParameter.ONLINEBKU; + if (bkuURL.equals(authconfig.getDefaultBKUURL(IOAAuthParameters.ONLINEBKU))) + return IOAAuthParameters.ONLINEBKU; - if (bkuURL.equals(authconfig.getDefaultBKUURL(OAAuthParameter.LOCALBKU))) - return OAAuthParameter.LOCALBKU; + if (bkuURL.equals(authconfig.getDefaultBKUURL(IOAAuthParameters.LOCALBKU))) + return IOAAuthParameters.LOCALBKU; - if (bkuURL.equals(authconfig.getDefaultBKUURL(OAAuthParameter.HANDYBKU))) - return OAAuthParameter.HANDYBKU; + if (bkuURL.equals(authconfig.getDefaultBKUURL(IOAAuthParameters.HANDYBKU))) + return IOAAuthParameters.HANDYBKU; } catch (ConfigurationException e) { Logger.info("Advanced Logging: Default BKUs read failed"); @@ -364,17 +374,17 @@ public class StatisticLogger { Logger.debug("Staticic Log search BKUType from generneric Parameters"); if (bkuURL.endsWith(GENERIC_LOCALBKU)) { - Logger.debug("BKUURL " + bkuURL + " is mapped to " + OAAuthParameter.LOCALBKU); - return OAAuthParameter.LOCALBKU; + Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.LOCALBKU); + return IOAAuthParameters.LOCALBKU; } if (bkuURL.startsWith(GENERIC_HANDYBKU)) { - Logger.debug("BKUURL " + bkuURL + " is mapped to " + OAAuthParameter.HANDYBKU); - return OAAuthParameter.HANDYBKU; + Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.HANDYBKU); + return IOAAuthParameters.HANDYBKU; } - Logger.debug("BKUURL " + bkuURL + " is mapped to " + OAAuthParameter.ONLINEBKU); - return OAAuthParameter.ONLINEBKU; + Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.ONLINEBKU); + return IOAAuthParameters.ONLINEBKU; } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java index 30ad0bdc9..a6c2cde05 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java @@ -51,6 +51,7 @@ import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.TargetToSectorNameMapper; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; @@ -496,7 +497,7 @@ public class AuthenticationBlockAssertionBuilder extends AuthenticationAssertion String gebDat, List extendedSAMLAttributes, AuthenticationSession session, - OAAuthParameter oaParam) + IOAAuthParameters oaParam) throws BuildException { session.setSAMLAttributeGebeORwbpk(true); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java index 4c824354c..ba4440bf8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java @@ -239,6 +239,7 @@ public class AuthenticationDataAssertionBuilder extends AuthenticationAssertionB { String isQualifiedCertificate = authData.isQualifiedCertificate() ? "true" : "false"; + String publicAuthorityAttribute = ""; if (authData.isPublicAuthority()) { String publicAuthorityIdentification = authData.getPublicAuthorityCode(); 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 1e0089a53..33c150927 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,24 +22,64 @@ */ package at.gv.egovernment.moa.id.auth.builder; +import iaik.x509.X509Certificate; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeQuery; +import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.Response; +import org.opensaml.ws.soap.client.BasicSOAPMessageContext; +import org.opensaml.ws.soap.client.http.HttpClientBuilder; +import org.opensaml.ws.soap.client.http.HttpSOAPClient; +import org.opensaml.ws.soap.common.SOAPException; +import org.opensaml.ws.soap.soap11.Body; +import org.opensaml.ws.soap.soap11.Envelope; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.SecurityException; import org.w3c.dom.Element; import org.w3c.dom.Node; +import eu.stork.peps.auth.commons.PersonalAttribute; +import eu.stork.peps.auth.commons.PersonalAttributeList; + 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.IdentityLink; import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.DynamicOABuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; 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.AuthConfigurationProvider; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.data.IAuthData; 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.AttributQueryBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionAttributeExtractorExeption; -import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; +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.utils.SAML2Utils; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; import at.gv.egovernment.moa.id.protocols.saml1.SAML1AuthenticationData; import at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; @@ -47,6 +87,7 @@ import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; import at.gv.egovernment.moa.id.util.ParamValidatorUtils; import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate; 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 at.gv.egovernment.moa.util.XPathUtils; @@ -58,7 +99,7 @@ import at.gv.egovernment.moa.util.XPathUtils; public class AuthenticationDataBuilder implements MOAIDAuthConstants { public static IAuthData buildAuthenticationData(IRequest protocolRequest, - AuthenticationSession session) throws ConfigurationException, BuildException, WrongParametersException { + AuthenticationSession session, List reqAttributes) throws ConfigurationException, BuildException, WrongParametersException, DynamicOABuildException { String oaID = protocolRequest.getOAURL(); @@ -71,11 +112,9 @@ public class AuthenticationDataBuilder implements MOAIDAuthConstants { if (!ParamValidatorUtils.isValidOA(oaID)) throw new WrongParametersException("StartAuthentication", PARAM_OA, "auth.12"); - - OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() - .getOnlineApplicationParameter(oaID); - AuthenticationData authdata = null; + AuthenticationData authdata = null; + if (protocolRequest instanceof SAML1RequestImpl) { //request is SAML1 SAML1AuthenticationData saml1authdata = new SAML1AuthenticationData(); @@ -88,11 +127,65 @@ public class AuthenticationDataBuilder implements MOAIDAuthConstants { } + //reuse some parameters if it is a reauthentication + OASessionStore activeOA = AuthenticationSessionStoreage.searchActiveOASSOSession(session, oaID, protocolRequest.requestedModule()); + if (activeOA != null) { + authdata.setSessionIndex(activeOA.getAssertionSessionID()); + authdata.setNameID(activeOA.getUserNameID()); + authdata.setNameIDFormat(activeOA.getUserNameIDFormat()); - if (protocolRequest.getInterfederationResponse() != null) { - //get attributes from interfederated IDP - buildAuthDataFromInterfederationResponse(authdata, session, oaParam, protocolRequest); + //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); + + } + } + } + + InterfederationSessionStore interfIDP = AuthenticationSessionStoreage.searchInterfederatedIDPFORAttributeQueryWithSessionID(session); + + IOAAuthParameters oaParam = null; + if (reqAttributes == null) { + //get OnlineApplication from MOA-ID-Auth configuration + oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(oaID); + + } else { + //build OnlineApplication dynamic from requested attributes + oaParam = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes, interfIDP); + + } + + if (interfIDP != null ) { + //IDP is a chained interfederated IDP and Authentication is requested + if (oaParam.isInderfederationIDP() && protocolRequest instanceof PVPTargetConfiguration && + !(((PVPTargetConfiguration)protocolRequest).getRequest() instanceof AttributeQuery)) { + //only set minimal response attributes + authdata.setQAALevel(interfIDP.getQAALevel()); + authdata.setBPK(interfIDP.getUserNameID()); + + } else { + //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); + + } + + //get attributes from interfederated IDP + getAuthDataFromInterfederation(authdata, session, oaParam, protocolRequest, interfIDP, reqAttributes); + } } else { //build AuthenticationData from MOASession @@ -103,42 +196,283 @@ public class AuthenticationDataBuilder implements MOAIDAuthConstants { return authdata; } + /** + * @param req + * @param session + * @param reqAttributes + * @return + * @throws WrongParametersException + * @throws ConfigurationException + * @throws BuildException + * @throws DynamicOABuildException + */ + public static 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 reqQueryAttr + * @throws ConfigurationException */ - private static void buildAuthDataFromInterfederationResponse( + private static void getAuthDataFromInterfederation( AuthenticationData authdata, AuthenticationSession session, - OAAuthParameter oaParam, IRequest req) { - - try { - AssertionAttributeExtractor extract = - new AssertionAttributeExtractor(req.getInterfederationResponse().getResponse()); + IOAAuthParameters oaParam, IRequest req, + InterfederationSessionStore interfIDP, List reqQueryAttr) throws BuildException, ConfigurationException{ - if (oaParam.isInderfederationIDP()) { - //only set minimal response attributes - authdata.setQAALevel(extract.getQAALevel()); - authdata.setBPK(extract.getNameID()); - + try { + List 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 { - //IDP response to service provider - // --> collect attributes by using BackChannel communication - - //TODO: get protocol specific requested attributes + //TODO: check if response include attributes and map this attributes to requested attributes + + //get PVP 2.1 attributes from protocol specific requested attributes + attributs = req.getRequestedAttributes(); + } + //collect attributes by using BackChannel communication + String endpoint = oaParam.getIDPAttributQueryServiceURL(); + if (MiscUtil.isEmpty(endpoint)) { + Logger.error("No AttributeQueryURL for interfederationIDP " + oaParam.getPublicURLPrefix()); + throw new ConfigurationException("No AttributeQueryURL for interfederationIDP " + oaParam.getPublicURLPrefix(), null); } + + //build attributQuery request + AttributeQuery query = + AttributQueryBuilder.buildAttributQueryRequest(interfIDP.getUserNameID(), endpoint, attributs); + + //build SOAP request + BasicParserPool parserPool = new BasicParserPool(); + parserPool.setNamespaceAware(true); + + Envelope soapRequest = SAML2Utils.buildSOAP11Envelope(query); + + BasicSOAPMessageContext soapContext = new BasicSOAPMessageContext(); + soapContext.setOutboundMessage(soapRequest); + HttpClientBuilder clientBuilder = new HttpClientBuilder(); + HttpSOAPClient soapClient = new HttpSOAPClient(clientBuilder.buildClient(), parserPool); + + //send request to IDP + soapClient.send(endpoint, soapContext); + + //parse response + Envelope soapResponse = (Envelope) soapContext.getInboundMessage(); + Body soapBody = soapResponse.getBody(); + + if (soapBody.getUnknownXMLObjects().size() == 0) { + Logger.error("Receive emptry AttributeQuery response-body."); + throw new AttributQueryException("Receive emptry AttributeQuery response-body.", null); + + } + + if (soapBody.getUnknownXMLObjects().get(0) instanceof Response) { + Response intfResp = (Response) soapBody.getUnknownXMLObjects().get(0); + + //validate PVP 2.1 response + try { + SAMLVerificationEngine engine = new SAMLVerificationEngine(); + engine.verifyResponse(intfResp, TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + + 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); + } + + //parse response information to authData + buildAuthDataFormInterfederationResponse(authdata, session, intfResp); + + } 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); + + } + + } 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) { - Logger.error("Build authData from interfederated PVP2.1 assertion FAILED.", e); + throw new BuildException("builder.06", null, e); } } + private static void buildAuthDataFormInterfederationResponse(AuthenticationData authData, AuthenticationSession session, + Response intfResp) throws BuildException, AssertionAttributeExtractorExeption { + + Logger.debug("Build AuthData from assertion starts ...."); + + Assertion assertion = intfResp.getAssertions().get(0); + + if (assertion.getAttributeStatements().size() == 0) { + Logger.warn("Can not build AuthData from Assertion. NO Attributes included."); + throw new AssertionAttributeExtractorExeption("Can not build AuthData from Assertion. NO Attributes included.", null); + + } + + AttributeStatement attrStat = assertion.getAttributeStatements().get(0); + for (Attribute attr : attrStat.getAttributes()) { + + if (attr.getName().equals(PVPConstants.PRINCIPAL_NAME_NAME)) + authData.setFamilyName(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.GIVEN_NAME_NAME)) + authData.setGivenName(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.BIRTHDATE_NAME)) + authData.setDateOfBirth(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.BPK_NAME)) { + String pvpbPK = attr.getAttributeValues().get(0).getDOM().getTextContent(); + authData.setBPK(pvpbPK.split(":")[1]); + } + + if (attr.getName().equals(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) + authData.setBPKType(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME)) + authData.setQAALevel(PVPConstants.STORK_QAA_PREFIX + + attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_ISSUING_NATION_NAME)) + authData.setCcc(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_CCS_URL_NAME)) + authData.setBkuURL(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_AUTH_BLOCK_NAME)) { + try { + byte[] authBlock = Base64Utils.decode(attr.getAttributeValues().get(0).getDOM().getTextContent(), false); + authData.setAuthBlock(new String(authBlock, "UTF-8")); + + } catch (IOException e) { + Logger.error("Received AuthBlock is not valid", e); + + } + } + + if (attr.getName().equals(PVPConstants.EID_SIGNER_CERTIFICATE_NAME)) { + try { + authData.setSignerCertificate(Base64Utils.decode( + attr.getAttributeValues().get(0).getDOM().getTextContent(), false)); + + } catch (IOException e) { + Logger.error("Received SignerCertificate is not valid", e); + + } + } + + if (attr.getName().equals(PVPConstants.EID_SOURCE_PIN_NAME)) + authData.setIdentificationValue(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_SOURCE_PIN_TYPE_NAME)) + authData.setIdentificationType(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + if (attr.getName().equals(PVPConstants.EID_IDENTITY_LINK_NAME)) { + try { + InputStream idlStream = Base64Utils.decodeToStream(attr.getAttributeValues().get(0).getDOM().getTextContent(), false); + IdentityLink idl = new IdentityLinkAssertionParser(idlStream).parseIdentityLink(); + authData.setIdentityLink(idl); + + } catch (ParseException e) { + Logger.error("Received IdentityLink is not valid", e); + + } catch (Exception e) { + Logger.error("Received IdentityLink is not valid", e); + + } + } + + if (attr.getName().equals(PVPConstants.MANDATE_REFERENCE_VALUE_NAME)) + authData.setMandateReferenceValue(attr.getAttributeValues().get(0).getDOM().getTextContent()); + + + if (attr.getName().equals(PVPConstants.MANDATE_FULL_MANDATE_NAME)) { + try { + byte[] mandate = Base64Utils.decode( + attr.getAttributeValues().get(0).getDOM().getTextContent(), false); + + if (authData.getMISMandate() == null) + authData.setMISMandate(new MISMandate()); + authData.getMISMandate().setMandate(mandate); + + authData.setUseMandate(true); + + } catch (Exception e) { + Logger.error("Received Mandate is not valid", e); + throw new AssertionAttributeExtractorExeption(PVPConstants.MANDATE_FULL_MANDATE_NAME); + + } + } + + if (attr.getName().equals(PVPConstants.MANDATE_PROF_REP_OID_NAME)) { + if (authData.getMISMandate() == null) + authData.setMISMandate(new MISMandate()); + authData.getMISMandate().setProfRep( + attr.getAttributeValues().get(0).getDOM().getTextContent()); + + } + + if (attr.getName().equals(PVPConstants.EID_STORK_TOKEN_NAME)) { + authData.setStorkAuthnResponse(attr.getAttributeValues().get(0).getDOM().getTextContent()); + authData.setForeigner(true); + } + + if (attr.getName().startsWith(PVPConstants.STORK_ATTRIBUTE_PREFIX)) { + + if (authData.getStorkAttributes() == null) + authData.setStorkAttributes(new PersonalAttributeList()); + + List storkAttrValues = new ArrayList(); + storkAttrValues.add(attr.getAttributeValues().get(0).getDOM().getTextContent()); + PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(), + false, storkAttrValues , "Available"); + authData.getStorkAttributes().put(attr.getName(), storkAttr ); + authData.setForeigner(true); + } + + } + + authData.setSsoSession(true); + + //only for SAML1 + if (PVPConstants.STORK_QAA_1_4.equals(authData.getQAALevel())) + authData.setQualifiedCertificate(true); + else + authData.setQualifiedCertificate(false); + authData.setPublicAuthority(false); + } + private static void buildAuthDataFormMOASession(AuthenticationData authData, AuthenticationSession session, - OAAuthParameter oaParam) throws BuildException { + IOAAuthParameters oaParam) throws BuildException { String target = oaParam.getTarget(); @@ -173,7 +507,42 @@ public class AuthenticationDataBuilder implements MOAIDAuthConstants { authData.setForeigner(session.isForeigner()); authData.setQAALevel(session.getQAALevel()); + + if (session.isForeigner()) { + if (authData.getStorkAuthnRequest() != null) { + authData.setCcc(authData.getStorkAuthnRequest() + .getCitizenCountryCode()); + } else { + + 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", e); + + } + } + + } else { + authData.setCcc("AT"); + + } + try { authData.setSsoSession(AuthenticationSessionStoreage.isSSOSession(session.getSessionID())); 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 new file mode 100644 index 000000000..132b6af01 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/DynamicOAAuthParameterBuilder.java @@ -0,0 +1,109 @@ +/* + * 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.builder; + +import java.util.List; + +import org.opensaml.saml2.core.Attribute; + +import at.gv.egovernment.moa.id.auth.exception.DynamicOABuildException; +import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.data.DynamicOAAuthParameters; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; + +/** + * @author tlenz + * + */ +public class DynamicOAAuthParameterBuilder { + + public static IOAAuthParameters buildFromAttributeQuery(List reqAttributes, InterfederationSessionStore interfIDP) 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); + + } + + } + + } + + if (interfIDP != null) { + //load interfederated IDP informations + OAAuthParameter idp = AuthConfigurationProvider.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); + + } + + 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); + } + + + + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java index ab93f509c..dc981ba33 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java @@ -52,7 +52,7 @@ import java.io.StringWriter; import java.util.Map; import at.gv.egovernment.moa.id.auth.exception.BuildException; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.util.FormBuildUtils; import at.gv.egovernment.moa.util.MiscUtil; @@ -153,7 +153,7 @@ public class GetIdentityLinkFormBuilder extends Builder { String dataURL, String certInfoXMLRequest, String certInfoDataURL, - String pushInfobox, OAAuthParameter oaParam, + String pushInfobox, IOAAuthParameters oaParam, String appletheigth, String appletwidth) throws BuildException diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java index 4d80be1e8..54196427e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java @@ -40,6 +40,7 @@ import at.gv.egovernment.moa.id.commons.db.ConfigurationDBRead; import at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.protocols.saml1.SAML1Protocol; import at.gv.egovernment.moa.id.util.FormBuildUtils; @@ -105,9 +106,9 @@ public class LoginFormBuilder { IOUtils.copy(input, writer); template = writer.toString(); template = template.replace(AUTH_URL, SERVLET); - template = template.replace(BKU_ONLINE, OAAuthParameter.ONLINEBKU); - template = template.replace(BKU_HANDY, OAAuthParameter.HANDYBKU); - template = template.replace(BKU_LOCAL, OAAuthParameter.LOCALBKU); + template = template.replace(BKU_ONLINE, IOAAuthParameters.ONLINEBKU); + template = template.replace(BKU_HANDY, IOAAuthParameters.HANDYBKU); + template = template.replace(BKU_LOCAL, IOAAuthParameters.LOCALBKU); } catch (Exception e) { Logger.error("Failed to read template", e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/DynamicOABuildException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/DynamicOABuildException.java new file mode 100644 index 000000000..554cf7370 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/DynamicOABuildException.java @@ -0,0 +1,40 @@ +/* + * 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.exception; + +/** + * @author tlenz + * + */ +public class DynamicOABuildException extends MOAIDException { + + + private static final long serialVersionUID = 3756862942519706809L; + + + public DynamicOABuildException(String messageId, Object[] parameters) { + super(messageId, parameters); + // TODO Auto-generated constructor stub + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/LogOutServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/LogOutServlet.java index fc4ec305d..9911fccd4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/LogOutServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/LogOutServlet.java @@ -101,7 +101,7 @@ public class LogOutServlet extends AuthServlet { } - if (ssomanager.isValidSSOSession(ssoid, req)) { + if (ssomanager.isValidSSOSession(ssoid, null)) { //TODO: Single LogOut Implementation diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java index 997241822..442ebe2f4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java @@ -108,7 +108,7 @@ public class SSOSendAssertionServlet extends AuthServlet{ } } - boolean isValidSSOSession = ssomanager.isValidSSOSession(ssoId, req); + boolean isValidSSOSession = ssomanager.isValidSSOSession(ssoId, null); String moaSessionID = null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java index 1e1652412..143a04dad 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java @@ -697,17 +697,17 @@ public class AuthConfigurationProvider extends ConfigurationProvider { Logger.warn("Error in MOA-ID Configuration. No SLRequestTemplates found"); throw new ConfigurationException("config.02", null); } else { - SLRequestTemplates.put(OAAuthParameter.ONLINEBKU, templ.getOnlineBKU()); - SLRequestTemplates.put(OAAuthParameter.LOCALBKU, templ.getLocalBKU()); - SLRequestTemplates.put(OAAuthParameter.HANDYBKU, templ.getHandyBKU()); + SLRequestTemplates.put(IOAAuthParameters.ONLINEBKU, templ.getOnlineBKU()); + SLRequestTemplates.put(IOAAuthParameters.LOCALBKU, templ.getLocalBKU()); + SLRequestTemplates.put(IOAAuthParameters.HANDYBKU, templ.getHandyBKU()); } //set Default BKU URLS DefaultBKUs bkuuls = moaidconfig.getDefaultBKUs(); if (bkuuls != null) { - DefaultBKUURLs.put(OAAuthParameter.ONLINEBKU, bkuuls.getOnlineBKU()); - DefaultBKUURLs.put(OAAuthParameter.LOCALBKU, bkuuls.getLocalBKU()); - DefaultBKUURLs.put(OAAuthParameter.HANDYBKU, bkuuls.getHandyBKU()); + DefaultBKUURLs.put(IOAAuthParameters.ONLINEBKU, bkuuls.getOnlineBKU()); + DefaultBKUURLs.put(IOAAuthParameters.LOCALBKU, bkuuls.getLocalBKU()); + DefaultBKUURLs.put(IOAAuthParameters.HANDYBKU, bkuuls.getHandyBKU()); } //set SSO Config @@ -886,7 +886,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider { return el; else { Logger.warn("getSLRequestTemplates: BKU Type does not match: " - + OAAuthParameter.ONLINEBKU + " or " + OAAuthParameter.HANDYBKU + " or " + OAAuthParameter.LOCALBKU); + + IOAAuthParameters.ONLINEBKU + " or " + IOAAuthParameters.HANDYBKU + " or " + IOAAuthParameters.LOCALBKU); return null; } } @@ -901,7 +901,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider { return el; else { Logger.warn("getSLRequestTemplates: BKU Type does not match: " - + OAAuthParameter.ONLINEBKU + " or " + OAAuthParameter.HANDYBKU + " or " + OAAuthParameter.LOCALBKU); + + IOAAuthParameters.ONLINEBKU + " or " + IOAAuthParameters.HANDYBKU + " or " + IOAAuthParameters.LOCALBKU); return null; } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IOAAuthParameters.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IOAAuthParameters.java new file mode 100644 index 000000000..39c8ecfdc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IOAAuthParameters.java @@ -0,0 +1,133 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.config.auth; + +import java.util.List; +import java.util.Map; + +import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin; +import at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS; +import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2; +import at.gv.egovernment.moa.id.commons.db.dao.config.OASAML1; +import at.gv.egovernment.moa.id.commons.db.dao.config.OAStorkAttribute; +import at.gv.egovernment.moa.id.commons.db.dao.config.TemplateType; + +/** + * @author tlenz + * + */ +public interface IOAAuthParameters { + + public static final String ONLINEBKU = "online"; + public static final String HANDYBKU = "handy"; + public static final String LOCALBKU = "local"; + public static final String INDERFEDERATEDIDP = "interfederated"; + + + public String getPublicURLPrefix(); + + public boolean getBusinessService(); + + public String getTarget(); + + public boolean isInderfederationIDP(); + + /** + * @return the identityLinkDomainIdentifier + */ + public String getIdentityLinkDomainIdentifier(); + + /** + * @return the keyBoxIdentifier + */ + public String getKeyBoxIdentifier(); + + /** + * @return the transformsInfos + */ + public List getTransformsInfos(); + + public OASAML1 getSAML1Parameter(); + + public OAPVP2 getPVP2Parameter(); + + /** + * @return the templateURL + */ + public List getTemplateURL(); + + public String getAditionalAuthBlockText(); + + public String getBKUURL(String bkutype); + + public List getBKUURL(); + + public boolean useSSO(); + + public boolean useSSOQuestion(); + + public String getSingleLogOutURL(); + + /** + * @return the mandateProfiles + */ + public List getMandateProfiles(); + + /** + * @return the identityLinkDomainIdentifierType + */ + public String getIdentityLinkDomainIdentifierType(); + + public boolean isShowMandateCheckBox(); + + public boolean isOnlyMandateAllowed(); + + /** + * Shall we show the stork login in the bku selection frontend? + * + * @return true, if is we should show stork login + */ + public boolean isShowStorkLogin(); + + public Map getFormCustomizaten(); + + public Integer getQaaLevel(); + + /** + * @return the requestedAttributes + */ + public List getRequestedAttributes(); + + public boolean isRequireConsentForStorkAttributes(); + + public List getStorkAPs(); + + public byte[] getBKUSelectionTemplate(); + + public byte[] getSendAssertionTemplate(); + + public List getPepsList(); + + public String getIDPAttributQueryServiceURL(); + +} \ No newline at end of file diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java index 492770aad..63b91f6d2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java @@ -57,6 +57,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.BKUSelectionCustomizationT import at.gv.egovernment.moa.id.commons.db.dao.config.BKUURLS; import at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS; import at.gv.egovernment.moa.id.commons.db.dao.config.IdentificationNumber; +import at.gv.egovernment.moa.id.commons.db.dao.config.InterfederationIDPType; import at.gv.egovernment.moa.id.commons.db.dao.config.Mandates; import at.gv.egovernment.moa.id.commons.db.dao.config.MandatesProfileNameItem; import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2; @@ -85,13 +86,11 @@ import at.gv.egovernment.moa.util.MiscUtil; * * @author Harald Bratko */ -public class OAAuthParameter extends OAParameter { +public class OAAuthParameter extends OAParameter implements IOAAuthParameters { - public static final String ONLINEBKU = "online"; - public static final String HANDYBKU = "handy"; - public static final String LOCALBKU = "local"; - private AuthComponentOA oa_auth; + private String keyBoxIdentifier; + private InterfederationIDPType inderfederatedIDP = null; public OAAuthParameter(OnlineApplication oa) { super(oa); @@ -99,13 +98,15 @@ public class OAAuthParameter extends OAParameter { this.oa_auth = oa.getAuthComponentOA(); this.keyBoxIdentifier = oa.getKeyBoxIdentifier().value(); -} + + this.inderfederatedIDP = oa.getInterfederationIDP(); + } - private String keyBoxIdentifier; -/** - * @return the identityLinkDomainIdentifier +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifier() */ +@Override public String getIdentityLinkDomainIdentifier() { IdentificationNumber idnumber = oa_auth.getIdentificationNumber(); @@ -115,34 +116,45 @@ public String getIdentityLinkDomainIdentifier() { return null; } -/** - * @return the keyBoxIdentifier +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getKeyBoxIdentifier() */ +@Override public String getKeyBoxIdentifier() { return keyBoxIdentifier; } -/** - * @return the transformsInfos +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTransformsInfos() */ +@Override public List getTransformsInfos() { List transformations = oa_auth.getTransformsInfo(); return ConfigurationUtils.getTransformInfos(transformations); } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSAML1Parameter() + */ + @Override public OASAML1 getSAML1Parameter() { return oa_auth.getOASAML1(); } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPVP2Parameter() + */ + @Override public OAPVP2 getPVP2Parameter() { return oa_auth.getOAPVP2(); } - /** - * @return the templateURL + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTemplateURL() */ + @Override public List getTemplateURL() { TemplatesType templates = oa_auth.getTemplates(); @@ -154,6 +166,10 @@ public List getTransformsInfos() { return null; } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getAditionalAuthBlockText() + */ + @Override public String getAditionalAuthBlockText() { TemplatesType templates = oa_auth.getTemplates(); @@ -163,6 +179,10 @@ public List getTransformsInfos() { return null; } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL(java.lang.String) + */ + @Override public String getBKUURL(String bkutype) { BKUURLS bkuurls = oa_auth.getBKUURLS(); if (bkuurls != null) { @@ -179,6 +199,10 @@ public List getTransformsInfos() { return null; } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL() + */ + @Override public List getBKUURL() { BKUURLS bkuurls = oa_auth.getBKUURLS(); @@ -196,6 +220,10 @@ public List getTransformsInfos() { } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSO() + */ + @Override public boolean useSSO() { OASSO sso = oa_auth.getOASSO(); if (sso != null) @@ -204,6 +232,10 @@ public List getTransformsInfos() { return false; } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSOQuestion() + */ + @Override public boolean useSSOQuestion() { OASSO sso = oa_auth.getOASSO(); if (sso != null) @@ -213,6 +245,10 @@ public List getTransformsInfos() { } + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSingleLogOutURL() + */ + @Override public String getSingleLogOutURL() { OASSO sso = oa_auth.getOASSO(); if (sso != null) @@ -221,9 +257,10 @@ public List getTransformsInfos() { return null; } -/** - * @return the mandateProfiles +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getMandateProfiles() */ +@Override public List getMandateProfiles() { Mandates mandates = oa_auth.getMandates(); @@ -253,9 +290,10 @@ public List getMandateProfiles() { return null; } -/** - * @return the identityLinkDomainIdentifierType +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifierType() */ +@Override public String getIdentityLinkDomainIdentifierType() { IdentificationNumber idnumber = oa_auth.getIdentificationNumber(); if (idnumber != null) @@ -265,6 +303,10 @@ public String getIdentityLinkDomainIdentifierType() { } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowMandateCheckBox() + */ +@Override public boolean isShowMandateCheckBox() { TemplatesType templates = oa_auth.getTemplates(); if (templates != null) { @@ -277,6 +319,10 @@ public boolean isShowMandateCheckBox() { return true; } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isOnlyMandateAllowed() + */ +@Override public boolean isOnlyMandateAllowed() { TemplatesType templates = oa_auth.getTemplates(); if (templates != null) { @@ -289,11 +335,10 @@ public boolean isOnlyMandateAllowed() { return false; } - /** - * Shall we show the stork login in the bku selection frontend? - * - * @return true, if is we should show stork login + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowStorkLogin() */ + @Override public boolean isShowStorkLogin() { try { return oa_auth.getOASTORK().isStorkLogonEnabled(); @@ -303,6 +348,10 @@ public boolean isOnlyMandateAllowed() { } } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getFormCustomizaten() + */ +@Override public Map getFormCustomizaten() { TemplatesType templates = oa_auth.getTemplates(); @@ -354,6 +403,10 @@ public Map getFormCustomizaten() { return map; } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel() + */ +@Override public Integer getQaaLevel() { if (oa_auth.getOASTORK() != null && oa_auth.getOASTORK().getQaa() != null) @@ -363,21 +416,34 @@ public Integer getQaaLevel() { return 4; } -/** - * @return the requestedAttributes +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getRequestedAttributes() */ +@Override public List getRequestedAttributes() { return oa_auth.getOASTORK().getOAAttributes(); } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isRequireConsentForStorkAttributes() + */ +@Override public boolean isRequireConsentForStorkAttributes() { return oa_auth.getOASTORK().isRequireConsent(); } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getStorkAPs() + */ +@Override public List getStorkAPs() { return oa_auth.getOASTORK().getAttributeProviders(); } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUSelectionTemplate() + */ +@Override public byte[] getBKUSelectionTemplate() { TemplatesType templates = oa_auth.getTemplates(); @@ -389,6 +455,10 @@ public byte[] getBKUSelectionTemplate() { return null; } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSendAssertionTemplate() + */ +@Override public byte[] getSendAssertionTemplate() { TemplatesType templates = oa_auth.getTemplates(); @@ -400,8 +470,34 @@ public byte[] getSendAssertionTemplate() { return null; } +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPepsList() + */ +@Override public List getPepsList() { return new ArrayList(oa_auth.getOASTORK().getCPEPS()); } + +/* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIDPAttributQueryServiceURL() + */ +@Override +public String getIDPAttributQueryServiceURL() { + if (inderfederatedIDP != null) + return inderfederatedIDP.getAttributeQueryURL(); + else + return null; + +} + +public boolean isIDPPublicService() { + if (inderfederatedIDP != null) + return inderfederatedIDP.isPublicService(); + + else + return false; + +} + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java new file mode 100644 index 000000000..f35027f21 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java @@ -0,0 +1,359 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.config.auth.data; + +import java.util.List; +import java.util.Map; + +import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin; +import at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS; +import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2; +import at.gv.egovernment.moa.id.commons.db.dao.config.OASAML1; +import at.gv.egovernment.moa.id.commons.db.dao.config.OAStorkAttribute; +import at.gv.egovernment.moa.id.commons.db.dao.config.TemplateType; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; + +/** + * @author tlenz + * + */ +public class DynamicOAAuthParameters implements IOAAuthParameters { + + private String applicationID = null; + + private boolean isBusinessService; + private String target; + private String businessTarget; + + private boolean inderfederatedIDP; + private String IDPQueryURL; + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBusinessService() + */ + @Override + public boolean getBusinessService() { + return this.isBusinessService; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTarget() + */ + @Override + public String getTarget() { + return this.target; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifier() + */ + @Override + public String getIdentityLinkDomainIdentifier() { + return this.businessTarget; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isInderfederationIDP() + */ + @Override + public boolean isInderfederationIDP() { + return this.inderfederatedIDP; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIDPAttributQueryServiceURL() + */ + @Override + public String getIDPAttributQueryServiceURL() { + return this.IDPQueryURL; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getKeyBoxIdentifier() + */ + @Override + public String getKeyBoxIdentifier() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTransformsInfos() + */ + @Override + public List getTransformsInfos() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSAML1Parameter() + */ + @Override + public OASAML1 getSAML1Parameter() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPVP2Parameter() + */ + @Override + public OAPVP2 getPVP2Parameter() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getTemplateURL() + */ + @Override + public List getTemplateURL() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getAditionalAuthBlockText() + */ + @Override + public String getAditionalAuthBlockText() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL(java.lang.String) + */ + @Override + public String getBKUURL(String bkutype) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUURL() + */ + @Override + public List getBKUURL() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSO() + */ + @Override + public boolean useSSO() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#useSSOQuestion() + */ + @Override + public boolean useSSOQuestion() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSingleLogOutURL() + */ + @Override + public String getSingleLogOutURL() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getMandateProfiles() + */ + @Override + public List getMandateProfiles() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getIdentityLinkDomainIdentifierType() + */ + @Override + public String getIdentityLinkDomainIdentifierType() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowMandateCheckBox() + */ + @Override + public boolean isShowMandateCheckBox() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isOnlyMandateAllowed() + */ + @Override + public boolean isOnlyMandateAllowed() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isShowStorkLogin() + */ + @Override + public boolean isShowStorkLogin() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getFormCustomizaten() + */ + @Override + public Map getFormCustomizaten() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel() + */ + @Override + public Integer getQaaLevel() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getRequestedAttributes() + */ + @Override + public List getRequestedAttributes() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#isRequireConsentForStorkAttributes() + */ + @Override + public boolean isRequireConsentForStorkAttributes() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getStorkAPs() + */ + @Override + public List getStorkAPs() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getBKUSelectionTemplate() + */ + @Override + public byte[] getBKUSelectionTemplate() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getSendAssertionTemplate() + */ + @Override + public byte[] getSendAssertionTemplate() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPepsList() + */ + @Override + public List getPepsList() { + // TODO Auto-generated method stub + return null; + } + + /** + * @param isBusinessService the isBusinessService to set + */ + public void setBusinessService(boolean isBusinessService) { + this.isBusinessService = isBusinessService; + } + + /** + * @param target the target to set + */ + public void setTarget(String target) { + this.target = target; + } + + /** + * @param businessTarget the businessTarget to set + */ + public void setBusinessTarget(String businessTarget) { + this.businessTarget = businessTarget; + } + + /** + * @param inderfederatedIDP the inderfederatedIDP to set + */ + public void setInderfederatedIDP(boolean inderfederatedIDP) { + this.inderfederatedIDP = inderfederatedIDP; + } + + /** + * @param iDPQueryURL the iDPQueryURL to set + */ + public void setIDPQueryURL(String iDPQueryURL) { + IDPQueryURL = iDPQueryURL; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getPublicURLPrefix() + */ + @Override + public String getPublicURLPrefix() { + return this.applicationID; + } + + /** + * @param applicationID the applicationID to set + */ + public void setApplicationID(String applicationID) { + this.applicationID = applicationID; + } + + + +} 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 e73bac41c..7a9d2cfc1 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 @@ -131,10 +131,17 @@ public class AuthenticationData implements IAuthData, Serializable { private MISMandate mandate = null; private String mandateReferenceValue = null; - private boolean foreigner; + private boolean foreigner =false; private String QAALevel = null; - private boolean ssoSession; + private boolean ssoSession = false; + + private boolean interfederatedSSOSession = false; + private String interfederatedIDP = null; + + private String sessionIndex = null; + private String nameID = null; + private String nameIDFormat = null; public AuthenticationData() { issueInstant = new Date(); @@ -575,10 +582,78 @@ public class AuthenticationData implements IAuthData, Serializable { public void setCcc(String ccc) { this.ccc = ccc; } + + /** + * @return the sessionIndex + */ + public String getSessionIndex() { + return sessionIndex; + } + + /** + * @param sessionIndex the sessionIndex to set + */ + public void setSessionIndex(String sessionIndex) { + this.sessionIndex = sessionIndex; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.data.IAuthData#getNameID() + */ + @Override + public String getNameID() { + return this.nameID; + } + + /** + * @param nameID the nameID to set + */ + public void setNameID(String nameID) { + this.nameID = nameID; + } + + /** + * @return the nameIDFormat + */ + public String getNameIDFormat() { + return nameIDFormat; + } + + /** + * @param nameIDFormat the nameIDFormat to set + */ + public void setNameIDFormat(String nameIDFormat) { + 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; + } - - - } 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 699bd871b..4ea81f134 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 @@ -42,6 +42,7 @@ public interface IAuthData { String getIssuer(); boolean isSsoSession(); + boolean isInterfederatedSSOSession(); boolean isUseMandate(); String getFamilyName(); @@ -52,6 +53,8 @@ public interface IAuthData { String getBPK(); String getBPKType(); + String getInterfederatedIDP(); + String getIdentificationValue(); String getIdentificationType(); @@ -71,6 +74,10 @@ public interface IAuthData { String getQAALevel(); + String getSessionIndex(); + String getNameID(); + String getNameIDFormat(); + boolean isForeigner(); String getCcc(); STORKAuthnRequest getStorkAuthnRequest(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationImpl.java index 971222b67..02bd74291 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationImpl.java @@ -32,10 +32,12 @@ public class SLOInformationImpl implements SLOInformationInterface { private String sessionIndex = null; private String nameID = null; private String protocolType = null; + private String nameIDFormat = null; - public SLOInformationImpl(String sessionID, String nameID, String protocolType) { + public SLOInformationImpl(String sessionID, String nameID, String nameIDFormat, String protocolType) { this.sessionIndex = sessionID; this.nameID = nameID; + this.nameIDFormat = nameIDFormat; this.protocolType = protocolType; } @@ -100,6 +102,25 @@ public class SLOInformationImpl implements SLOInformationInterface { public String getProtocolType() { return protocolType; } + + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.data.SLOInformationInterface#getUserNameIDFormat() + */ + @Override + public String getUserNameIDFormat() { + return this.nameIDFormat; + } + + + /** + * @param nameIDFormat the nameIDFormat to set + */ + public void setNameIDFormat(String nameIDFormat) { + this.nameIDFormat = nameIDFormat; + } + + diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationInterface.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationInterface.java index 7290665e9..2c5682c0f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationInterface.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/SLOInformationInterface.java @@ -53,6 +53,11 @@ public interface SLOInformationInterface { * return authentication protocol type */ public String getProtocolType(); + + /** + * @return + */ + public String getUserNameIDFormat(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java index 2f4bbbcf4..9f1b6b3e8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java @@ -249,26 +249,38 @@ public class DispatcherServlet extends AuthServlet{ try { protocolRequest = info.preProcess(req, resp, action); - if (protocolRequest != null && - MiscUtil.isEmpty(protocolRequest.getRequestID())) { - - //Start new Authentication - protocolRequest.setAction(action); - protocolRequest.setModule(module); - protocolRequestID = Random.nextRandom(); - protocolRequest.setRequestID(protocolRequestID); - - RequestStorage.setPendingRequest(protocolRequest); - - Logger.debug(DispatcherServlet.class.getName()+": Create PendingRequest with ID " + protocolRequestID + "."); - - } else if (protocolRequest != null && + //request is a valid interfederation response + if (protocolRequest != null && protocolRequest.getInterfederationResponse() != null ) { Logger.debug("Create new interfederated MOA-Session and add to HTTPRequest"); + + //reload SP protocol implementation + info = ModulStorage.getModuleByPath(protocolRequest.requestedModule()); + moduleAction = info.getAction(protocolRequest.requestedAction()); + + //create interfederated mOASession String sessionID = AuthenticationSessionStoreage.createInterfederatedSession(protocolRequest, true); req.getParameterMap().put(PARAM_SESSIONID, sessionID); + Logger.info("PreProcessing of SSO interfederation response complete. "); - + + //request is a not valid interfederation response -> Restart local authentication + } else if (protocolRequest != null && + MiscUtil.isNotEmpty(protocolRequest.getRequestID())) { + Logger.info("PreProcessing of SSO interfederation response FAILED. Starting local authentication ..."); + + //request is a new authentication request + } else if (protocolRequest != null && + MiscUtil.isEmpty(protocolRequest.getRequestID())) { + //Start new Authentication + protocolRequest.setAction(action); + protocolRequest.setModule(module); + protocolRequestID = Random.nextRandom(); + protocolRequest.setRequestID(protocolRequestID); + RequestStorage.setPendingRequest(protocolRequest); + Logger.debug(DispatcherServlet.class.getName()+": Create PendingRequest with ID " + protocolRequestID + "."); + + } else { Logger.error("Failed to generate a valid protocol request!"); resp.setContentType("text/html;charset=UTF-8"); @@ -335,7 +347,7 @@ public class DispatcherServlet extends AuthServlet{ } - isValidSSOSession = ssomanager.isValidSSOSession(ssoId, req); + isValidSSOSession = ssomanager.isValidSSOSession(ssoId, protocolRequest); useSSOOA = oaParam.useSSO(); @@ -445,7 +457,7 @@ public class DispatcherServlet extends AuthServlet{ //Advanced statistic logging StatisticLogger logger = StatisticLogger.getInstance(); - logger.logSuccessOperation(protocolRequest, moasession, isSSOSession); + logger.logSuccessOperation(protocolRequest, authData, isSSOSession); } 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 c29c3a1b3..aaeb84f92 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,10 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.moduls; +import java.util.List; + +import org.opensaml.saml2.core.Attribute; + import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse; public interface IRequest { @@ -38,6 +42,7 @@ public interface IRequest { public String getRequestID(); public String getRequestedIDP(); public MOAResponse getInterfederationResponse(); + public List getRequestedAttributes(); //public void setTarget(); } 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 684c6630a..c2e6cd273 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 @@ -31,11 +31,14 @@ import javax.servlet.http.HttpServletResponse; import org.hibernate.Query; import org.hibernate.Session; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore; +import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OldSSOSessionIDStore; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; @@ -68,7 +71,7 @@ public class SSOManager { return instance; } - public boolean isValidSSOSession(String ssoSessionID, HttpServletRequest httpReq) { + public boolean isValidSSOSession(String ssoSessionID, IRequest protocolRequest) { // search SSO Session if (ssoSessionID == null) { @@ -76,10 +79,36 @@ public class SSOManager { return false; } - // String moaSessionId =HTTPSessionUtils.getHTTPSessionString(httpReq.getSession(), - // AuthenticationManager.MOA_SESSION, null); + AuthenticatedSessionStore storedSession = AuthenticationSessionStoreage.isValidSessionWithSSOID(ssoSessionID, null); - return AuthenticationSessionStoreage.isValidSessionWithSSOID(ssoSessionID, null); + if (storedSession == null) + return false; + + else { + if (protocolRequest != null && + protocolRequest instanceof RequestImpl && + storedSession.isInterfederatedSSOSession()) { + + if (MiscUtil.isEmpty(((RequestImpl) protocolRequest).getRequestedIDP())) { + InterfederationSessionStore selectedIDP = AuthenticationSessionStoreage.searchInterfederatedIDPFORSSOWithMOASession(storedSession.getSessionid()); + + if (selectedIDP != null) { + //no local SSO session exist -> request interfederated IDP + ((RequestImpl) protocolRequest).setRequestedIDP(selectedIDP.getIdpurlprefix()); + + } else { + Logger.warn("MOASession is marked as interfederated SSO session but no interfederated IDP is found. Switch to local authentication ..."); + MOASessionDBUtils.delete(storedSession); + + } + } + + return false; + + } + + return true; + } } @@ -95,24 +124,10 @@ public class SSOManager { List result; synchronized (session) { - -// try { -// session.getTransaction().rollback(); -// } -// catch (Exception e) { -// e.printStackTrace(); -// } -// try { -// session.getSessionFactory().openSession(); -// } -// catch (Exception e) { -// e.printStackTrace(); -// } - // session.getTransaction().begin(); - + session.beginTransaction(); Query query = session.getNamedQuery("getSSOSessionWithOldSessionID"); - query.setString("sessionid", ssoId); + query.setParameter("sessionid", ssoId); result = query.list(); // send transaction @@ -198,4 +213,44 @@ public class SSOManager { } } } + + /** + * @param entityID + * @param request + */ + public boolean removeInterfederatedSSOIDP(String entityID, + HttpServletRequest request) { + + String ssoSessionID = getSSOSessionID(request); + + if (MiscUtil.isNotEmpty(ssoSessionID)) { + + AuthenticatedSessionStore storedSession = AuthenticationSessionStoreage.isValidSessionWithSSOID(ssoSessionID, null); + + if (storedSession == null) + return false; + + InterfederationSessionStore selectedIDP = AuthenticationSessionStoreage.searchInterfederatedIDPFORSSOWithMOASessionIDPID(storedSession.getSessionid(), entityID); + + if (selectedIDP != null) { + //no local SSO session exist -> request interfederated IDP + Logger.info("Delete interfederated IDP " + selectedIDP.getIdpurlprefix() + + " from MOASession " + storedSession.getSessionid()); + MOASessionDBUtils.delete(selectedIDP); + + } else { + Logger.warn("MOASession is marked as interfederated SSO session but no interfederated IDP is found. Switch to local authentication ..."); + + } + + + + + return true; + + } else + return false; + + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java index 9376e3d58..3b0d07ce1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/attributes/OAuth20AttributeBuilder.java @@ -215,4 +215,41 @@ public final class OAuth20AttributeBuilder { final OAAuthParameter oaParam, final IAuthData authData) { addAttibutes(buildersSTORK, jsonObject, oaParam, authData); } + + /** + * @return the buildersprofile + */ + public static List getBuildersprofile() { + return buildersProfile; + } + + /** + * @return the builderseid + */ + public static List getBuilderseid() { + return buildersEID; + } + + /** + * @return the builderseidgov + */ + public static List getBuilderseidgov() { + return buildersEIDGov; + } + + /** + * @return the buildersmandate + */ + public static List getBuildersmandate() { + return buildersMandate; + } + + /** + * @return the buildersstork + */ + public static List getBuildersstork() { + return buildersSTORK; + } + + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java index 2a1fe0882..4c70ce995 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java @@ -100,7 +100,7 @@ class OAuth20AuthAction implements IAction { //TODO: maybe add bPK / wbPK to SLO information - SLOInformationInterface sloInformation = new SLOInformationImpl(accessToken, null, req.requestedModule()); + SLOInformationInterface sloInformation = new SLOInformationImpl(accessToken, null, null, req.requestedModule()); return sloInformation; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java index 6a9e98792..c47e366a1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java @@ -22,7 +22,9 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.oauth20.protocol; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -31,12 +33,18 @@ import org.opensaml.saml2.core.Attribute; import at.gv.egovernment.moa.id.commons.db.dao.config.OAOAUTH20; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util; +import at.gv.egovernment.moa.id.protocols.oauth20.attributes.OAuth20AttributeBuilder; import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20AccessDeniedException; import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception; import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20ResponseTypeException; import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20WrongParameterException; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.IAttributeBuilder; +import at.gv.egovernment.moa.logging.Logger; class OAuth20AuthRequest extends OAuth20BaseRequest { @@ -163,7 +171,42 @@ class OAuth20AuthRequest extends OAuth20BaseRequest { */ @Override public List getRequestedAttributes() { - //TODO: implement attribut mapping - return null; + Map reqAttr = new HashMap(); + for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) + reqAttr.put(el, ""); + + try { + OAAuthParameter oa = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(getOAURL()); + + for (String s : scope.split(" ")) { + if (s.equalsIgnoreCase("profile")) { + for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersprofile()) + reqAttr.put(el.getName(), ""); + + } else if (s.equalsIgnoreCase("eID")) { + for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuilderseid()) + reqAttr.put(el.getName(), ""); + + } else if (s.equalsIgnoreCase("eID_gov")) { + for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuilderseidgov()) + reqAttr.put(el.getName(), ""); + + } else if (s.equalsIgnoreCase("mandate")) { + for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersmandate()) + reqAttr.put(el.getName(), ""); + + } else if (s.equalsIgnoreCase("stork")) { + for (IAttributeBuilder el :OAuth20AttributeBuilder.getBuildersstork()) + reqAttr.put(el.getName(), ""); + + } + } + + return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.keySet().iterator()); + + } catch (ConfigurationException e) { + Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e); + return null; + } } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java index 00b7a83f0..951960bc6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20Protocol.java @@ -2,6 +2,7 @@ package at.gv.egovernment.moa.id.protocols.oauth20.protocol; import java.net.URLEncoder; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -16,11 +17,14 @@ import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Constants; import at.gv.egovernment.moa.id.protocols.oauth20.OAuth20Util; import at.gv.egovernment.moa.id.protocols.oauth20.exceptions.OAuth20Exception; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import com.google.gson.JsonObject; +import edu.emory.mathcs.backport.java.util.Arrays; + public class OAuth20Protocol implements IModulInfo { public static final String NAME = OAuth20Protocol.class.getName(); @@ -29,6 +33,13 @@ public class OAuth20Protocol implements IModulInfo { public static final String AUTH_ACTION = "AUTH"; public static final String TOKEN_ACTION = "TOKEN"; + @SuppressWarnings("unchecked") + public static final List DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList( + new String[] { + PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, + PVPConstants.BPK_NAME + }); + private static HashMap actions = new HashMap(); static { 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 new file mode 100644 index 000000000..71d1c26d4 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -0,0 +1,178 @@ +/* + * 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; + + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.joda.time.DateTime; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeQuery; +import org.opensaml.saml2.core.Response; +import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.xml.security.SecurityException; + +import edu.emory.mathcs.backport.java.util.Arrays; + +import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.data.SLOInformationInterface; +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.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.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class AttributQueryAction implements IAction { + + @SuppressWarnings("unchecked") + private final static List DEFAULTSTORKATTRIBUTES = Arrays.asList( + new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); + + @SuppressWarnings("unchecked") + private final static List DEFAULTMANDATEATTRIBUTES = Arrays.asList( + new String[]{ PVPConstants.MANDATE_FULL_MANDATE_NAME, + PVPConstants.MANDATE_PROF_REP_OID_NAME}); + + + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) + */ + @Override + public SLOInformationInterface processRequest(IRequest req, + HttpServletRequest httpReq, HttpServletResponse httpResp, + IAuthData authData) throws MOAIDException { + + if (req instanceof PVPTargetConfiguration && + ((PVPTargetConfiguration) req).getRequest() instanceof MOARequest && + ((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest() instanceof AttributeQuery) { + + AttributeQuery attrQuery = (AttributeQuery)((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest(); + + //load moaSession + String nameID = attrQuery.getSubject().getNameID().getValue(); + + AuthenticationSession session = AuthenticationSessionStoreage.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); + + } + + DateTime date = new DateTime(); + + //generate authData + authData = AuthenticationDataBuilder.buildAuthenticationData(req, session, attrQuery.getAttributes()); + + //add default attributes in case of mandates or STORK is in use + List attrList = addDefaultAttributes(attrQuery, authData); + + //build PVP 2.1 assertion + Assertion assertion = PVP2AssertionBuilder.buildAssertion(attrQuery, attrList, authData, date, authData.getSessionIndex()); + + //build PVP 2.1 response + Response authResponse = AuthResponseBuilder.buildResponse(attrQuery, date, assertion); + + try { + SoapBinding decoder = new SoapBinding(); + decoder.encodeRespone(httpReq, httpResp, authResponse, null, null); + return null; + + } catch (MessageEncodingException e) { + Logger.error("Message Encoding exception", e); + throw new MOAIDException("pvp2.01", null, e); + + } catch (SecurityException e) { + Logger.error("Security exception", e); + throw new MOAIDException("pvp2.01", null, e); + + } + + } else { + Logger.error("Process AttributeQueryAction but request is NOT of type AttributQuery."); + throw new MOAIDException("pvp2.13", null); + + } + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, + HttpServletResponse httpResp) { + return false; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName() + */ + @Override + public String getDefaultActionName() { + return PVP2XProtocol.ATTRIBUTEQUERY; + } + + private List addDefaultAttributes(AttributeQuery query, IAuthData authData) { + + List reqAttributs = new ArrayList(); + + for (Attribute attr : query.getAttributes()) { + reqAttributs.add(attr.getName()); + + } + + //add default STORK attributes if it is a STORK authentication + if (authData.isForeigner() && !reqAttributs.containsAll(DEFAULTSTORKATTRIBUTES)) { + for (String el : DEFAULTSTORKATTRIBUTES) { + if (!reqAttributs.contains(el)) + reqAttributs.add(el); + } + } + + //add default mandate attributes if it is a authentication with mandates + if (authData.isUseMandate() && !reqAttributs.containsAll(DEFAULTMANDATEATTRIBUTES)) { + for (String el : DEFAULTMANDATEATTRIBUTES) { + if (!reqAttributs.contains(el)) + reqAttributs.add(el); + } + } + + return reqAttributs; + } +} 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 7410e0624..70db9cc23 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 @@ -39,6 +39,7 @@ public class AuthenticationAction implements IAction { HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { PVPTargetConfiguration pvpRequest = (PVPTargetConfiguration) req; + SLOInformationImpl sloInformation = (SLOInformationImpl) RequestManager.getInstance().handle(pvpRequest.request, httpReq, httpResp, authData); //set protocol type 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 639b8672b..d04480ff5 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 @@ -24,6 +24,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x; import iaik.pkcs.pkcs11.objects.Object; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -31,59 +32,66 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.TransformerException; import org.apache.commons.lang.StringEscapeUtils; import org.joda.time.DateTime; import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.AttributeQuery; import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.Conditions; -import org.opensaml.saml2.core.EncryptedAssertion; -import org.opensaml.saml2.core.RequestAbstractType; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.LogoutRequest; +import org.opensaml.saml2.core.LogoutResponse; +import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.Status; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusMessage; import org.opensaml.saml2.core.impl.AuthnRequestImpl; -import org.opensaml.saml2.encryption.Decrypter; -import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver; import org.opensaml.saml2.metadata.AssertionConsumerService; import org.opensaml.saml2.metadata.AttributeConsumingService; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; -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.keyinfo.StaticKeyInfoCredentialResolver; -import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.signature.SignableXMLObject; + +import edu.emory.mathcs.backport.java.util.Arrays; 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.MOAIDException; import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IModulInfo; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.moduls.NoPassivAuthenticationException; import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.moduls.SSOManager; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IDecoder; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding; 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.binding.PostBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +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.exceptions.MandateAttributesNotHandleAbleException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NameIDFormatNotSupportedException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; -import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider; -import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; 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.verification.SAMLVerificationEngine; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; import at.gv.egovernment.moa.id.util.VelocityLogAdapter; import at.gv.egovernment.moa.logging.Logger; @@ -96,18 +104,27 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { public static final String POST = "Post"; public static final String SOAP = "Soap"; public static final String METADATA = "Metadata"; + public static final String ATTRIBUTEQUERY = "AttributeQuery"; private static List decoder = new ArrayList(); private static HashMap actions = new HashMap(); + @SuppressWarnings("unchecked") + public static final List DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList( + new String[] { + PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME + }); + static { decoder.add(new PostBinding()); decoder.add(new RedirectBinding()); + decoder.add(new SoapBinding()); actions.put(REDIRECT, new AuthenticationAction()); actions.put(POST, new AuthenticationAction()); actions.put(METADATA, new MetadataAction()); + actions.put(ATTRIBUTEQUERY, new AttributQueryAction()); //TODO: insert getArtifact action @@ -179,9 +196,22 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { } - if (msg instanceof MOARequest) + if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof AuthnRequest) return preProcessAuthRequest(request, response, (MOARequest) msg); + else if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof AttributeQuery) + return preProcessAttributQueryRequest(request, response, (MOARequest) msg); + + else if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof LogoutRequest) + return preProcessLogOut(request, response, (MOARequest) msg); + + else if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof LogoutResponse) + return preProcessLogOut(request, response, (MOARequest) msg); + else if (msg instanceof MOAResponse) { //load service provider AuthRequest from session @@ -192,12 +222,17 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { MOAResponse processedMsg = preProcessAuthResponse((MOAResponse) msg); if ( processedMsg != null ) { - iReqSP.setInterfederationResponse((MOAResponse) msg); + iReqSP.setInterfederationResponse(processedMsg); } else { Logger.info("Receive NO valid SSO session from " + msg.getEntityID() - +". Switch to local authentication process ..."); - iReqSP.setRequestedIDP(null); + +". Switch to local authentication process ..."); + + SSOManager ssomanager = SSOManager.getInstance(); + ssomanager.removeInterfederatedSSOIDP(msg.getEntityID(), request); + + iReqSP.setRequestedIDP(null); + } return iReqSP; @@ -206,11 +241,8 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { Logger.error("Stored PVP21 authrequest from service provider has an unsuppored type."); return null; - - } - - - else { + + } else { Logger.error("Receive unsupported PVP21 message"); throw new MOAIDException("Unsupported PVP21 message", new Object[] {}); } @@ -273,16 +305,27 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { samlResponse.setStatus(status); String remoteSessionID = SAML2Utils.getSecureIdentifier(); samlResponse.setID(remoteSessionID); - + + samlResponse.setIssueInstant(new DateTime()); + Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); + nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath()); + nissuer.setFormat(NameID.ENTITY); + samlResponse.setIssuer(nissuer); + IEncoder encoder = null; - if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { encoder = new RedirectBinding(); - } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_ARTIFACT_BINDING_URI)) { + + } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_ARTIFACT_BINDING_URI)) { // TODO: not supported YET!! //binding = new ArtifactBinding(); + } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { encoder = new PostBinding(); + + } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) { + encoder = new SoapBinding(); } if(encoder == null) { @@ -323,10 +366,75 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { return true; } + + /** + * PreProcess Single LogOut request + * @param request + * @param response + * @param msg + * @return + */ + private IRequest preProcessLogOut(HttpServletRequest request, + HttpServletResponse response, MOARequest msg) { + // TODO Auto-generated method stub + return null; + } + + /** + * PreProcess AttributeQuery request + * @param request + * @param response + * @param moaRequest + * @return + * @throws Throwable + */ + private IRequest preProcessAttributQueryRequest(HttpServletRequest request, + HttpServletResponse response, MOARequest moaRequest) throws Throwable { + + AttributeQuery attrQuery = (AttributeQuery) moaRequest.getSamlRequest(); + moaRequest.setEntityID(attrQuery.getIssuer().getValue()); + + //validate destination + String destinaten = attrQuery.getDestination(); + if (!PVPConfiguration.getInstance().getIDPAttributeQueryService().equals(destinaten)) { + Logger.warn("AttributeQuery destination does not match IDP AttributeQueryService URL"); + throw new AttributQueryException("AttributeQuery destination does not match IDP AttributeQueryService URL", null); + + } + + //check if Issuer is an interfederation IDP + // check parameter + if (!ParamValidatorUtils.isValidOA(moaRequest.getEntityID())) + throw new WrongParametersException("StartAuthentication", + PARAM_OA, "auth.12"); + + OAAuthParameter oa = AuthConfigurationProvider.getInstance().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); + + } + + PVPTargetConfiguration config = new PVPTargetConfiguration(); + config.setRequest(moaRequest); + config.setOAURL(moaRequest.getEntityID()); + config.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); + + return config; + } + + /** + * PreProcess Authn request + * @param request + * @param response + * @param moaRequest + * @return + * @throws Throwable + */ private IRequest preProcessAuthRequest(HttpServletRequest request, HttpServletResponse response, MOARequest moaRequest) throws Throwable { - RequestAbstractType samlReq = moaRequest.getSamlRequest(); + SignableXMLObject samlReq = moaRequest.getSamlRequest(); if(!(samlReq instanceof AuthnRequest)) { throw new MOAIDException("Unsupported request", new Object[] {}); @@ -398,6 +506,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { } /** + * PreProcess AuthResponse and Assertion * @param msg */ private MOAResponse preProcessAuthResponse(MOAResponse msg) { @@ -406,67 +515,29 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { try { if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { - List saml2assertions = new ArrayList(); - //check encrypted Assertion - List encryAssertionList = samlResp.getEncryptedAssertions(); - if (encryAssertionList != null && encryAssertionList.size() > 0) { - //decrypt assertions - - Logger.debug("Found encryped assertion. Start decryption ..."); - - X509Credential authDecCredential = CredentialProvider.getIDPAssertionEncryptionCredential(); - - StaticKeyInfoCredentialResolver skicr = - new StaticKeyInfoCredentialResolver(authDecCredential); - - 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 = samlResp.getAssertions(); - - } + //validate PVP 2.1 assertion + SAMLVerificationEngine.validateAssertion(samlResp, true); + + msg.setSAMLMessage(SAML2Utils.asDOMDocument(samlResp).getDocumentElement()); + return msg; + + } else if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.NO_PASSIVE_URI)) { + Logger.info("Interfederation IDP has no valid Single Sign-On session. Starting local authentication ..."); - for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { - - Conditions conditions = saml2assertion.getConditions(); - DateTime notbefore = conditions.getNotBefore(); - DateTime notafter = conditions.getNotOnOrAfter(); - if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) { - Logger.warn("PVP2 Assertion is out of Date"); - return null; - - } - - samlResp.getAssertions().clear(); - samlResp.getEncryptedAssertions().clear(); - samlResp.getAssertions().addAll(saml2assertions); - - msg.setSAMLMessage(samlResp.getDOM()); - return msg; - - } } + + } catch (IOException e) { + Logger.warn("Interfederation response marshaling FAILED.", e); - } catch (CredentialsNotAvailableException e) { - Logger.warn("Assertion decrypt FAILED - No Credentials", e); + } catch (MarshallingException e) { + Logger.warn("Interfederation response marshaling FAILED.", e); - } catch (DecryptionException e) { - Logger.warn("Assertion decrypt FAILED.", e); + } catch (TransformerException e) { + Logger.warn("Interfederation response marshaling FAILED.", e); + } catch (AssertionValidationExeption e) { + //error is already logged, to nothing } return null; 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 7946c7596..dafaf6279 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 @@ -39,6 +39,8 @@ public interface PVPConstants { public static final String STORK_QAA_1_3 = "http://www.stork.gov.eu/1.0/citizenQAALevel/3"; public static final String STORK_QAA_1_4 = "http://www.stork.gov.eu/1.0/citizenQAALevel/4"; + public static final String STORK_ATTRIBUTE_PREFIX = "http://www.stork.gov.eu/1.0/"; + public static final String URN_OID_PREFIX = "urn:oid:"; public static final String PVP_VERSION_OID = "1.2.40.0.10.2.1.1.261.10"; 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 9cddb9a17..96e2bf7e9 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 @@ -22,27 +22,40 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.impl.AuthnRequestImpl; +import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.moduls.RequestImpl; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException; +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.logging.Logger; public class PVPTargetConfiguration extends RequestImpl { private static final long serialVersionUID = 4889919265919638188L; - MOARequest request; + InboundMessage request; String binding; String consumerURL; - public MOARequest getRequest() { + public InboundMessage getRequest() { return request; } - public void setRequest(MOARequest request) { + public void setRequest(InboundMessage request) { this.request = request; } @@ -68,7 +81,59 @@ public class PVPTargetConfiguration extends RequestImpl { */ @Override public List getRequestedAttributes() { - // TODO Auto-generated method stub - return null; + + Map reqAttr = new HashMap(); + for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) + reqAttr.put(el, ""); + + try { + OAAuthParameter oa = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(getOAURL()); + + SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata().getSPSSODescriptor(SAMLConstants.SAML20P_NS); + if (spSSODescriptor.getAttributeConsumingServices() != null && + spSSODescriptor.getAttributeConsumingServices().size() > 0) { + + Integer aIdx = null; + if (getRequest() instanceof MOARequest && + ((MOARequest)getRequest()).getSamlRequest() instanceof AuthnRequestImpl) { + AuthnRequestImpl authnRequest = (AuthnRequestImpl)((MOARequest)getRequest()).getSamlRequest(); + aIdx = authnRequest.getAttributeConsumingServiceIndex(); + + } else { + Logger.error("MOARequest is NOT of type AuthnRequest"); + } + + int idx = 0; + + AttributeConsumingService attributeConsumingService = null; + + if (aIdx != null) { + idx = aIdx.intValue(); + attributeConsumingService = spSSODescriptor + .getAttributeConsumingServices().get(idx); + + } else { + List attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices(); + for (AttributeConsumingService el : attrConsumingServiceList) { + if (el.isDefault()) + attributeConsumingService = el; + } + } + + for ( RequestedAttribute attr : attributeConsumingService.getRequestAttributes()) + reqAttr.put(attr.getName(), ""); + } + + return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.keySet().iterator()); + + } catch (NoMetadataInformationException e) { + Logger.warn("NO metadata found for Entity " + getRequest().getEntityID()); + return null; + + } catch (ConfigurationException e) { + Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e); + return null; + } + } } 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 645d15086..020055139 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 @@ -49,6 +49,7 @@ import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; import org.opensaml.xml.security.x509.X509Credential; 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.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; @@ -189,7 +190,7 @@ public class PostBinding implements IDecoder, IEncoder { } public boolean handleDecode(String action, HttpServletRequest req) { - return (req.getMethod().equals("POST")); + return (req.getMethod().equals("POST") && action.equals(PVP2XProtocol.POST)); } } 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 ec24a2a0d..ec7c117b9 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 @@ -22,6 +22,8 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.binding; +import java.util.List; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -33,43 +35,64 @@ import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.StatusResponseType; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.soap.client.BasicSOAPMessageContext; +import org.opensaml.ws.soap.soap11.Envelope; import org.opensaml.ws.soap.soap11.decoder.http.HTTPSOAP11Decoder; import org.opensaml.ws.transport.http.HttpServletRequestAdapter; import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.signature.SignableXMLObject; import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; 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.signer.CredentialProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; +import at.gv.egovernment.moa.logging.Logger; public class SoapBinding implements IDecoder, IEncoder { public InboundMessageInterface decode(HttpServletRequest req, HttpServletResponse resp) throws MessageDecodingException, SecurityException, PVP2Exception { - HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(); - BasicSAMLMessageContext messageContext = - new BasicSAMLMessageContext(); + HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); + BasicSAMLMessageContext messageContext = + new BasicSAMLMessageContext(); messageContext .setInboundMessageTransport(new HttpServletRequestAdapter( req)); + soapDecoder.decode(messageContext); - - RequestAbstractType inboundMessage = (RequestAbstractType) messageContext + + Envelope inboundMessage = (Envelope) messageContext .getInboundMessage(); - MOARequest request = new MOARequest(inboundMessage); + if (inboundMessage.getBody() != null) { + List xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); + + if (!xmlElemList.isEmpty()) { + SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); + MOARequest request = new MOARequest(attrReq); + + request.setVerified(false); + return request; + + } + } - return request; + Logger.error("Receive empty PVP 2.1 attributequery request."); + throw new AttributQueryException("Receive empty PVP 2.1 attributequery request.", null); } public boolean handleDecode(String action, HttpServletRequest req) { - return (action.equals(PVP2XProtocol.SOAP)); + return (req.getMethod().equals("POST") && + (action.equals(PVP2XProtocol.SOAP) || action.equals(PVP2XProtocol.ATTRIBUTEQUERY))); } public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java new file mode 100644 index 000000000..6296d102f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java @@ -0,0 +1,185 @@ +/* + * 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.builder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.joda.time.DateTime; +import org.opensaml.Configuration; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeQuery; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.impl.AttributeQueryBuilder; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureConstants; +import org.opensaml.xml.signature.SignatureException; +import org.opensaml.xml.signature.Signer; +import org.w3c.dom.Document; + +import at.gv.egovernment.moa.id.config.ConfigurationException; +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.builder.attributes.SamlAttributeGenerator; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; + +/** + * @author tlenz + * + */ +public class AttributQueryBuilder { + + public static List buildSAML2AttributeList(OAAuthParameter oa, Iterator iterator) { + + Logger.debug("Build OA specific Attributes for AttributQuery request"); + + List attrList = new ArrayList(); + + SamlAttributeGenerator generator = new SamlAttributeGenerator(); + + while(iterator.hasNext()) { + String rA = iterator.next(); + Attribute attr = PVPAttributeBuilder.buildEmptyAttribute(rA); + if (attr == null) { + Logger.warn("Attribut " + rA + " has no valid Name"); + + } else { + //add OA specific information + if (rA.equals(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) { + if (oa.getBusinessService()) + attr = generator.buildStringAttribute(attr.getFriendlyName(), + attr.getName(), oa.getIdentityLinkDomainIdentifier()); + else + attr = generator.buildStringAttribute(attr.getFriendlyName(), + attr.getName(), Constants.URN_PREFIX_CDID + "+" + oa.getTarget()); + } + + //TODO: add attribute values for SSO with mandates (ProfileList) + + + attrList.add(attr); + } + } + + return attrList; + } + + + public static AttributeQuery buildAttributQueryRequest(String nameID, + String endpoint, List requestedAttributes) throws AttributQueryException { + + + try { + + AttributeQuery query = new AttributeQueryBuilder().buildObject(); + + //set user nameID + Subject subject = SAML2Utils.createSAMLObject(Subject.class); + NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); + subjectNameID.setValue(nameID); + subjectNameID.setFormat(NameID.TRANSIENT); + subject.setNameID(subjectNameID); + query.setSubject(subject); + + //set attributes + query.getAttributes().addAll(requestedAttributes); + + //set general request parameters + DateTime now = new DateTime(); + query.setIssueInstant(now); + + Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); + nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath()); + nissuer.setFormat(NameID.ENTITY); + query.setIssuer(nissuer); + + String sessionID = SAML2Utils.getSecureIdentifier(); + query.setID(sessionID); + + query.setDestination(endpoint); + + X509Credential idpSigningCredential = CredentialProvider.getIDPAssertionSigningCredential(); + + Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(idpSigningCredential); + query.setSignature(signer); + + DocumentBuilder builder; + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); + + builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + Marshaller out = Configuration.getMarshallerFactory() + .getMarshaller(query); + out.marshall(query, document); + + Signer.signObject(signer); + + return query; + + } catch (ConfigurationException e) { + Logger.error("Build AttributQuery Request FAILED.", e); + throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e); + + } catch (CredentialsNotAvailableException e) { + Logger.error("Build AttributQuery Request FAILED.", e); + throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e); + + } catch (ParserConfigurationException e) { + Logger.error("Build AttributQuery Request FAILED.", e); + throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e); + + } catch (MarshallingException e) { + Logger.error("Build AttributQuery Request FAILED.", e); + throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e); + + } catch (SignatureException e) { + Logger.error("Build AttributQuery Request FAILED.", e); + throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e); + + } + + + } + +} 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 new file mode 100644 index 000000000..4ef09184d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java @@ -0,0 +1,152 @@ +/* + * 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.builder; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.joda.time.DateTime; +import org.opensaml.Configuration; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.EncryptedAssertion; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.RequestAbstractType; +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.security.MetadataCredentialResolver; +import org.opensaml.security.MetadataCriteria; +import org.opensaml.xml.encryption.EncryptionException; +import org.opensaml.xml.encryption.EncryptionParameters; +import org.opensaml.xml.encryption.KeyEncryptionParameters; +import org.opensaml.xml.security.CriteriaSet; +import org.opensaml.xml.security.SecurityException; +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.KeyInfoGeneratorFactory; +import org.opensaml.xml.security.x509.X509Credential; + +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +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; + +/** + * @author tlenz + * + */ +public class AuthResponseBuilder { + + public static Response buildResponse(RequestAbstractType req, DateTime date, Assertion assertion) 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) + nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath()); + nissuer.setFormat(NameID.ENTITY); + authResponse.setIssuer(nissuer); + authResponse.setInResponseTo(req.getID()); + + //set responseID + String remoteSessionID = SAML2Utils.getSecureIdentifier(); + authResponse.setID(remoteSessionID); + + + //SAML2 response required IssueInstant + authResponse.setIssueInstant(date); + + authResponse.setStatus(SAML2Utils.getSuccessStatus()); + + //check, if metadata includes an encryption key + MetadataCredentialResolver mdCredResolver = + new MetadataCredentialResolver(MOAMetadataProvider.getInstance()); + + CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) ); + criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); + criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) ); + + X509Credential encryptionCredentials = null; + try { + encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet); + + } catch (SecurityException e2) { + Logger.warn("Can not extract the Assertion Encryption-Key from metadata", e2); + throw new InvalidAssertionEncryptionException(); + + } + + boolean isEncryptionActive = AuthConfigurationProvider.getInstance().isPVP2AssertionEncryptionActive(); + if (encryptionCredentials != null && isEncryptionActive) { + //encrypt SAML2 assertion + + try { + + EncryptionParameters dataEncParams = new EncryptionParameters(); + dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE); + + List keyEncParamList = new ArrayList(); + KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); + + keyEncParam.setEncryptionCredential(encryptionCredentials); + keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE); + KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration() + .getKeyInfoGeneratorManager().getDefaultManager() + .getFactory(encryptionCredentials); + keyEncParam.setKeyInfoGenerator(kigf.newInstance()); + keyEncParamList.add(keyEncParam); + + Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); + //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE); + samlEncrypter.setKeyPlacement(KeyPlacement.PEER); + + EncryptedAssertion encryptAssertion = null; + + encryptAssertion = samlEncrypter.encrypt(assertion); + + authResponse.getEncryptedAssertions().add(encryptAssertion); + + } catch (EncryptionException e1) { + Logger.warn("Can not encrypt the PVP2 assertion", e1); + throw new InvalidAssertionEncryptionException(); + + } + + } else { + authResponse.getAssertions().add(assertion); + + } + + return authResponse; + } +} 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 57f01210d..8b6e71e6b 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 @@ -170,6 +170,22 @@ public class PVPAttributeBuilder { return null; } + public static Attribute buildEmptyAttribute(String name) { + if (builders.containsKey(name)) { + return builders.get(name).buildEmpty(generator); + } + return null; + } + + public static Attribute buildAttribute(String name, String value) { + if (builders.containsKey(name)) { + return builders.get(name).buildEmpty(generator); + } + return null; + } + + + public static List buildSupportedEmptyAttributes() { List attributes = new ArrayList(); Iterator builderIt = builders.values().iterator(); 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 5f16bcfce..79a1c3e0f 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 @@ -23,6 +23,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion; import java.security.MessageDigest; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -30,6 +31,7 @@ import org.joda.time.DateTime; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeQuery; import org.opensaml.saml2.core.AttributeStatement; import org.opensaml.saml2.core.Audience; import org.opensaml.saml2.core.AudienceRestriction; @@ -61,6 +63,7 @@ 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.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; @@ -79,13 +82,65 @@ import at.gv.egovernment.moa.id.util.Random; 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; public class PVP2AssertionBuilder implements PVPConstants { + + public static Assertion buildAssertion(AttributeQuery attrQuery, + List reqAttributes, IAuthData authData, DateTime date, String sessionIndex) throws ConfigurationException { + + + AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); + authnContextClassRef.setAuthnContextClassRef(authData.getQAALevel()); + + List attrList = new ArrayList(); + if (reqAttributes != null) { + Iterator 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); + + } + } + } + + + NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); + subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat()); + subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue()); + + SubjectConfirmationData subjectConfirmationData = null; + + return buildGenericAssertion(attrQuery.getIssuer().getValue(), date, + authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex); + } + public static Assertion buildAssertion(AuthnRequest authnRequest, IAuthData authData, EntityDescriptor peerEntity, DateTime date, AssertionConsumerService assertionConsumerService, SLOInformationImpl sloInformation) throws MOAIDException { - Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class); + RequestedAuthnContext reqAuthnContext = authnRequest .getRequestedAuthnContext(); @@ -149,29 +204,13 @@ public class PVP2AssertionBuilder implements PVPConstants { } } - AuthnContext authnContext = SAML2Utils - .createSAMLObject(AuthnContext.class); - authnContext.setAuthnContextClassRef(authnContextClassRef); - - AuthnStatement authnStatement = SAML2Utils - .createSAMLObject(AuthnStatement.class); - - String sessionIndex = SAML2Utils.getSecureIdentifier(); - authnStatement.setAuthnInstant(date); - authnStatement.setSessionIndex(sessionIndex); - authnStatement.setAuthnContext(authnContext); - assertion.getAuthnStatements().add(authnStatement); SPSSODescriptor spSSODescriptor = peerEntity .getSPSSODescriptor(SAMLConstants.SAML20P_NS); - - AttributeStatement attributeStatement = SAML2Utils - .createSAMLObject(AttributeStatement.class); - - Subject subject = SAML2Utils.createSAMLObject(Subject.class); - + //add Attributes to Assertion + List attrList = new ArrayList(); if (spSSODescriptor.getAttributeConsumingServices() != null && spSSODescriptor.getAttributeConsumingServices().size() > 0) { @@ -192,7 +231,7 @@ public class PVP2AssertionBuilder implements PVPConstants { attributeConsumingService = el; } } - + if (attributeConsumingService != null) { Iterator it = attributeConsumingService .getRequestAttributes().iterator(); @@ -207,7 +246,7 @@ public class PVP2AssertionBuilder implements PVPConstants { reqAttribut.getName()); } } else { - attributeStatement.getAttributes().add(attr); + attrList.add(attr); } } catch (PVP2Exception e) { Logger.error( @@ -231,13 +270,10 @@ public class PVP2AssertionBuilder implements PVPConstants { } } } - if (attributeStatement.getAttributes().size() > 0) { - assertion.getAttributeStatements().add(attributeStatement); - } NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - //TLenz: set correct bPK Type and Value from AuthData + //build nameID and nameID Format from moasession if (authData.isUseMandate()) { Element mandate = authData.getMandate(); if(mandate == null) { @@ -337,21 +373,68 @@ public class PVP2AssertionBuilder implements PVPConstants { } } else - subjectNameID.setFormat(nameIDFormat); - - - subject.setNameID(subjectNameID); - - SubjectConfirmation subjectConfirmation = SAML2Utils - .createSAMLObject(SubjectConfirmation.class); - subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); + subjectNameID.setFormat(nameIDFormat); + + + String sessionIndex = null; + + //if request is a reauthentication and NameIDFormat match reuse old session information + if (MiscUtil.isNotEmpty(authData.getNameID()) && + MiscUtil.isNotEmpty(authData.getNameIDFormat()) && + nameIDFormat.equals(authData.getNameIDFormat())) { + subjectNameID.setValue(authData.getNameID()); + sessionIndex = authData.getSessionIndex(); + + } else + sessionIndex = SAML2Utils.getSecureIdentifier(); + SubjectConfirmationData subjectConfirmationData = SAML2Utils .createSAMLObject(SubjectConfirmationData.class); subjectConfirmationData.setInResponseTo(authnRequest.getID()); subjectConfirmationData.setNotOnOrAfter(date.plusMinutes(5)); subjectConfirmationData.setRecipient(assertionConsumerService.getLocation()); + + //set SLO information + sloInformation.setUserNameIdentifier(subjectNameID.getValue()); + sloInformation.setNameIDFormat(subjectNameID.getFormat()); + sloInformation.setSessionIndex(sessionIndex); + + return buildGenericAssertion(peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex); + } + + private static Assertion buildGenericAssertion(String entityID, DateTime date, + AuthnContextClassRef authnContextClassRef, List attrList, + NameID subjectNameID, SubjectConfirmationData subjectConfirmationData, + String sessionIndex) throws ConfigurationException { + Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class); + + AuthnContext authnContext = SAML2Utils + .createSAMLObject(AuthnContext.class); + authnContext.setAuthnContextClassRef(authnContextClassRef); + + AuthnStatement authnStatement = SAML2Utils + .createSAMLObject(AuthnStatement.class); + + authnStatement.setAuthnInstant(date); + authnStatement.setSessionIndex(sessionIndex); + authnStatement.setAuthnContext(authnContext); + assertion.getAuthnStatements().add(authnStatement); + + AttributeStatement attributeStatement = SAML2Utils + .createSAMLObject(AttributeStatement.class); + attributeStatement.getAttributes().addAll(attrList); + if (attributeStatement.getAttributes().size() > 0) { + assertion.getAttributeStatements().add(attributeStatement); + } + + Subject subject = SAML2Utils.createSAMLObject(Subject.class); + subject.setNameID(subjectNameID); + + SubjectConfirmation subjectConfirmation = SAML2Utils + .createSAMLObject(SubjectConfirmation.class); + subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData); subject.getSubjectConfirmations().add(subjectConfirmation); @@ -361,7 +444,7 @@ public class PVP2AssertionBuilder implements PVPConstants { .createSAMLObject(AudienceRestriction.class); Audience audience = SAML2Utils.createSAMLObject(Audience.class); - audience.setAudienceURI(peerEntity.getEntityID()); + audience.setAudienceURI(entityID); audienceRestriction.getAudiences().add(audience); conditions.setNotBefore(date); @@ -380,11 +463,7 @@ public class PVP2AssertionBuilder implements PVPConstants { assertion.setSubject(subject); assertion.setID(SAML2Utils.getSecureIdentifier()); assertion.setIssueInstant(date); - - //set SLO information - sloInformation.setUserNameIdentifier(subjectNameID.getValue()); - sloInformation.setSessionIndex(sessionIndex); - return assertion; + return assertion; } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java index 6ad3017d1..9b85af9f8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java @@ -22,15 +22,9 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes; -import iaik.x509.X509Certificate; - -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - 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.logging.Logger; public class EIDIssuingNationAttributeBuilder implements IPVPAttributeBuilder { @@ -40,37 +34,7 @@ public class EIDIssuingNationAttributeBuilder implements IPVPAttributeBuilder { public ATT build(OAAuthParameter oaParam, IAuthData authData, IAttributeGenerator g) throws AttributeException { - String countryCode = "AT"; - - - if (authData.getStorkAuthnRequest() != null) { - countryCode = authData.getStorkAuthnRequest() - .getCitizenCountryCode(); - - } else { - - 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()); - countryCode = rdn.getValue().toString(); - break; - } - } - } - - } catch (Exception e) { - Logger.error("Failed to extract country code from certificate", e); - - } - } + String countryCode = authData.getCcc(); return g.buildStringAttribute(EID_ISSUING_NATION_FRIENDLY_NAME, EID_ISSUING_NATION_NAME, countryCode); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java index 9a65157a4..04cc59b10 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java @@ -22,10 +22,14 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes; +import java.io.IOException; + 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.UnavailableAttributeException; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.MiscUtil; public class EIDSTORKTOKEN implements IPVPAttributeBuilder { @@ -48,7 +52,14 @@ public class EIDSTORKTOKEN implements IPVPAttributeBuilder { throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME); } else { - return g.buildStringAttribute(EID_STORK_TOKEN_FRIENDLY_NAME, EID_STORK_TOKEN_NAME, storkResponse); + try { + return g.buildStringAttribute(EID_STORK_TOKEN_FRIENDLY_NAME, EID_STORK_TOKEN_NAME, + Base64Utils.encode(storkResponse.getBytes())); + + } catch (IOException e) { + Logger.warn("Encode AuthBlock BASE64 failed.", e); + throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME); + } } } 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 c189d44a6..255fba093 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 @@ -52,6 +52,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.Contact; import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; @@ -72,6 +73,8 @@ public class PVPConfiguration { public static final String PVP2_METADATA = "/pvp2/metadata"; public static final String PVP2_REDIRECT = "/pvp2/redirect"; public static final String PVP2_POST = "/pvp2/post"; + public static final String PVP2_SOAP = "/pvp2/soap"; + public static final String PVP2_ATTRIBUTEQUERY = "/pvp2/attributequery"; public static final String PVP_CONFIG_FILE = "pvp2config.properties"; @@ -144,6 +147,14 @@ public class PVPConfiguration { return getIDPPublicPath() + PVP2_POST; } + public String getIDPSSOSOAPService() throws ConfigurationException { + return getIDPPublicPath() + PVP2_SOAP; + } + + public String getIDPAttributeQueryService() throws ConfigurationException { + return getIDPPublicPath() + PVP2_ATTRIBUTEQUERY; + } + public String getIDPSSORedirectService() throws ConfigurationException { return getIDPPublicPath() + PVP2_REDIRECT; } @@ -237,7 +248,7 @@ public class PVPConfiguration { public iaik.x509.X509Certificate getTrustEntityCertificate(String entityID) { try { - OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(entityID); + IOAAuthParameters oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(entityID); if (oaParam == null) { Logger.warn("Online Application with ID " + entityID + " not found!"); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java new file mode 100644 index 000000000..69ca4e8f5 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java @@ -0,0 +1,50 @@ +/* + * 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.exceptions; + +/** + * @author tlenz + * + */ +public class AssertionAttributeExtractorExeption extends PVP2Exception { + + /** + * + */ + private static final long serialVersionUID = -6459000942830951492L; + + public AssertionAttributeExtractorExeption(String attributeName) { + super("Parse PVP2.1 assertion FAILED: Attribute " + attributeName + + " can not extract.", null); + } + + public AssertionAttributeExtractorExeption(String messageId, + Object[] parameters) { + super(messageId, parameters); + } + + public AssertionAttributeExtractorExeption() { + super("Parse PVP2.1 assertion FAILED. Interfederation not possible", null); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java new file mode 100644 index 000000000..fcd8472b1 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java @@ -0,0 +1,49 @@ +/* + * 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.exceptions; + +import at.gv.egovernment.moa.id.config.ConfigurationException; + +/** + * @author tlenz + * + */ +public class AssertionValidationExeption extends PVP2Exception { + + private static final long serialVersionUID = -3987805399122286259L; + + public AssertionValidationExeption(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * @param string + * @param object + * @param e + */ + public AssertionValidationExeption(String string, Object[] parameters, + Throwable e) { + super(string, parameters, e); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java new file mode 100644 index 000000000..9008a7183 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java @@ -0,0 +1,44 @@ +/* + * 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.exceptions; + +/** + * @author tlenz + * + */ +public class AttributQueryException extends PVP2Exception { + + /** + * + */ + private static final long serialVersionUID = -4302422507173728748L; + + public AttributQueryException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + public AttributQueryException(String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java index 75442ebb6..f2f8f0a23 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java @@ -28,6 +28,7 @@ import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.xml.io.Unmarshaller; import org.opensaml.xml.io.UnmarshallerFactory; import org.opensaml.xml.io.UnmarshallingException; +import org.opensaml.xml.signature.SignableXMLObject; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.logging.Logger; @@ -36,17 +37,17 @@ public class MOARequest extends InboundMessage{ private static final long serialVersionUID = 8613921176727607896L; - public MOARequest(RequestAbstractType inboundMessage) { + public MOARequest(SignableXMLObject inboundMessage) { setSAMLMessage(inboundMessage.getDOM()); } - public RequestAbstractType getSamlRequest() { + public SignableXMLObject getSamlRequest() { UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage()); try { - return (RequestAbstractType) unmashaller.unmarshall(getInboundMessage()); + return (SignableXMLObject) unmashaller.unmarshall(getInboundMessage()); } catch (UnmarshallingException e) { Logger.warn("AuthnRequest Unmarshaller error", e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java index a1bf92592..303fc2924 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java @@ -34,6 +34,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPAssertionStorage; +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.binding.SoapBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.RequestDeniedException; @@ -42,18 +43,18 @@ import at.gv.egovernment.moa.logging.Logger; public class ArtifactResolution implements IRequestHandler { - public boolean handleObject(MOARequest obj) { - return (obj.getSamlRequest() instanceof ArtifactResolve); + public boolean handleObject(InboundMessage obj) { + return (obj instanceof MOARequest && + ((MOARequest)obj).getSamlRequest() instanceof ArtifactResolve); } - public SLOInformationInterface process(MOARequest obj, HttpServletRequest req, + public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData) throws MOAIDException { if (!handleObject(obj)) { throw new MOAIDException("pvp2.13", null); } - - ArtifactResolve artifactResolve = (ArtifactResolve) obj - .getSamlRequest(); + + ArtifactResolve artifactResolve = (ArtifactResolve) ((MOARequest)obj).getSamlRequest(); String artifactID = artifactResolve.getArtifact().getArtifact(); PVPAssertionStorage pvpAssertion = PVPAssertionStorage.getInstance(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java index c5f73a59f..ca5210d21 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java @@ -22,74 +22,55 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.pvp2x.requestHandler; -import java.util.ArrayList; -import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.joda.time.DateTime; -import org.opensaml.Configuration; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.AuthnRequest; -import org.opensaml.saml2.core.EncryptedAssertion; -import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.Response; -import org.opensaml.saml2.encryption.Encrypter; -import org.opensaml.saml2.encryption.Encrypter.KeyPlacement; import org.opensaml.saml2.metadata.AssertionConsumerService; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.opensaml.security.MetadataCredentialResolver; -import org.opensaml.security.MetadataCriteria; import org.opensaml.ws.message.encoder.MessageEncodingException; -import org.opensaml.xml.encryption.EncryptionException; -import org.opensaml.xml.encryption.EncryptionParameters; -import org.opensaml.xml.encryption.KeyEncryptionParameters; -import org.opensaml.xml.security.CriteriaSet; import org.opensaml.xml.security.SecurityException; -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.KeyInfoGeneratorFactory; -import org.opensaml.xml.security.x509.X509Credential; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; -import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationImpl; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.ArtifactBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder; +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.binding.PostBinding; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding; +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.config.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionConsumerServiceException; -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; public class AuthnRequestHandler implements IRequestHandler, PVPConstants { - public boolean handleObject(MOARequest obj) { - return (obj.getSamlRequest() instanceof AuthnRequest); + public boolean handleObject(InboundMessage obj) { + + return (obj instanceof MOARequest && + ((MOARequest)obj).getSamlRequest() instanceof AuthnRequest); } - public SLOInformationInterface process(MOARequest obj, HttpServletRequest req, + public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData) throws MOAIDException { if (!handleObject(obj)) { throw new MOAIDException("pvp2.13", null); } - + //get basic information - AuthnRequest authnRequest = (AuthnRequest) obj.getSamlRequest(); + MOARequest moaRequest = (MOARequest) obj; + AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest(); EntityDescriptor peerEntity = obj.getEntityMetadata(); SPSSODescriptor spSSODescriptor = peerEntity .getSPSSODescriptor(SAMLConstants.SAML20P_NS); @@ -121,88 +102,8 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants { Assertion assertion = PVP2AssertionBuilder.buildAssertion(authnRequest, authData, peerEntity, date, consumerService, sloInformation); - Response authResponse = SAML2Utils.createSAMLObject(Response.class); - - Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); - - //change to entity value from entity name to IDP EntityID (URL) - nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath()); - nissuer.setFormat(NameID.ENTITY); - authResponse.setIssuer(nissuer); - authResponse.setInResponseTo(authnRequest.getID()); - - //set responseID - String remoteSessionID = SAML2Utils.getSecureIdentifier(); - authResponse.setID(remoteSessionID); - - - //SAML2 response required IssueInstant - authResponse.setIssueInstant(date); - - authResponse.setStatus(SAML2Utils.getSuccessStatus()); - - String oaURL = consumerService.getLocation(); - - //check, if metadata includes an encryption key - MetadataCredentialResolver mdCredResolver = - new MetadataCredentialResolver(MOAMetadataProvider.getInstance()); - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add( new EntityIDCriteria(obj.getSamlRequest().getIssuer().getValue()) ); - criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); - criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) ); - - X509Credential encryptionCredentials = null; - try { - encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet); - - } catch (SecurityException e2) { - Logger.warn("Can not extract the Assertion Encryption-Key from metadata", e2); - throw new InvalidAssertionEncryptionException(); - - } - - boolean isEncryptionActive = AuthConfigurationProvider.getInstance().isPVP2AssertionEncryptionActive(); - if (encryptionCredentials != null && isEncryptionActive) { - //encrypt SAML2 assertion - - try { - - EncryptionParameters dataEncParams = new EncryptionParameters(); - dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE); - - List keyEncParamList = new ArrayList(); - KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); - - keyEncParam.setEncryptionCredential(encryptionCredentials); - keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE); - KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration() - .getKeyInfoGeneratorManager().getDefaultManager() - .getFactory(encryptionCredentials); - keyEncParam.setKeyInfoGenerator(kigf.newInstance()); - keyEncParamList.add(keyEncParam); - - Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); - //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE); - samlEncrypter.setKeyPlacement(KeyPlacement.PEER); - - EncryptedAssertion encryptAssertion = null; - - encryptAssertion = samlEncrypter.encrypt(assertion); - - authResponse.getEncryptedAssertions().add(encryptAssertion); - - } catch (EncryptionException e1) { - Logger.warn("Can not encrypt the PVP2 assertion", e1); - throw new InvalidAssertionEncryptionException(); - - } - - } else { - authResponse.getAssertions().add(assertion); - - } - + Response authResponse = AuthResponseBuilder.buildResponse(authnRequest, date, assertion); + IEncoder binding = null; if (consumerService.getBinding().equals( @@ -223,32 +124,21 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants { if (binding == null) { throw new BindingNotSupportedException(consumerService.getBinding()); } - + try { - binding.encodeRespone(req, resp, authResponse, oaURL, obj.getRelayState()); - // TODO add remoteSessionID to AuthSession ExternalPVPSessionStore - -// Logger logger = new Logger(); -// logger.debug("Redirect Binding Request = " + PrettyPrinter.prettyPrint(SAML2Utils.asDOMDocument(authResponse))); - - + binding.encodeRespone(req, resp, authResponse, + consumerService.getLocation(), obj.getRelayState()); + return sloInformation; } catch (MessageEncodingException e) { Logger.error("Message Encoding exception", e); throw new MOAIDException("pvp2.01", null, e); + } catch (SecurityException e) { Logger.error("Security exception", e); throw new MOAIDException("pvp2.01", null, e); -// } catch (TransformerException e) { -// Logger.error("Security exception", e); -// throw new MOAIDException("pvp2.01", null, e); -// } catch (IOException e) { -// Logger.error("Security exception", e); -// throw new MOAIDException("pvp2.01", null, e); -// } catch (MarshallingException e) { -// Logger.error("Security exception", e); -// throw new MOAIDException("pvp2.01", null, e); + } } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java index fb4f5134f..d1ae0b202 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java @@ -28,11 +28,12 @@ import javax.servlet.http.HttpServletResponse; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; +import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; public interface IRequestHandler { - public boolean handleObject(MOARequest obj); + public boolean handleObject(InboundMessage obj); - public SLOInformationInterface process(MOARequest obj, HttpServletRequest req, + public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData) throws MOAIDException; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java index 563712907..5b9bf940d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java @@ -33,6 +33,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; +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.exceptions.SAMLRequestNotSupported; @@ -55,7 +56,7 @@ public class RequestManager { handler.add(new ArtifactResolution()); } - public SLOInformationInterface handle(MOARequest obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData) + public SLOInformationInterface handle(InboundMessage obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData) throws SAMLRequestNotSupported, MOAIDException { Iterator it = handler.iterator(); while(it.hasNext()) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java index b52e37e06..9d57c2bae 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java @@ -38,6 +38,8 @@ import org.opensaml.saml2.core.Status; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.metadata.AssertionConsumerService; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.ws.soap.soap11.Body; +import org.opensaml.ws.soap.soap11.Envelope; import org.opensaml.xml.XMLObject; import org.opensaml.xml.XMLObjectBuilderFactory; import org.opensaml.xml.io.Marshaller; @@ -115,4 +117,15 @@ public class SAML2Utils { return 0; } + + public static Envelope buildSOAP11Envelope(XMLObject payload) { + XMLObjectBuilderFactory bf = Configuration.getBuilderFactory(); + Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME).buildObject(Envelope.DEFAULT_ELEMENT_NAME); + Body body = (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME); + + body.getUnknownXMLObjects().add(payload); + envelope.setBody(body); + + return envelope; + } } 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 e4ae01066..fde453920 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,30 +22,52 @@ *******************************************************************************/ 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.common.xml.SAMLConstants; +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.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.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.security.x509.X509Credential; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.validation.ValidationException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption; 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.signer.CredentialProvider; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; +import at.gv.egovernment.moa.logging.Logger; public class SAMLVerificationEngine { public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { - if (msg instanceof MOARequest) - verifyRequest(((MOARequest)msg).getSamlRequest(), sigTrustEngine); + if (msg instanceof MOARequest && + ((MOARequest)msg).getSamlRequest() instanceof RequestAbstractType) + verifyRequest(((RequestAbstractType)((MOARequest)msg).getSamlRequest()), sigTrustEngine); else verifyResponse(((MOAResponse)msg).getResponse(), sigTrustEngine); @@ -102,4 +124,88 @@ public class SAMLVerificationEngine { } } + public static void validateAssertion(Response samlResp, boolean validateDestination) throws AssertionValidationExeption { + try { + if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + List saml2assertions = new ArrayList(); + + if (validateDestination && !samlResp.getDestination().startsWith( + PVPConfiguration.getInstance().getIDPPublicPath())) { + 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 encryAssertionList = samlResp.getEncryptedAssertions(); + if (encryAssertionList != null && encryAssertionList.size() > 0) { + //decrypt assertions + + Logger.debug("Found encryped assertion. Start decryption ..."); + + X509Credential authDecCredential = CredentialProvider.getIDPAssertionEncryptionCredential(); + + StaticKeyInfoCredentialResolver skicr = + new StaticKeyInfoCredentialResolver(authDecCredential); + + 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()); + + } + + for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { + + Conditions conditions = saml2assertion.getConditions(); + DateTime notbefore = conditions.getNotBefore(); + DateTime notafter = conditions.getNotOnOrAfter(); + if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) { + Logger.warn("PVP2 Assertion is out of Date"); + saml2assertions.remove(saml2assertion); + + } + } + + if (saml2assertions.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(saml2assertions); + + } 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 (CredentialsNotAvailableException e) { + Logger.warn("Assertion decrypt FAILED - No Credentials", e); + throw new AssertionValidationExeption("Assertion decrypt FAILED - No Credentials", null, e); + + } 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/saml1/GetArtifactAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index 6ce647ff8..67f780b3a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -80,7 +80,7 @@ public class GetArtifactAction implements IAction { String samlArtifactBase64 = saml1server.BuildSAMLArtifact(oaParam, authData, sourceID); if (authData.isSsoSession()) { - String url = "RedirectServlet"; + String url = AuthConfigurationProvider.getInstance().getPublicURLPrefix() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(oaURL, "UTF-8")); if (!oaParam.getBusinessService()) url = addURLParameter(url, PARAM_TARGET, URLEncoder.encode(oaParam.getTarget(), "UTF-8")); @@ -109,7 +109,7 @@ public class GetArtifactAction implements IAction { } SLOInformationInterface sloInformation = - new SLOInformationImpl(authData.getAssertionID(), null, req.requestedModule()); + new SLOInformationImpl(authData.getAssertionID(), null, null, req.requestedModule()); return sloInformation; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java index 7569eef84..d48c0a9bb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationData.java @@ -46,9 +46,7 @@ package at.gv.egovernment.moa.id.protocols.saml1; -import java.text.DateFormat; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.List; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java index b6a2ac0b6..7b106b206 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java @@ -23,12 +23,15 @@ package at.gv.egovernment.moa.id.protocols.saml1; import java.util.HashMap; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; +import edu.emory.mathcs.backport.java.util.Arrays; + import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; @@ -41,7 +44,7 @@ import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IModulInfo; 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.util.ParamValidatorUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -54,8 +57,23 @@ public class SAML1Protocol implements IModulInfo, MOAIDAuthConstants { public static final String GETARTIFACT = "GetArtifact"; - private static HashMap actions = new HashMap(); + @SuppressWarnings("unchecked") + public static final List DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList( + new String[] { + PVPConstants.BPK_NAME, + PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, + PVPConstants.GIVEN_NAME_NAME, + PVPConstants.PRINCIPAL_NAME_NAME, + PVPConstants.BIRTHDATE_NAME, + PVPConstants.EID_CCS_URL_NAME, + PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME, + PVPConstants.EID_IDENTITY_LINK_NAME, + PVPConstants.EID_SOURCE_PIN_NAME, + PVPConstants.EID_SOURCE_PIN_TYPE_NAME + }); + private static HashMap actions = new HashMap(); + static { actions.put(GETARTIFACT, new GetArtifactAction()); @@ -143,6 +161,9 @@ public class SAML1Protocol implements IModulInfo, MOAIDAuthConstants { config.setTarget(oaParam.getTarget()); + //config.setRequestedIDP("https://demo.egiz.gv.at/demoportal_moaid-2.0"); + config.setRequestedIDP("https://labda.iaik.tugraz.at:8443/moa-id-auth"); + // request.getSession().setAttribute(PARAM_OA, oaURL); // request.getSession().setAttribute(PARAM_TARGET, oaParam.getTarget()); return config; @@ -157,7 +178,7 @@ public class SAML1Protocol implements IModulInfo, MOAIDAuthConstants { String samlArtifactBase64 = saml1authentication.BuildErrorAssertion(e, protocolRequest); - String url = "RedirectServlet"; + String url = AuthConfigurationProvider.getInstance().getPublicURLPrefix() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(protocolRequest.getOAURL(), "UTF-8")); url = addURLParameter(url, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8")); url = response.encodeRedirectURL(url); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java index dc5e715c9..9bf88534f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java @@ -22,11 +22,19 @@ */ package at.gv.egovernment.moa.id.protocols.saml1; +import java.util.ArrayList; import java.util.List; import org.opensaml.saml2.core.Attribute; +import at.gv.egovernment.moa.id.commons.db.dao.config.OASAML1; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; 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.builder.AttributQueryBuilder; +import at.gv.egovernment.moa.logging.Logger; /** * @author tlenz @@ -57,8 +65,32 @@ public class SAML1RequestImpl extends RequestImpl { */ @Override public List getRequestedAttributes() { - //TODO: implement attribut mapping - return null; + + List reqAttr = new ArrayList(); + reqAttr.addAll(SAML1Protocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION); + + try { + OAAuthParameter oa = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(getOAURL()); + OASAML1 saml1 = oa.getSAML1Parameter(); + if (saml1 != null) { + if (saml1.isProvideAUTHBlock()) + reqAttr.add(PVPConstants.EID_AUTH_BLOCK_NAME); + + if (saml1.isProvideCertificate()) + reqAttr.add(PVPConstants.EID_SIGNER_CERTIFICATE_NAME); + + if (saml1.isProvideFullMandatorData()) + reqAttr.add(PVPConstants.MANDATE_FULL_MANDATE_NAME); + } + + return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.iterator()); + + } catch (ConfigurationException e) { + Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e); + return null; + } + + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java index 75f40c89e..2b5879901 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java @@ -85,7 +85,7 @@ public class AttributeCollector implements IAction { SLOInformationImpl sloInfo = (SLOInformationImpl) processRequest(container, httpReq, httpResp, authData, oaParam); if (sloInfo == null) { - sloInfo = new SLOInformationImpl(null, null, req.requestedModule()); + sloInfo = new SLOInformationImpl(null, null, null, req.requestedModule()); } return sloInfo; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java index a3996d52b..3ac71be3b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java @@ -4,6 +4,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +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; @@ -160,7 +161,7 @@ public class AuthenticationRequest implements IAction { } - public PersonalAttributeList populateAttributes(OAAuthParameter oaParam) { + public PersonalAttributeList populateAttributes(IOAAuthParameters oaParam) { IPersonalAttributeList attrLst = moaStorkRequest.getStorkAuthnRequest().getPersonalAttributeList(); Logger.info("Found " + attrLst.size() + " personal attributes in the request."); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java index 06e6a9038..d827e73cf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ConsentEvaluator.java @@ -7,7 +7,7 @@ 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.ex.MOADatabaseException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; @@ -78,7 +78,7 @@ public class ConsentEvaluator implements IAction { * @return the string * @throws MOAIDException the mOAID exception */ - public String requestConsent(DataContainer container, HttpServletResponse response, OAAuthParameter oaParam) throws MOAIDException { + public String requestConsent(DataContainer container, HttpServletResponse response, IOAAuthParameters oaParam) throws MOAIDException { // prepare redirect String newArtifactId; try { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AssertionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AssertionStorage.java index bc9de7a50..890ec9f0d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AssertionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AssertionStorage.java @@ -208,7 +208,7 @@ public class AssertionStorage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getAssertionWithArtifact"); - query.setString("artifact", artifact); + query.setParameter("artifact", artifact); result = query.list(); //send transaction diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java index e18d9786d..2ee4327dc 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.List; import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang.StringEscapeUtils; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; @@ -113,10 +114,13 @@ public class AuthenticationSessionStoreage { public static String createInterfederatedSession(IRequest req, boolean isAuthenticated) throws MOADatabaseException, AssertionAttributeExtractorExeption { String id = Random.nextRandom(); AuthenticationSession session = new AuthenticationSession(id); + session.setAuthenticated(true); + session.setAuthenticatedUsed(false); AuthenticatedSessionStore dbsession = new AuthenticatedSessionStore(); dbsession.setSessionid(id); dbsession.setAuthenticated(isAuthenticated); + dbsession.setInterfederatedSSOSession(true); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 Date now = new Date(); @@ -127,20 +131,37 @@ public class AuthenticationSessionStoreage { //add interfederation information List idpList = dbsession.getInderfederation(); - if (idpList == null) + InterfederationSessionStore idp = null; + if (idpList == null) { idpList = new ArrayList(); - - InterfederationSessionStore idp = new InterfederationSessionStore(); - idp.setCreated(now); - idp.setIdpurlprefix(req.getInterfederationResponse().getEntityID()); + dbsession.setInderfederation(idpList); + + } else { + for (InterfederationSessionStore el : idpList) { + //resue old entry if interfederation IDP is reused for authentication + if (el.getIdpurlprefix().equals(req.getInterfederationResponse().getEntityID())) + idp = el; + + } + } + + //create new interfederation IDP entry + if (idp == null) { + idp = new InterfederationSessionStore(); + idp.setCreated(now); + idp.setIdpurlprefix(req.getInterfederationResponse().getEntityID()); + + } AssertionAttributeExtractor extract = new AssertionAttributeExtractor(req.getInterfederationResponse().getResponse()); idp.setSessionIndex(extract.getSessionIndex()); idp.setUserNameID(extract.getNameID()); idp.setAttributesRequested(false); idp.setQAALevel(extract.getQAALevel()); + idp.setMoasession(dbsession); idpList.add(idp); + //store AssertionStore element to Database try { MOASessionDBUtils.saveOrUpdate(dbsession); @@ -153,28 +174,7 @@ public class AuthenticationSessionStoreage { return id; } - - public static void setInterfederationAttributCollectorUsed(AuthenticationSession session, String idpID) throws MOADatabaseException { - AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); - List idpList = dbsession.getInderfederation(); - for (InterfederationSessionStore idp : idpList) { - if (idp.getIdpurlprefix().endsWith(idpID)) - idp.setAttributesRequested(true); - } - //store AssertionStore element to Database - try { - MOASessionDBUtils.saveOrUpdate(dbsession); - Logger.info("MOASession with sessionID=" + session.getSessionID() - + " is stored in Database"); - - } catch (MOADatabaseException e) { - Logger.warn("MOASession could not stored.",e); - throw e; - } - } - - public static void storeSession(AuthenticationSession session) throws MOADatabaseException, BuildException { try { @@ -234,7 +234,7 @@ public class AuthenticationSessionStoreage { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); - query.setString("sessionid", moaSessionID); + query.setParameter("sessionid", moaSessionID); result = query.list(); @@ -308,7 +308,7 @@ public class AuthenticationSessionStoreage { tx = session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); - query.setString("sessionid", moaSessionID); + query.setParameter("sessionid", moaSessionID); result = query.list(); @@ -344,7 +344,10 @@ public class AuthenticationSessionStoreage { if (SLOInfo != null) { activeOA.setAssertionSessionID(SLOInfo.getSessionIndex()); activeOA.setUserNameID(SLOInfo.getUserNameIdentifier()); + activeOA.setUserNameIDFormat(SLOInfo.getUserNameIDFormat()); activeOA.setProtocolType(SLOInfo.getProtocolType()); + activeOA.setAttributeQueryUsed(false); + } @@ -436,7 +439,7 @@ public class AuthenticationSessionStoreage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithSSOID"); - query.setString("sessionid", SSOSessionID); + query.setParameter("sessionid", SSOSessionID); result = query.list(); //send transaction @@ -457,7 +460,7 @@ public class AuthenticationSessionStoreage { } - public static boolean isValidSessionWithSSOID(String SSOId, String moaSessionId) { + public static AuthenticatedSessionStore isValidSessionWithSSOID(String SSOId, String moaSessionId) { MiscUtil.assertNotNull(SSOId, "SSOSessionID"); Logger.trace("Get authenticated session with SSOID " + SSOId + " from database."); @@ -468,7 +471,7 @@ public class AuthenticationSessionStoreage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithSSOID"); - query.setString("sessionid", SSOId); + query.setParameter("sessionid", SSOId); result = query.list(); //send transaction @@ -480,10 +483,10 @@ public class AuthenticationSessionStoreage { //Assertion requires an unique artifact if (result.size() != 1) { Logger.trace("No entries found."); - return false; + return null; } else { - return true; + return result.get(0); } } @@ -498,7 +501,7 @@ public class AuthenticationSessionStoreage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithPendingRequestID"); - query.setString("sessionid", id); + query.setParameter("sessionid", id); result = query.list(); //send transaction @@ -532,6 +535,48 @@ public class AuthenticationSessionStoreage { } + + public static AuthenticationSession getSessionWithUserNameID(String nameID) { + + try { + MiscUtil.assertNotNull(nameID, "nameID"); + Logger.trace("Get authenticated session with pedingRequestID " + nameID + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getMOAISessionWithUserNameID"); + query.setParameter("usernameid", StringEscapeUtils.escapeHtml(nameID)); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() != 1) { + Logger.trace("No entries found."); + return null; + } + + //decrypt Session + EncryptedData encdata = new EncryptedData(result.get(0).getSession(), + result.get(0).getIv()); + byte[] decrypted = SessionEncrytionUtil.decrypt(encdata); + return (AuthenticationSession) SerializationUtils.deserialize(decrypted); + + + } catch (Throwable e) { + Logger.warn("MOASession deserialization-exception by using MOASessionID=" + nameID); + return null; + } + + } + public static AuthenticationSession getSessionWithPendingRequestID(String pedingRequestID) { try { @@ -544,7 +589,7 @@ public class AuthenticationSessionStoreage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithPendingRequestID"); - query.setString("sessionid", pedingRequestID); + query.setParameter("sessionid", pedingRequestID); result = query.list(); //send transaction @@ -622,6 +667,129 @@ public class AuthenticationSessionStoreage { } + public static OASessionStore searchActiveOASSOSession(AuthenticationSession moaSession, String oaID, String protocolType) { + MiscUtil.assertNotNull(moaSession, "MOASession"); + MiscUtil.assertNotNull(oaID, "OnlineApplicationIdentifier"); + MiscUtil.assertNotNull(protocolType, "usedProtocol"); + Logger.trace("Get active OnlineApplication for sessionID " + moaSession.getSessionID() + " with OAID " + + oaID + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getActiveOAWithSessionIDandOAIDandProtocol"); + query.setParameter("sessionID", moaSession.getSessionID()); + query.setParameter("oaID", oaID); + query.setParameter("protocol", protocolType); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() == 0) { + Logger.trace("No entries found."); + return null; + + } + + return result.get(0).getActiveOAsessions().get(0); + } + + public static InterfederationSessionStore searchInterfederatedIDPFORSSOWithMOASession(String sessionID) { + MiscUtil.assertNotNull(sessionID, "MOASession"); + Logger.trace("Get interfederated IDP for SSO with sessionID " + sessionID + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getInterfederatedIDPForSSOWithSessionID"); + query.setParameter("sessionID", sessionID); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() == 0) { + Logger.trace("No entries found."); + return null; + + } + + return result.get(0).getInderfederation().get(0); + } + + public static InterfederationSessionStore searchInterfederatedIDPFORSSOWithMOASessionIDPID(String sessionID, String idpID) { + MiscUtil.assertNotNull(sessionID, "MOASession"); + MiscUtil.assertNotNull(idpID, "Interfederated IDP ID"); + Logger.trace("Get interfederated IDP "+ idpID + " for SSO with sessionID " + sessionID + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getInterfederatedIDPForSSOWithSessionIDIDPID"); + query.setParameter("sessionID", sessionID); + query.setParameter("idpID", idpID); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() == 0) { + Logger.trace("No entries found."); + return null; + + } + + return result.get(0).getInderfederation().get(0); + } + + public static InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(AuthenticationSession moaSession) { + MiscUtil.assertNotNull(moaSession, "MOASession"); + Logger.trace("Get interfederated IDP for AttributeQuery with sessionID " + moaSession.getSessionID() + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getInterfederatedIDPForAttributeQueryWithSessionID"); + query.setParameter("sessionID", moaSession.getSessionID()); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() == 0) { + Logger.trace("No entries found."); + return null; + + } + + return result.get(0).getInderfederation().get(0); + } + @SuppressWarnings("rawtypes") private static AuthenticatedSessionStore searchInDatabase(String sessionID) throws MOADatabaseException { MiscUtil.assertNotNull(sessionID, "moasessionID"); @@ -633,7 +801,7 @@ public class AuthenticationSessionStoreage { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getSessionWithID"); - query.setString("sessionid", sessionID); + query.setParameter("sessionid", sessionID); result = query.list(); //send transaction @@ -650,4 +818,58 @@ public class AuthenticationSessionStoreage { return (AuthenticatedSessionStore) result.get(0); } + + /** + * @param entityID + * @param requestID + */ + public static boolean removeInterfederetedSession(String entityID, + String pedingRequestID) { + + try { + Logger.debug("Remove interfederated IDP from local SSO session ..."); + + MiscUtil.assertNotNull(pedingRequestID, "pedingRequestID"); + Logger.trace("Get authenticated session with pedingRequestID " + pedingRequestID + " from database."); + Session session = MOASessionDBUtils.getCurrentSession(); + + List result; + + synchronized (session) { + session.beginTransaction(); + Query query = session.getNamedQuery("getSessionWithPendingRequestID"); + query.setParameter("sessionid", pedingRequestID); + result = query.list(); + + //send transaction + session.getTransaction().commit(); + } + + Logger.trace("Found entries: " + result.size()); + + //Assertion requires an unique artifact + if (result.size() != 1) { + Logger.trace("No entries found."); + return false; + } + + AuthenticatedSessionStore authsession = result.get(0); + + List idpSessions = authsession.getInderfederation(); + if (idpSessions != null) { + for (InterfederationSessionStore idp : idpSessions) { + if (idp.getIdpurlprefix().equals(entityID)) + idpSessions.remove(idp); + + } + } + + MOASessionDBUtils.saveOrUpdate(authsession); + return true; + + } catch (Throwable e) { + Logger.warn("MOASession deserialization-exception by using MOASessionID=" + pedingRequestID); + return false; + } + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java index ae8e5ee27..054ad1014 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBExceptionStoreImpl.java @@ -154,7 +154,7 @@ public class DBExceptionStoreImpl implements IExceptionStore { synchronized (session) { session.beginTransaction(); Query query = session.getNamedQuery("getExceptionWithID"); - query.setString("id", id); + query.setParameter("id", id); result = query.list(); //send transaction 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 3cd8ee24a..0a228c318 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 @@ -87,6 +87,7 @@ builder.02=Fehler beim Ausblenden von Stammzahlen builder.03=Fehler beim Aufbau des HTML Codes f\u00FCr Vollmachten builder.04=Die Personenbindung konnte nicht neu signiert werden und wird aus diesem Grund nicht ausgeliefert. MOA-SS lieferte folgenden Fehlercode {0} und Fehler {1} zur\u00FCck. 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. service.00=Fehler beim Aufruf des Web Service: {0} service.01=Fehler beim Aufruf des Web Service: kein Endpoint @@ -212,7 +213,7 @@ stork.13=Fehler beim Sammeln eines Attributes in einem AttributProviderPlugin stork.14=Es wurde weder Authentifizierungs/ noch Attributerequest empfangen stork.15=Unbekannte request. stork.16=Ein Attribute aus zwei verschiedenen Quellen unterscheidet sich\: {0} -stork.17=Fehler beim Einholen der Zustimmung für Attribut\u00FCbertragung durch den Benutzer +stork.17=Fehler beim Einholen der Zustimmung f\uFFFDr Attribut\u00FCbertragung durch den Benutzer stork.18=STORK-SAML Engine konnte nicht initialisiert werden. pvp2.00={0} ist kein gueltiger consumer service index diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java index 29cc5ebdc..cfab6b0d5 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java @@ -53,7 +53,12 @@ import org.hibernate.annotations.DynamicUpdate; @NamedQuery(name="getSessionWithID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore where authenticatedsessionstore.sessionid = :sessionid"), @NamedQuery(name="getSessionWithSSOID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore where authenticatedsessionstore.SSOsessionid = :sessionid"), @NamedQuery(name="getSessionWithPendingRequestID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore where authenticatedsessionstore.pendingRequestID = :sessionid"), - @NamedQuery(name="getMOAISessionsWithTimeOut", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore where authenticatedsessionstore.created < :timeoutcreate or authenticatedsessionstore.updated < :timeoutupdate") + @NamedQuery(name="getMOAISessionsWithTimeOut", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore where authenticatedsessionstore.created < :timeoutcreate or authenticatedsessionstore.updated < :timeoutupdate"), + @NamedQuery(name="getMOAISessionWithUserNameID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.activeOAsessions activeOAsessions where activeOAsessions.userNameID = :usernameid and activeOAsessions.attributeQueryUsed is false"), + @NamedQuery(name="getActiveOAWithSessionIDandOAIDandProtocol", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.activeOAsessions activeOAsessions where activeOAsessions.oaurlprefix = :oaID and activeOAsessions.protocolType = :protocol and authenticatedsessionstore.sessionid = :sessionID"), + @NamedQuery(name="getInterfederatedIDPForAttributeQueryWithSessionID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is false and authenticatedsessionstore.sessionid = :sessionID"), + @NamedQuery(name="getInterfederatedIDPForSSOWithSessionID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is true and authenticatedsessionstore.sessionid = :sessionID order by inderfederations.QAALevel DESC"), + @NamedQuery(name="getInterfederatedIDPForSSOWithSessionIDIDPID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is true and authenticatedsessionstore.sessionid = :sessionID and inderfederations.idpurlprefix = :idpID") }) public class AuthenticatedSessionStore implements Serializable{ @@ -82,6 +87,9 @@ public class AuthenticatedSessionStore implements Serializable{ @Column(name = "isSSOSession", nullable=false) private boolean isSSOSession = false; + + @Column(name = "isInterfederatedSSOSession", nullable=false) + private boolean isInterfederatedSSOSession = false; @Column(name = "pendingRequestID", nullable=false) private String pendingRequestID = ""; @@ -238,8 +246,21 @@ public class AuthenticatedSessionStore implements Serializable{ public void setIv(byte[] iv) { this.iv = iv; } + + /** + * @return the isInterfederatedSSOSession + */ + public boolean isInterfederatedSSOSession() { + return isInterfederatedSSOSession; + } + + /** + * @param isInterfederatedSSOSession the isInterfederatedSSOSession to set + */ + public void setInterfederatedSSOSession(boolean isInterfederatedSSOSession) { + this.isInterfederatedSSOSession = isInterfederatedSSOSession; + } - } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/OASessionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/OASessionStore.java index 25b48310e..539de990f 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/OASessionStore.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/OASessionStore.java @@ -59,9 +59,15 @@ public class OASessionStore implements Serializable{ @Column(name = "userNameID", unique=false, nullable=true) private String userNameID; + @Column(name = "userNameIDFormat", unique=false, nullable=true) + private String userNameIDFormat; + @Column(name = "protocolType", unique=false, nullable=true) private String protocolType; + @Column(name = "attributequeryused", unique=false, nullable=false) + private boolean attributeQueryUsed = false; + @Column(name = "created", updatable=false, nullable=false) // @Temporal(TemporalType.TIMESTAMP) private Date created; @@ -149,6 +155,36 @@ public class OASessionStore implements Serializable{ this.protocolType = protocolType; } + /** + * @return the attributeQueryUsed + */ + public boolean isAttributeQueryUsed() { + return attributeQueryUsed; + } + + /** + * @param attributeQueryUsed the attributeQueryUsed to set + */ + public void setAttributeQueryUsed(boolean attributeQueryUsed) { + this.attributeQueryUsed = attributeQueryUsed; + } + + /** + * @return the userNameIDFormat + */ + public String getUserNameIDFormat() { + return userNameIDFormat; + } + + /** + * @param userNameIDFormat the userNameIDFormat to set + */ + public void setUserNameIDFormat(String userNameIDFormat) { + this.userNameIDFormat = userNameIDFormat; + } + + + } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java index 65c9003e3..b557d2dc9 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java @@ -78,6 +78,9 @@ public class StatisticLog implements Serializable{ @Column(name = "isSSOLogin", unique=false) private boolean ssosession; + @Column(name = "isInterfederatedSSOLogin", unique=false) + private boolean interfederatedSSOSession; + @Column(name = "isBusinessService", unique=false) private boolean businessservice; @@ -390,6 +393,21 @@ public class StatisticLog implements Serializable{ public void setErrortype(String errortype) { this.errortype = errortype; } + + /** + * @return the interfederatedSSOSession + */ + public boolean isInterfederatedSSOSession() { + return interfederatedSSOSession; + } + + /** + * @param interfederatedSSOSession the interfederatedSSOSession to set + */ + public void setInterfederatedSSOSession(boolean interfederatedSSOSession) { + this.interfederatedSSOSession = interfederatedSSOSession; + } + diff --git a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd index 49d919978..32b4f4ba7 100644 --- a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd +++ b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd @@ -481,11 +481,18 @@ + + + + + + + enthält Parameter über die OA, die die -- cgit v1.2.3