diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv')
30 files changed, 1836 insertions, 519 deletions
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 ea796d974..e92c3377a 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 @@ -287,10 +287,10 @@ public class StatisticLogger implements IStatisticLogger{ } IAuthenticationSession moasession = null; - if (MiscUtil.isNotEmpty(errorRequest.getSSOSessionIdentifier())) { + if (MiscUtil.isNotEmpty(errorRequest.getInternalSSOSessionIdentifier())) { Logger.debug("Use MOA session information from SSO session for ErrorLogging"); try { - moasession = authenticatedSessionStorage.getInternalSSOSession(errorRequest.getSSOSessionIdentifier()); + moasession = authenticatedSessionStorage.getInternalSSOSession(errorRequest.getInternalSSOSessionIdentifier()); } catch (MOADatabaseException e) { Logger.error("Error during database communication", e); 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 b60162f35..a13455972 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 @@ -28,8 +28,13 @@ import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -87,6 +92,7 @@ import at.gv.util.client.szr.SZRClient; import at.gv.util.config.EgovUtilPropertiesConfiguration; import at.gv.util.wsdl.szr.SZRException; import at.gv.util.xsd.szr.PersonInfoType; +import iaik.x509.X509Certificate; /** * @author tlenz @@ -95,10 +101,30 @@ import at.gv.util.xsd.szr.PersonInfoType; @Service("AuthenticationDataBuilder") public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder { + public static final String CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS = "configuration.foreignsectors.pubkey"; + @Autowired private IAuthenticationSessionStoreage authenticatedSessionStorage; @Autowired protected AuthConfiguration authConfig; @Autowired protected LoALevelMapper loaLevelMapper; + private Map<String, X509Certificate> encKeyMap = new HashMap<String, X509Certificate>(); + + @PostConstruct + private void initialize() { + Map<String, String> pubKeyMap = authConfig.getBasicMOAIDConfigurationWithPrefix(CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS); + for (Entry<String, String> el : pubKeyMap.entrySet()) { + try { + encKeyMap.put(el.getKey(), new X509Certificate(Base64Utils.decode(el.getValue(), false))); + Logger.info("Load foreign bPK encryption certificate for sector: " + el.getKey()); + + } catch (Exception e) { + Logger.warn("Can NOT load foreign bPK encryption certificate for sector: \" + el.getKey()", e); + + } + + } + } + @Override public IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException { try { @@ -108,8 +134,7 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } catch (ConfigurationException | BuildException | WrongParametersException | DynamicOABuildException | EAAFBuilderException e) { Logger.warn("Can not build authentication data from session information"); - throw new EAAFAuthenticationException("TODO", new Object[]{}, - "Can not build authentication data from session information", e); + throw new EAAFAuthenticationException("TODO", new Object[]{}, e); } @@ -490,6 +515,9 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } + //build foreign bPKs + generateForeignbPK(authData, oaParam.foreignbPKSectorsRequested()); + //#################################################################### //copy all generic authentication information, which are not processed before to authData Iterator<String> copyInterator = includedToGenericAuthData.iterator(); @@ -688,8 +716,7 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } catch (MOAIDException e) { Logger.warn("Can not build OA specific IDL. Reason: " + e.getMessage(), e); - throw new EAAFParserException("TODO", null, - "Can not build OA specific IDL. Reason: " + e.getMessage(), e); + throw new EAAFParserException("TODO", null, e); } @@ -743,4 +770,58 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } + private void generateForeignbPK(MOAAuthenticationData authData, List<String> foreignSectors) { + if (foreignSectors != null && !foreignSectors.isEmpty()) { + Logger.debug("Sectors for foreign bPKs are configurated. Starting foreign bPK generation ... "); + for (String foreignSector : foreignSectors) { + Logger.trace("Process sector: " + foreignSector + " ... "); + if (encKeyMap.containsKey(foreignSector)) { + try { + String sector = null; + //splitt sector into VKZ and target + if (foreignSector.startsWith("wbpk")) { + Logger.trace("Find foreign private sector " + foreignSector); + sector = Constants.URN_PREFIX + ":" + foreignSector; + + } else { + String[] split = foreignSector.split("+"); + if (split.length != 2) { + Logger.warn("Foreign sector: " + foreignSector + " looks WRONG. IGNORE IT!"); + + } else { + Logger.trace("Find foreign public sector. VKZ: " + split[0] + " Target: " + split[1]); + sector = Constants.URN_PREFIX_CDID + "+" + split[1]; + + } + + } + + if (sector != null) { + Pair<String, String> bpk = new BPKBuilder().generateAreaSpecificPersonIdentifier( + authData.getIdentificationValue(), + authData.getIdentificationType(), + sector); + String foreignbPK = BPKBuilder.encryptBPK(bpk.getFirst(), bpk.getSecond(), encKeyMap.get(foreignSector).getPublicKey()); + authData.getEncbPKList().add("(" + foreignSector + "|" + foreignbPK + ")"); + Logger.debug("Foreign bPK for sector: " + foreignSector + " created."); + + } + + } catch (Exception e) { + Logger.warn("Foreign bPK generation FAILED for sector: " + foreignSector, e); + + } + + } else { + Logger.info("NO encryption cerfificate FOUND in configuration for sector: " + foreignSector); + Logger.info("Foreign bPK for sector: " + foreignSector + " is NOT possible"); + + } + } + + } else + Logger.debug("No foreign bPKs required for this service provider"); + + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java index 9ca15c76f..27d983785 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java @@ -22,6 +22,8 @@ */ package at.gv.egovernment.moa.id.auth.builder; +import java.util.List; + import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -74,10 +76,15 @@ public class SignatureVerificationUtils { } } - public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException { + public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException { + return verify(signature, trustProfileID, null); + + } + + public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID) throws MOAIDException { try { //build signature-verification request - Element domVerifyXMLSignatureRequest = build(signature, trustProfileID); + Element domVerifyXMLSignatureRequest = build(signature, trustProfileID, verifyTransformsInfoProfileID); //send signature-verification to MOA-SP Element domVerifyXMLSignatureResponse = SignatureVerificationInvoker.getInstance() @@ -112,7 +119,7 @@ public class SignatureVerificationUtils { * * @throws ParseException */ - private Element build(byte[] signature, String trustProfileID) + private Element build(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID) throws ParseException { try { @@ -153,6 +160,20 @@ public class SignatureVerificationUtils { requestElem_.appendChild(signatureManifestCheckParamsElem); signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + //verify transformations + if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) { + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + for (String element : verifyTransformsInfoProfileID) { + Element verifyTransformsInfoProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); + verifyTransformsInfoProfileIDElem.appendChild(requestDoc_.createTextNode(element)); + + } + } + + + //hashinput data Element returnHashInputDataElem = requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); requestElem_.appendChild(returnHashInputDataElem); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java index d5ca89656..d2d39e9e6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java @@ -52,10 +52,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.auth.exception.ServiceException; -import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.ConnectionParameterInterface; -import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.spss.MOAException; import at.gv.egovernment.moa.spss.api.SignatureVerificationService; import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; @@ -64,7 +61,6 @@ import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser; import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; -import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moaspss.logging.Logger; /** @@ -93,22 +89,22 @@ public class SignatureVerificationInvoker { } private SignatureVerificationInvoker() { - try { - AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); - ConnectionParameterInterface authConnParam = authConfigProvider.getMoaSpConnectionParameter(); +// try { +// AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); +// ConnectionParameterInterface authConnParam = authConfigProvider.getMoaSpConnectionParameter(); - if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { - - - } else { +// if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { +// +// +// } else { svs = SignatureVerificationService.getInstance(); - } +// } - } catch (ConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } +// } catch (ConfigurationException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } } @@ -144,35 +140,34 @@ public class SignatureVerificationInvoker { protected Element doCall(QName serviceName, Element request) throws ServiceException { ConnectionParameterInterface authConnParam = null; try { - AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); - authConnParam = authConfigProvider.getMoaSpConnectionParameter(); - //If the ConnectionParameter do NOT exist, we try to get the api to work.... - if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { - - throw new ServiceException("service.00", new Object[]{"MOA-SP connection via Web-Service is not allowed any more!!!!!!"}); -// Service service = ServiceFactory.newInstance().createService(serviceName); -// Call call = service.createCall(); -// SOAPBodyElement body = new SOAPBodyElement(request); -// SOAPBodyElement[] params = new SOAPBodyElement[] { body }; -// Vector responses; -// SOAPBodyElement response; +// AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); +// authConnParam = authConfigProvider.getMoaSpConnectionParameter(); +// //If the ConnectionParameter do NOT exist, we try to get the api to work.... +// if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { // -// Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); -// call.setTargetEndpointAddress(authConnParam.getUrl()); -// responses = (Vector) call.invoke(serviceName, params); -// Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used -// response = (SOAPBodyElement) responses.get(0); -// return response.getAsDOM(); - } - else { - VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(request); - +// throw new ServiceException("service.00", new Object[]{"MOA-SP connection via Web-Service is not allowed any more!!!!!!"}); +//// Service service = ServiceFactory.newInstance().createService(serviceName); +//// Call call = service.createCall(); +//// SOAPBodyElement body = new SOAPBodyElement(request); +//// SOAPBodyElement[] params = new SOAPBodyElement[] { body }; +//// Vector responses; +//// SOAPBodyElement response; +//// +//// Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); +//// call.setTargetEndpointAddress(authConnParam.getUrl()); +//// responses = (Vector) call.invoke(serviceName, params); +//// Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used +//// response = (SOAPBodyElement) responses.get(0); +//// return response.getAsDOM(); +// } +// else { + VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(request); VerifyXMLSignatureResponse vsresponse = svs.verifyXMLSignature(vsrequest); - Document result = new VerifyXMLSignatureResponseBuilder().build(vsresponse); - + Document result = new VerifyXMLSignatureResponseBuilder(true).build(vsresponse); + //Logger.setHierarchy("moa.id.auth"); return result.getDocumentElement(); - } +// } } catch (Exception ex) { if (authConnParam != null) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java index 6e374995f..b976cba9e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java @@ -82,7 +82,7 @@ public class EvaluateSSOConsentsTaskImpl extends AbstractAuthServletTask { boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq); //load MOA SSO-session from database - AuthenticationSession ssoMOSSession = authenticatedSessionStorage.getInternalSSOSession(pendingReq.getSSOSessionIdentifier()); + AuthenticationSession ssoMOSSession = authenticatedSessionStorage.getInternalSSOSession(pendingReq.getInternalSSOSessionIdentifier()); if (!(isValidSSOSession && ssoMOSSession.isAuthenticated() )) { Logger.info("Single Sign-On consents evaluator found NO valid SSO session. Stopping authentication process ..."); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java new file mode 100644 index 000000000..7d9a2c28c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java @@ -0,0 +1,86 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.config.auth.data.UserWhitelistStore; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +public class UserRestrictionTask extends AbstractAuthServletTask { + + public static final String CONFIG_PROPS_SP_LIST = "configuration.restrictions.sp.entityIds"; + public static final String CONFIG_PROPS_CSV_USER_FILE = "configuration.restrictions.sp.users.url"; + public static final String CONFIG_PROPS_CSV_USER_SECTOR = "configuration.restrictions.sp.users.sector"; + + @Autowired(required=true) UserWhitelistStore whitelist; + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) + throws TaskExecutionException { + try { + String spEntityId = pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(); + List<String> restrictedSPs = KeyValueUtils.getListOfCSVValues(authConfig.getBasicConfiguration(CONFIG_PROPS_SP_LIST)); + if (restrictedSPs.contains(spEntityId)) { + Logger.debug("SP:" + spEntityId + " has a user restrication. Check users bPK ... "); + AuthenticationSessionWrapper moasession = new AuthenticationSessionWrapper(pendingReq.genericFullDataStorage()); + + //check if user idl is already loaded + if (moasession.getIdentityLink() == null) { + Logger.warn("PendingRequest contains NO IdentityLink. User restrictation NOT possible!"); + throw new MOAIDException("process.03", null); + + } + + //calculate whitelist bPK for current user + String bpkTarget = authConfig.getBasicConfiguration(CONFIG_PROPS_CSV_USER_SECTOR); + if (MiscUtil.isEmpty(bpkTarget)) { + Logger.info("NO bPK sector for user whitelist in configuration"); + throw new MOAIDException("config.05", new Object[] {CONFIG_PROPS_CSV_USER_SECTOR}); + + } + + Pair<String, String> pseudonym = new BPKBuilder().generateAreaSpecificPersonIdentifier( + moasession.getIdentityLink().getIdentificationValue(), + moasession.getIdentityLink().getIdentificationType(), + bpkTarget); + + + //check if user's bPK is whitelisted + if (!whitelist.isUserbPKInWhitelistDynamic(pseudonym.getFirst())) { + Logger.info("User's bPK is not whitelisted. Authentication process stops ..."); + Logger.trace("User's bPK: " + pseudonym.getFirst()); + throw new MOAIDException("auth.35", null); + + } + + Logger.debug("User was found in whitelist. Continue authentication process ... "); + + } else + Logger.trace("SP: " + spEntityId + " has no user restrication."); + + + } catch (MOAIDException e) { + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } catch (Exception e) { + Logger.warn("RestartAuthProzessManagement has an internal error", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java index e6b4e9bb8..c66353846 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java @@ -46,12 +46,11 @@ package at.gv.egovernment.moa.id.auth.parser; -import iaik.utils.Base64InputStream; -import iaik.x509.X509Certificate; - import java.io.ByteArrayInputStream; import java.io.InputStream; +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; import org.w3c.dom.Element; import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; @@ -60,6 +59,9 @@ import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; +import iaik.utils.Base64InputStream; +import iaik.x509.X509Certificate; /** * Parses a <code><VerifyXMLSignatureResponse></code> returned by @@ -115,6 +117,9 @@ public class VerifyXMLSignatureResponseParser { private static final String CERTIFICATE_CHECK_CODE_XPATH = ROOT + MOA + "CertificateCheck/" + MOA + "Code"; + private static final String SIGNING_TIME_XPATH = + ROOT + MOA + "SigningTime"; + /** This is the root element of the XML-Document provided by the Security Layer Card*/ private Element verifyXMLSignatureResponse; @@ -200,7 +205,14 @@ public class VerifyXMLSignatureResponseParser { if (signatureManifestCheckCode != null) { respData.setSignatureManifestCheckCode(new Integer(signatureManifestCheckCode).intValue()); } - respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue()); + respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue()); + + String signingTimeElement = XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNING_TIME_XPATH,""); + if (MiscUtil.isNotEmpty(signingTimeElement)) { + DateTime datetime = ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(signingTimeElement); + respData.setSigningDateTime(datetime.toDate()); + + } } catch (Throwable t) { throw new ParseException("parser.01", null, t); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java index 448e2a0f5..c39d78d8b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java @@ -164,6 +164,13 @@ public class IDPSingleLogOutServlet extends AbstractController { Logger.info("Restart Single LogOut process after timeout ... "); try { SLOInformationContainer sloContainer = transactionStorage.get(restartProcess, SLOInformationContainer.class); + if (sloContainer == null) { + Logger.info("No Single LogOut processing information with ID: " + restartProcess); + handleErrorNoRedirect(new MOAIDException("slo.03", null), req, resp, false); + return; + + } + if (sloContainer.hasFrontChannelOA()) sloContainer.putFailedOA("differntent OAs"); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java index c77542b4a..e5a8bb739 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java @@ -23,6 +23,7 @@ package at.gv.egovernment.moa.id.auth.servlet; import java.io.IOException; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -40,7 +41,6 @@ import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.moduls.SSOManager; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -83,7 +83,10 @@ public class RedirectServlet { oa = authConfig.getServiceProviderConfiguration(url, IOAAuthParameters.class); String authURL = HTTPUtils.extractAuthURLFromRequest(req); - if (oa == null || !authConfig.getPublicURLPrefix().contains(authURL)) { + List<String> allowedPublicUrlPrefixes = authConfig.getPublicURLPrefix(); + + if ((oa == null && !checkRedirectToItself(url, allowedPublicUrlPrefixes)) + || !authConfig.getPublicURLPrefix().contains(authURL)) { resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Parameters not valid"); return; @@ -168,5 +171,17 @@ public class RedirectServlet { } } + + private boolean checkRedirectToItself(String url, List<String> allowedPublicUrlPrefixes) { + if (url != null) { + for (String el : allowedPublicUrlPrefixes) { + if (url.startsWith(el)) + return true; + + } + } + + return false; + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java index 07b5242e0..5aa3a691f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java @@ -25,10 +25,14 @@ package at.gv.egovernment.moa.id.auth.servlet.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringEscapeUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.IRequestStorage; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils; @@ -41,7 +45,9 @@ import at.gv.egovernment.moa.util.MiscUtil; */ public class UniqueSessionIdentifierInterceptor implements HandlerInterceptor { - @Autowired private SSOManager ssomanager; + @Autowired private IRequestStorage requestStorage; + @Autowired(required=false) private SSOManager ssomanager; + /* (non-Javadoc) * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) @@ -50,18 +56,35 @@ public class UniqueSessionIdentifierInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - //get SSO Cookie for Request - String ssoId = ssomanager.getSSOSessionID(request); + String uniqueSessionIdentifier = null; + + //if SSOManager is available, search SessionIdentifier in SSO session + if (ssomanager != null) { + String ssoId = ssomanager.getSSOSessionID(request); + uniqueSessionIdentifier = ssomanager.getUniqueSessionIdentifier(ssoId); + + } + + // search SessionIdentifier in PendingRequest if available + if (MiscUtil.isEmpty(uniqueSessionIdentifier)) { + String pendingReqId = StringEscapeUtils.escapeHtml4( + request.getParameter(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID)); + if (StringUtils.isNotEmpty(pendingReqId)) { + IRequest pendingReq = requestStorage.getPendingRequest(pendingReqId); + if (pendingReq != null) + uniqueSessionIdentifier = pendingReq.getUniqueSessionIdentifier(); + + } + } - //search for unique session identifier - String uniqueSessionIdentifier = ssomanager.getUniqueSessionIdentifier(ssoId); - if (MiscUtil.isEmpty(uniqueSessionIdentifier)) + //if NO SSOSession and no PendingRequest create new SessionIdentifier + if (StringUtils.isEmpty(uniqueSessionIdentifier)) uniqueSessionIdentifier = Random.nextHexRandom16(); TransactionIDUtils.setSessionId(uniqueSessionIdentifier); - request.setAttribute(EAAFConstants.UNIQUESESSIONIDENTIFIER, uniqueSessionIdentifier); - + request.setAttribute(EAAFConstants.UNIQUESESSIONIDENTIFIER, uniqueSessionIdentifier); return true; + } /* (non-Javadoc) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java new file mode 100644 index 000000000..604d224eb --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +/* + * Copyright 2003 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.validator; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.IdentityLink; +import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.util.Constants; + +/** + * This class is used to validate an {@link IdentityLink} + * returned by the security layer + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class IdentityLinkValidator implements Constants { + + // + // XPath namespace prefix shortcuts + // + /** Xpath prefix for reaching PersonData Namespaces */ + private static final String PDATA = PD_PREFIX + ":"; + /** Xpath prefix for reaching SAML Namespaces */ + private static final String SAML = SAML_PREFIX + ":"; + /** Xpath prefix for reaching XML-DSIG Namespaces */ + private static final String DSIG = DSIG_PREFIX + ":"; + /** Xpath prefix for reaching ECDSA Namespaces */ + private static final String ECDSA = ECDSA_PREFIX + ":"; + /** Xpath expression to the root element */ + private static final String ROOT = ""; + /** Xpath expression to the SAML:SubjectConfirmationData element */ + private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH = + ROOT + + SAML + + "AttributeStatement/" + + SAML + + "Subject/" + + SAML + + "SubjectConfirmation/" + + SAML + + "SubjectConfirmationData"; +/** Xpath expression to the PersonData:Person element */ + private static final String PERSON_XPATH = + SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person"; + /** Xpath expression to the SAML:Attribute element */ + private static final String ATTRIBUTE_XPATH = + ROOT + SAML + "AttributeStatement/" + SAML + "Attribute"; +// /** Xpath expression to the SAML:AttributeName attribute */ +// private static final String ATTRIBUTE_NAME_XPATH = +// ROOT + SAML + "AttributeStatement/" + SAML + "Attribute/@AttributeName"; +// /** Xpath expression to the SAML:AttributeNamespace attribute */ +// private static final String ATTRIBUTE_NAMESPACE_XPATH = +// ROOT +// + SAML +// + "AttributeStatement/" +// + SAML +// + "Attribute/@AttributeNamespace"; +// /** Xpath expression to the SAML:AttributeValue element */ +// private static final String ATTRIBUTE_VALUE_XPATH = +// ROOT +// + SAML +// + "AttributeStatement/" +// + SAML +// + "Attribute/" +// + SAML +// + "AttributeValue"; + + /** Singleton instance. <code>null</code>, if none has been created. */ + private static IdentityLinkValidator instance; + + /** + * Constructor for a singleton IdentityLinkValidator. + * @return a new IdentityLinkValidator instance + * @throws ValidateException if no instance can be created + */ + public static synchronized IdentityLinkValidator getInstance() + throws ValidateException { + if (instance == null) { + instance = new IdentityLinkValidator(); + } + return instance; + } + + /** + * Method validate. Validates the {@link IdentityLink} + * @param identityLink The identityLink to validate + * @throws ValidateException on any validation error + */ + public void validate(IIdentityLink identityLink) throws ValidateException { + + Element samlAssertion = identityLink.getSamlAssertion(); + //Search the SAML:ASSERTION Object (A2.054) + if (samlAssertion == null) { + throw new ValidateException("validator.00", null); + } + + // Check how many saml:Assertion/saml:AttributeStatement/ + // saml:Subject/ saml:SubjectConfirmation/ + // saml:SubjectConfirmationData/pr:Person of type + // PhysicalPersonType exist (A2.056) + NodeList nl = XPathUtils.selectNodeList(samlAssertion, PERSON_XPATH); + // If we have just one Person-Element we don't need to check the attributes + int counterPhysicalPersonType = 0; + if (nl.getLength() > 1) + for (int i = 0; i < nl.getLength(); i++) { + String xsiType = + ((Element) nl.item(i)) + .getAttributeNodeNS( + "http://www.w3.org/2001/XMLSchema-instance", + "type") + .getNodeValue(); + // We have to check if xsiType contains "PhysicalPersonType" + // An equal-check will fail because of the Namespace-prefix of the attribute value + if (xsiType.indexOf("PhysicalPersonType") > -1) + counterPhysicalPersonType++; + } + if (counterPhysicalPersonType > 1) + throw new ValidateException("validator.01", null); + + //Check the SAML:ATTRIBUTES + nl = XPathUtils.selectNodeList(samlAssertion, ATTRIBUTE_XPATH); + for (int i = 0; i < nl.getLength(); i++) { + String attributeName = + XPathUtils.getAttributeValue( + (Element) nl.item(i), + "@AttributeName", + null); + String attributeNS = + XPathUtils.getAttributeValue( + (Element) nl.item(i), + "@AttributeNamespace", + null); + if (attributeName.equals("CitizenPublicKey")) { + + if (attributeNS.equals("http://www.buergerkarte.at/namespaces/personenbindung/20020506#") || + attributeNS.equals("urn:publicid:gv.at:namespaces:identitylink:1.2")) { + Element attributeValue = + (Element) XPathUtils.selectSingleNode((Element) nl.item(i),nSMap, SAML + "AttributeValue/" + DSIG + "RSAKeyValue"); + if (attributeValue==null) + attributeValue = + (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + ECDSA + "ECDSAKeyValue"); + if (attributeValue==null) + attributeValue = + (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + DSIG + "DSAKeyValue"); + if (attributeValue == null) + throw new ValidateException("validator.02", null); + + } + else + throw new ValidateException("validator.03", new Object [] {attributeNS} ); + } + else + throw new ValidateException("validator.04", new Object [] {attributeName} ); + } + + //Check if dsig:Signature exists + Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion,ROOT + DSIG + "Signature"); + if (dsigSignature==null) throw new ValidateException("validator.05", new Object[] {"in der Personenbindung"}); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java new file mode 100644 index 000000000..d1c67b06e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +/* + * Copyright 2003 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.validator; + +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><VerifyXMLSignatureRequestBuilder></code> structure + * used for sending the DSIG-Signature of the Security Layer card for validating to MOA-SP. + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureRequestBuilder { + + /** shortcut for XMLNS namespace URI */ + private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; + /** shortcut for MOA namespace URI */ + private static final String MOA_NS_URI = Constants.MOA_NS_URI; + /** The DSIG-Prefix */ + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + + /** The document containing the <code>VerifyXMLsignatureRequest</code> */ + private Document requestDoc_; + /** the <code>VerifyXMLsignatureRequest</code> root element */ + private Element requestElem_; + + + /** + * Builds the body for a <code>VerifyXMLsignatureRequest</code> including the root + * element and namespace declarations. + * + * @throws BuildException If an error occurs on building the document. + */ + public VerifyXMLSignatureRequestBuilder() throws BuildException { + try { + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + requestDoc_ = docBuilder.newDocument(); + requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); + requestDoc_.appendChild(requestElem_); + } catch (Throwable t) { + throw new BuildException( + "builder.00", + new Object[] {"VerifyXMLSignatureRequest", t.toString()}, + t); + } + } + + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from an IdentityLink with a known trustProfileID which + * has to exist in MOA-SP + * @param identityLink - The IdentityLink + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * + * @return Element - The complete request as Dom-Element + * + * @throws ParseException + */ + public Element build(IIdentityLink identityLink, String trustProfileID) + throws ParseException + { + try { + // build the request + Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); + requestElem_.appendChild(dateTimeElem); + Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); + dateTimeElem.appendChild(dateTime); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); + verifySignatureEnvironmentElem.appendChild(base64ContentElem); + // insert the base64 encoded identity link SAML assertion + String serializedAssertion = identityLink.getSerializedSamlAssertion(); + String base64EncodedAssertion = Base64Utils.encode(serializedAssertion.getBytes("UTF-8")); + //replace all '\r' characters by no char. + StringBuffer replaced = new StringBuffer(); + for (int i = 0; i < base64EncodedAssertion.length(); i ++) { + char c = base64EncodedAssertion.charAt(i); + if (c != '\r') { + replaced.append(c); + } + } + base64EncodedAssertion = replaced.toString(); + Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); + base64ContentElem.appendChild(base64Content); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + // add the transforms + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); + + for (int i = 0; i < dsigTransforms.length; i++) { + Element verifyTransformsInfoProfileElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); + verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true)); + } + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + } catch (Throwable t) { + throw new ParseException("builder.00", + new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); + } + + return requestElem_; + } + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from an IdentityLink with a known trustProfileID which + * has to exist in MOA-SP + * @param identityLink - The IdentityLink + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * + * @return Element - The complete request as Dom-Element + * + * @throws ParseException + */ + public Element build(byte[]mandate, String trustProfileID) + throws ParseException + { + try { + // build the request +// Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +// requestElem_.appendChild(dateTimeElem); +// Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +// dateTimeElem.appendChild(dateTime); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); + verifySignatureEnvironmentElem.appendChild(base64ContentElem); + // insert the base64 encoded identity link SAML assertion + //String serializedAssertion = identityLink.getSerializedSamlAssertion(); + //String base64EncodedAssertion = Base64Utils.encode(mandate.getBytes("UTF-8")); + String base64EncodedAssertion = Base64Utils.encode(mandate); + //replace all '\r' characters by no char. + StringBuffer replaced = new StringBuffer(); + for (int i = 0; i < base64EncodedAssertion.length(); i ++) { + char c = base64EncodedAssertion.charAt(i); + if (c != '\r') { + replaced.append(c); + } + } + base64EncodedAssertion = replaced.toString(); + Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); + base64ContentElem.appendChild(base64Content); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +// // add the transforms +// Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +// signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +// Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +// +// for (int i = 0; i < dsigTransforms.length; i++) { +// Element verifyTransformsInfoProfileElem = +// requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +// referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +// verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true)); +// } + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + } catch (Throwable t) { + throw new ParseException("builder.00", + new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); + } + + return requestElem_; + } + + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from the signed AUTH-Block with a known trustProfileID which + * has to exist in MOA-SP + * @param csr - signed AUTH-Block + * @param verifyTransformsInfoProfileID - allowed verifyTransformsInfoProfileID + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * @return Element - The complete request as Dom-Element + * @throws ParseException + */ + public Element build( + CreateXMLSignatureResponse csr, + List<String> verifyTransformsInfoProfileID, + String trustProfileID) + throws BuildException { //samlAssertionObject + + try { + // build the request +// requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:" +// + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); + verifySignatureEnvironmentElem.appendChild(xmlContentElem); + xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); + // insert the SAML assertion + xmlContentElem.appendChild(requestDoc_.importNode(csr.getSamlAssertion(), true)); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); + // add the transform profile IDs + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + +// for (int i = 0; i < verifyTransformsInfoProfileID.length; i++) { +// +// Element verifyTransformsInfoProfileIDElem = +// requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +// referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +// verifyTransformsInfoProfileIDElem.appendChild( +// requestDoc_.createTextNode(verifyTransformsInfoProfileID[i])); +// } + + for (String element : verifyTransformsInfoProfileID) { + + Element verifyTransformsInfoProfileIDElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); + verifyTransformsInfoProfileIDElem.appendChild( + requestDoc_.createTextNode(element)); + } + + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + + } catch (Throwable t) { + throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); + } + + return requestElem_; + } + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from the signed data with a known trustProfileID which + * has to exist in MOA-SP + * @param csr - signed AUTH-Block + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * @return Element - The complete request as Dom-Element + * @throws ParseException + */ + public Element buildDsig( + CreateXMLSignatureResponse csr, + String trustProfileID) + throws BuildException { //samlAssertionObject + + try { + // build the request +// requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:" +// + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); + + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + + Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); + verifySignatureEnvironmentElem.appendChild(xmlContentElem); + xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); + + // insert the dsig:Signature + xmlContentElem.appendChild(requestDoc_.importNode(csr.getDsigSignature(), true)); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode("/"+ DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); + // add the transform profile IDs + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + + } catch (Throwable t) { + throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); + } + + return requestElem_; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java new file mode 100644 index 000000000..b9c15e75e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +/* + * Copyright 2003 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.validator; + +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; +import iaik.asn1.structures.Name; +import iaik.security.ec.common.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +/** + * This class is used to validate an {@link VerifyXMLSignatureResponse} + * returned by MOA-SPSS + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureResponseValidator { + + /** Identification string for checking identity link */ + public static final String CHECK_IDENTITY_LINK = "IdentityLink"; + /** Identification string for checking authentication block */ + public static final String CHECK_AUTH_BLOCK = "AuthBlock"; + + /** Singleton instance. <code>null</code>, if none has been created. */ + private static VerifyXMLSignatureResponseValidator instance; + + /** + * Constructor for a singleton VerifyXMLSignatureResponseValidator. + */ + public static synchronized VerifyXMLSignatureResponseValidator getInstance() + throws ValidateException { + if (instance == null) { + instance = new VerifyXMLSignatureResponseValidator(); + } + return instance; + } + + /** + * Validates a {@link VerifyXMLSignatureResponse} returned by MOA-SPSS. + * + * @param verifyXMLSignatureResponse the <code><VerifyXMLSignatureResponse></code> + * @param identityLinkSignersSubjectDNNames subject names configured + * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated + * @param oaParam specifies whether the validation result of the + * manifest has to be ignored (identityLink validation if + * the OA is a business service) or not + * @throws ValidateException on any validation error + * @throws ConfigurationException + */ + public void validate(IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, + List<String> identityLinkSignersSubjectDNNames, + String whatToCheck, + IOAAuthParameters oaParam, + AuthConfiguration authConfig) + throws ValidateException, ConfigurationException { + + if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) + throw new ValidateException("validator.06", new Object[] {whatToCheck}); + + if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) { + String checkFailedReason =""; + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 1) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.21", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 2) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.22", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 3) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.23", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 4) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null); + +// TEST CARDS + if (whatToCheck.equals(CHECK_IDENTITY_LINK)) + throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); + else + throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); + } + + //check QC + if (authConfig.isCertifiacteQCActive() && + !whatToCheck.equals(CHECK_IDENTITY_LINK) && + !verifyXMLSignatureResponse.isQualifiedCertificate()) { + + //check if testcards are active and certificate has an extension for test credentials + if (oaParam.isTestCredentialEnabled()) { + boolean foundTestCredentialOID = false; + try { + X509Certificate signerCert = verifyXMLSignatureResponse.getX509certificate(); + + List<String> validOIDs = new ArrayList<String>(); + if (oaParam.getTestCredentialOIDs() != null) + validOIDs.addAll(oaParam.getTestCredentialOIDs()); + else + validOIDs.add(MOAIDAuthConstants.TESTCREDENTIALROOTOID); + + Set<String> extentsions = signerCert.getCriticalExtensionOIDs(); + extentsions.addAll(signerCert.getNonCriticalExtensionOIDs()); + Iterator<String> extit = extentsions.iterator(); + while(extit.hasNext()) { + String certOID = extit.next(); + for (String el : validOIDs) { + if (certOID.startsWith(el)) + foundTestCredentialOID = true; + } + } + + } catch (Exception e) { + Logger.warn("Test credential OID extraction FAILED.", e); + + } + //throw Exception if not TestCredentialOID is found + if (!foundTestCredentialOID) + throw new ValidateException("validator.72", null); + + } else + throw new ValidateException("validator.71", null); + } + + // if OA is type is business service the manifest validation result has + // to be ignored + boolean ignoreManifestValidationResult = false; + if (whatToCheck.equals(CHECK_IDENTITY_LINK)) + ignoreManifestValidationResult = (oaParam.hasBaseIdInternalProcessingRestriction()) ? true + : false; + + if (ignoreManifestValidationResult) { + Logger.debug("OA type is business service, thus ignoring DSIG manifest validation result"); + } else { + if (verifyXMLSignatureResponse.isXmlDSIGManigest()) + if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0) + throw new ValidateException("validator.08", null); + } + + + // Check the signature manifest only when verifying the signed AUTHBlock + if (whatToCheck.equals(CHECK_AUTH_BLOCK)) { + if (verifyXMLSignatureResponse.getSignatureManifestCheckCode() > 0) { + throw new ValidateException("validator.50", null); + } + } + + //Check whether the returned X509 SubjectName is in the MOA-ID configuration or not + if (identityLinkSignersSubjectDNNames != null) { + String subjectDN = ""; + X509Certificate x509Cert = verifyXMLSignatureResponse.getX509certificate(); + try { + subjectDN = ((Name) x509Cert.getSubjectDN()).getRFC2253String(); + } + catch (RFC2253NameParserException e) { + throw new ValidateException("validator.17", null); + } + //System.out.println("subjectDN: " + subjectDN); + // check the authorisation to sign the identity link + if (!identityLinkSignersSubjectDNNames.contains(subjectDN)) { + // subject DN check failed, try OID check: + try { + if (x509Cert.getExtension(MOAIDAuthConstants.IDENTITY_LINK_SIGNER_OID) == null) { + throw new ValidateException("validator.18", new Object[] { subjectDN }); + } else { + Logger.debug("Identity link signer cert accepted for signing identity link: " + + "subjectDN check failed, but OID check successfully passed."); + } + } catch (X509ExtensionInitException e) { + throw new ValidateException("validator.49", null); + } + } else { + Logger.debug("Identity link signer cert accepted for signing identity link: " + + "subjectDN check successfully passed."); + } + + } + } + + /** + * Method validateCertificate. + * @param verifyXMLSignatureResponse The VerifyXMLSignatureResponse + * @param idl The Identitylink + * @throws ValidateException + */ + public void validateCertificate( + IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, + IIdentityLink idl) + throws ValidateException { + + X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate(); + PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey(); + + PublicKey pubKeySignature = x509Response.getPublicKey(); + checkIDLAgainstSignatureCertificate(pubKeysIdentityLink, pubKeySignature); + + } + + + public void checkIDLAgainstSignatureCertificate( PublicKey[] pubKeysIdentityLink, PublicKey pubKeySignature) throws ValidateException { + boolean found = false; + for (int i = 0; i < pubKeysIdentityLink.length; i++) { + PublicKey idlPubKey = pubKeysIdentityLink[i]; + //compare RSAPublicKeys + if ((idlPubKey instanceof java.security.interfaces.RSAPublicKey) && + (pubKeySignature instanceof java.security.interfaces.RSAPublicKey)) { + + RSAPublicKey rsaPubKeySignature = (RSAPublicKey) pubKeySignature; + RSAPublicKey rsakey = (RSAPublicKey) pubKeysIdentityLink[i]; + + if (rsakey.getModulus().equals(rsaPubKeySignature.getModulus()) + && rsakey.getPublicExponent().equals(rsaPubKeySignature.getPublicExponent())) + found = true; + } + + //compare ECDSAPublicKeys + if( ( (idlPubKey instanceof java.security.interfaces.ECPublicKey) || + (idlPubKey instanceof ECPublicKey)) && + ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) || + (pubKeySignature instanceof ECPublicKey) ) ) { + + try { + ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded()); + ECPublicKey ecdsakey = new ECPublicKey(pubKeysIdentityLink[i].getEncoded()); + + if(ecdsakey.equals(ecdsaPubKeySignature)) + found = true; + + } catch (InvalidKeyException e) { + Logger.warn("ECPublicKey can not parsed into a iaik.ECPublicKey", e); + throw new ValidateException("validator.09", null); + } + + + + } + +// Logger.debug("IDL-Pubkey=" + idl.getPublicKey()[i].getClass().getName() +// + " Resp-Pubkey=" + pubKeySignature.getClass().getName()); + + } + + if (!found) { + + throw new ValidateException("validator.09", null); + + } + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/client/utils/SZRGWClientUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/client/utils/SZRGWClientUtils.java index ee5cb2395..a9abc2c5f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/client/utils/SZRGWClientUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/client/utils/SZRGWClientUtils.java @@ -1,200 +1,200 @@ -/* - * 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.client.utils; - -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.UUID; - -import org.opensaml.xml.util.XMLHelper; -import org.w3c.dom.Element; - -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egovernment.moa.id.client.SZRGWClient; -import at.gv.egovernment.moa.id.client.SZRGWClientException; -import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; -import at.gv.egovernment.moa.id.commons.api.ConnectionParameterInterface; -import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; -import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; -import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.util.MiscUtil; -import at.gv.util.xsd.mis.MandateIdentifiers; -import at.gv.util.xsd.mis.Target; -import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest; -import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest.PEPSData; -import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse; -import at.gv.util.xsd.srzgw.MISType; -import at.gv.util.xsd.srzgw.MISType.Filters; - -/** - * @author tlenz - * - */ -public class SZRGWClientUtils { - - /** - * Does the request to the SZR-GW. - * - * @param signature the signature - * @return the identity link - * @throws SZRGWClientException the sZRGW client exception - * @throws ConfigurationException the configuration exception - */ - public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, Element signature) throws SZRGWClientException, ConfigurationException { - return getIdentityLink(pendingReq, null, null, null, null, XMLHelper.nodeToString(signature), null); - } - - /** - * Does the request to the SZR-GW. - * - * @param PEPSIdentifier the pEPS identifier - * @param PEPSFirstname the pEPS firstname - * @param PEPSFamilyname the pEPS familyname - * @param PEPSDateOfBirth the pEPS date of birth - * @param signature XMLDSIG signature - * @return Identity link assertion - * @throws SZRGWClientException the sZRGW client exception - * @throws ConfigurationException the configuration exception - */ - public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String signature, String PEPSFiscalNumber) throws SZRGWClientException { - return getIdentityLink(pendingReq, PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, null, signature, null, null, null, null, null, null, null, PEPSFiscalNumber); - } - - /** - * SZR-GW Client interface. - * - * @param eIdentifier the e identifier - * @param givenName the given name - * @param lastName the last name - * @param dateOfBirth the date of birth - * @param citizenSignature the citizen signature - * @param representative the representative - * @param represented the represented - * @param mandate the mandate - * @return the identity link - * @throws SZRGWClientException the sZRGW client exception - */ - public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String eIdentifier, - String givenName, String lastName, String dateOfBirth, String gender, - String citizenSignature, String representative, String represented, - String mandate, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { - return getIdentityLink(pendingReq, eIdentifier, givenName, lastName, dateOfBirth, gender, - citizenSignature, representative, represented, mandate, null, - null, targetType, targetValue, oaFriendlyName, filters, PEPSFiscalNumber); - } - - /** - * Gets the identity link. - * - * @param citizenSignature the citizen signature - * @param representative the representative - * @param represented the represented - * @param mandate the mandate - * @param organizationAddress the organization address - * @param organizationType the organization type - * @return the identity link - * @throws SZRGWClientException - */ - public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String citizenSignature, - String representative, String represented, String mandateContent, - String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { - return getIdentityLink(pendingReq, null, null, null, null, null, - citizenSignature, represented, representative, mandateContent, organizationAddress, - organizationType, targetType, targetValue, oaFriendlyName, filters, PEPSFiscalNumber); - } - - public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String gender, String citizenSignature, String represented, String representative, String mandateContent, String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { - - try { - AuthConfiguration authConf = AuthConfigurationProviderFactory.getInstance(); - ConnectionParameterInterface connectionParameters = authConf.getForeignIDConnectionParameter(pendingReq.getServiceProviderConfiguration(IOAAuthParameters.class)); - - String requestID = UUID.randomUUID().toString(); - SZRGWClient client = new SZRGWClient(connectionParameters); - - CreateIdentityLinkRequest request = new CreateIdentityLinkRequest(); - request.setSignature(citizenSignature.getBytes("UTF-8")); - request.setReqID(requestID); - if(PEPSDateOfBirth!=null || PEPSFamilyname!=null || PEPSFirstname!=null || PEPSIdentifier!=null || representative!=null || represented!=null || mandateContent!=null || organizationAddress!=null || organizationType!=null) - { - PEPSData data = new PEPSData(); - data.setDateOfBirth(PEPSDateOfBirth); - data.setFamilyname(PEPSFamilyname); - data.setFirstname(PEPSFirstname); - data.setIdentifier(PEPSIdentifier); - - data.setFiscalNumber(PEPSFiscalNumber); - - data.setRepresentative(representative); - data.setRepresented(represented); - data.setMandateContent(mandateContent); - - data.setLegalPersonCanonicalRegisteredAddress(organizationAddress); - data.setLegalPersonTranslatableType(organizationType); - - request.setPEPSData(data); - } - if (null != mandateContent) { - MISType mis = new MISType(); - - Target targetObject = new Target(); - targetObject.setType(targetType); - targetObject.setValue(targetValue); - mis.setTarget(targetObject); - - mis.setOAFriendlyName(oaFriendlyName); - - Filters filterObject = new Filters(); - MandateIdentifiers mandateIds = new MandateIdentifiers(); - for(String current : filters) - mandateIds.getMandateIdentifier().add(current.trim()); - filterObject.setMandateIdentifiers(mandateIds); - mis.setFilters(filterObject); - - request.setMIS(mis); - } - - if (MiscUtil.isEmpty(connectionParameters.getUrl())) { - Logger.warn("SZR-Gateway Service URL is empty"); - throw new SZRGWClientException("service.07"); - } - - Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")..."); - CreateIdentityLinkResponse response = client.sentCreateIDLRequest(request, connectionParameters.getUrl()); - return response; - - } - catch (ConfigurationException e) { - Logger.warn(e); - Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null )); - } catch (UnsupportedEncodingException e) { - Logger.warn(e); - } - - return null; - - } - -} +///* +// * 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.client.utils; +// +//import java.io.UnsupportedEncodingException; +//import java.util.List; +//import java.util.UUID; +// +//import org.opensaml.xml.util.XMLHelper; +//import org.w3c.dom.Element; +// +//import at.gv.egiz.eaaf.core.api.IRequest; +//import at.gv.egovernment.moa.id.client.SZRGWClient; +//import at.gv.egovernment.moa.id.client.SZRGWClientException; +//import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +//import at.gv.egovernment.moa.id.commons.api.ConnectionParameterInterface; +//import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +//import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +//import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +//import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +//import at.gv.egovernment.moa.logging.Logger; +//import at.gv.egovernment.moa.util.MiscUtil; +//import at.gv.util.xsd.mis.MandateIdentifiers; +//import at.gv.util.xsd.mis.Target; +//import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest; +//import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest.PEPSData; +//import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse; +//import at.gv.util.xsd.srzgw.MISType; +//import at.gv.util.xsd.srzgw.MISType.Filters; +// +///** +// * @author tlenz +// * +// */ +//public class SZRGWClientUtils { +// +// /** +// * Does the request to the SZR-GW. +// * +// * @param signature the signature +// * @return the identity link +// * @throws SZRGWClientException the sZRGW client exception +// * @throws ConfigurationException the configuration exception +// */ +// public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, Element signature) throws SZRGWClientException, ConfigurationException { +// return getIdentityLink(pendingReq, null, null, null, null, XMLHelper.nodeToString(signature), null); +// } +// +// /** +// * Does the request to the SZR-GW. +// * +// * @param PEPSIdentifier the pEPS identifier +// * @param PEPSFirstname the pEPS firstname +// * @param PEPSFamilyname the pEPS familyname +// * @param PEPSDateOfBirth the pEPS date of birth +// * @param signature XMLDSIG signature +// * @return Identity link assertion +// * @throws SZRGWClientException the sZRGW client exception +// * @throws ConfigurationException the configuration exception +// */ +// public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String signature, String PEPSFiscalNumber) throws SZRGWClientException { +// return getIdentityLink(pendingReq, PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, null, signature, null, null, null, null, null, null, null, PEPSFiscalNumber); +// } +// +// /** +// * SZR-GW Client interface. +// * +// * @param eIdentifier the e identifier +// * @param givenName the given name +// * @param lastName the last name +// * @param dateOfBirth the date of birth +// * @param citizenSignature the citizen signature +// * @param representative the representative +// * @param represented the represented +// * @param mandate the mandate +// * @return the identity link +// * @throws SZRGWClientException the sZRGW client exception +// */ +// public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String eIdentifier, +// String givenName, String lastName, String dateOfBirth, String gender, +// String citizenSignature, String representative, String represented, +// String mandate, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { +// return getIdentityLink(pendingReq, eIdentifier, givenName, lastName, dateOfBirth, gender, +// citizenSignature, representative, represented, mandate, null, +// null, targetType, targetValue, oaFriendlyName, filters, PEPSFiscalNumber); +// } +// +// /** +// * Gets the identity link. +// * +// * @param citizenSignature the citizen signature +// * @param representative the representative +// * @param represented the represented +// * @param mandate the mandate +// * @param organizationAddress the organization address +// * @param organizationType the organization type +// * @return the identity link +// * @throws SZRGWClientException +// */ +// public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String citizenSignature, +// String representative, String represented, String mandateContent, +// String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { +// return getIdentityLink(pendingReq, null, null, null, null, null, +// citizenSignature, represented, representative, mandateContent, organizationAddress, +// organizationType, targetType, targetValue, oaFriendlyName, filters, PEPSFiscalNumber); +// } +// +// public static CreateIdentityLinkResponse getIdentityLink(IRequest pendingReq, String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String gender, String citizenSignature, String represented, String representative, String mandateContent, String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, List<String> filters, String PEPSFiscalNumber) throws SZRGWClientException { +// +// try { +// AuthConfiguration authConf = AuthConfigurationProviderFactory.getInstance(); +// ConnectionParameterInterface connectionParameters = authConf.getForeignIDConnectionParameter(pendingReq.getServiceProviderConfiguration(IOAAuthParameters.class)); +// +// String requestID = UUID.randomUUID().toString(); +// SZRGWClient client = new SZRGWClient(connectionParameters); +// +// CreateIdentityLinkRequest request = new CreateIdentityLinkRequest(); +// request.setSignature(citizenSignature.getBytes("UTF-8")); +// request.setReqID(requestID); +// if(PEPSDateOfBirth!=null || PEPSFamilyname!=null || PEPSFirstname!=null || PEPSIdentifier!=null || representative!=null || represented!=null || mandateContent!=null || organizationAddress!=null || organizationType!=null) +// { +// PEPSData data = new PEPSData(); +// data.setDateOfBirth(PEPSDateOfBirth); +// data.setFamilyname(PEPSFamilyname); +// data.setFirstname(PEPSFirstname); +// data.setIdentifier(PEPSIdentifier); +// +// data.setFiscalNumber(PEPSFiscalNumber); +// +// data.setRepresentative(representative); +// data.setRepresented(represented); +// data.setMandateContent(mandateContent); +// +// data.setLegalPersonCanonicalRegisteredAddress(organizationAddress); +// data.setLegalPersonTranslatableType(organizationType); +// +// request.setPEPSData(data); +// } +// if (null != mandateContent) { +// MISType mis = new MISType(); +// +// Target targetObject = new Target(); +// targetObject.setType(targetType); +// targetObject.setValue(targetValue); +// mis.setTarget(targetObject); +// +// mis.setOAFriendlyName(oaFriendlyName); +// +// Filters filterObject = new Filters(); +// MandateIdentifiers mandateIds = new MandateIdentifiers(); +// for(String current : filters) +// mandateIds.getMandateIdentifier().add(current.trim()); +// filterObject.setMandateIdentifiers(mandateIds); +// mis.setFilters(filterObject); +// +// request.setMIS(mis); +// } +// +// if (MiscUtil.isEmpty(connectionParameters.getUrl())) { +// Logger.warn("SZR-Gateway Service URL is empty"); +// throw new SZRGWClientException("service.07"); +// } +// +// Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")..."); +// CreateIdentityLinkResponse response = client.sentCreateIDLRequest(request, connectionParameters.getUrl()); +// return response; +// +// } +// catch (ConfigurationException e) { +// Logger.warn(e); +// Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null )); +// } catch (UnsupportedEncodingException e) { +// Logger.warn(e); +// } +// +// return null; +// +// } +// +//} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameterDecorator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameterDecorator.java index 6ecba5820..a2dfeba2f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameterDecorator.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameterDecorator.java @@ -909,6 +909,18 @@ public boolean containsConfigurationKey(String arg0) { } +@Override +public List<String> foreignbPKSectorsRequested() { + String value = spConfiguration.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_FOREIGN); + if (MiscUtil.isNotEmpty(value)) + return KeyValueUtils.getListOfCSVValues(KeyValueUtils.normalizeCSVValueString(value)); + + else + return null; + +} + + @Override public Map<String, String> getFullConfiguration() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java index d5328618a..fff019ae7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java @@ -441,41 +441,42 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide return result; } - /** - * Returns the {@link ConnectionParameter} for the ForeignID. NOTE: may return {@code null}. - * - * @return the connection parameter. - * @throws ConfigurationException is thrown in case of missing {@link AuthComponentGeneral}. - */ - @Transactional - public ConnectionParameter getForeignIDConnectionParameter(IOAAuthParameters oaParameters) throws ConfigurationException { - String serviceURL = null; - try { - //load OA specific MIS service URL if OA configuration exists - if (oaParameters != null) - serviceURL = oaParameters.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_EXTERNAL_SZRGW_SERVICE_URL); - - //get first entry from general configuration if no OA specific URL exists - if (MiscUtil.isEmpty(serviceURL)) { - List<String> serviceURLs = KeyValueUtils.getListOfCSVValues( - configuration.getStringValue(MOAIDConfigurationConstants.GENERAL_AUTH_SERVICES_SZRGW_URL)); - if (serviceURLs.size() > 0) - serviceURL = serviceURLs.get(0); - - } - - if (MiscUtil.isNotEmpty(serviceURL)) - return new ConnectionParameterMandate(serviceURL, getFullConfigurationProperties(), getRootConfigFileDir()); - - else - throw new ConfigurationException("service.09", new Object[]{"NO SZR-GW Service URL"}); - - } catch (at.gv.egiz.components.configuration.api.ConfigurationException e) { - Logger.warn("Initialize SZR-GW service connection parameters FAILED.", e); - throw new ConfigurationException("service.09", new Object[]{e.getMessage()}, e); - - } - } +// /** +// * Returns the {@link ConnectionParameter} for the ForeignID. NOTE: may return {@code null}. +// * +// * @return the connection parameter. +// * @throws ConfigurationException is thrown in case of missing {@link AuthComponentGeneral}. +// */ +// @Transactional +// @Deprecated +// public ConnectionParameter getForeignIDConnectionParameter(IOAAuthParameters oaParameters) throws ConfigurationException { +// String serviceURL = null; +// try { +// //load OA specific MIS service URL if OA configuration exists +// if (oaParameters != null) +// serviceURL = oaParameters.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_EXTERNAL_CENTRAL_EIDASNODE_SERVICE_URL); +// +// //get first entry from general configuration if no OA specific URL exists +// if (MiscUtil.isEmpty(serviceURL)) { +// List<String> serviceURLs = KeyValueUtils.getListOfCSVValues( +// configuration.getStringValue(MOAIDConfigurationConstants.GENERAL_AUTH_SERVICES_CENTRAL_EIDASNODE_URL)); +// if (serviceURLs.size() > 0) +// serviceURL = serviceURLs.get(0); +// +// } +// +// if (MiscUtil.isNotEmpty(serviceURL)) +// return new ConnectionParameterMandate(serviceURL, getFullConfigurationProperties(), getRootConfigFileDir()); +// +// else +// throw new ConfigurationException("service.09", new Object[]{"NO SZR-GW Service URL"}); +// +// } catch (at.gv.egiz.components.configuration.api.ConfigurationException e) { +// Logger.warn("Initialize SZR-GW service connection parameters FAILED.", e); +// throw new ConfigurationException("service.09", new Object[]{e.getMessage()}, e); +// +// } +// } /** * Returns the {@link ConnectionParameter} for the OnlineMandates. NOTE: may return {@code null}. @@ -1056,7 +1057,7 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide Logger.info("Online application with identifier " + id + " is found, but NOT active."); } else - Logger.warn("Online application with identifier " + id + " is not found."); + Logger.info("Online application with identifier " + id + " is not found."); } catch (at.gv.egiz.components.configuration.api.ConfigurationException e) { @@ -1282,7 +1283,9 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide //check AuthURL against ConfigurationURL if (configuredURL.getHost().equals(requestedURL.getHost()) && configPort == authURLPort && - configuredURL.getPath().equals(requestedURL.getPath())) { + ( configuredURL.getPath().equals(requestedURL.getPath()) + || requestedURL.getPath().startsWith(configuredURL.getPath()) ) + && configuredURL.getProtocol().equals(requestedURL.getProtocol()) ) { Logger.debug("Select configurated PublicURLPrefix: " + configuredURL + " for authURL: " + requestedURL); resultURL = configuredURL; 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 index 86235a26d..390b77dab 100644 --- 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 @@ -533,6 +533,13 @@ public class DynamicOAAuthParameters implements IOAAuthParameters, Serializable{ return false; } + + @Override + public List<String> foreignbPKSectorsRequested() { + // TODO Auto-generated method stub + return null; + } + @Override public boolean containsConfigurationKey(String arg0) { // TODO Auto-generated method stub diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/UserWhitelistStore.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/UserWhitelistStore.java new file mode 100644 index 000000000..9c296e2b8 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/UserWhitelistStore.java @@ -0,0 +1,154 @@ +package at.gv.egovernment.moa.id.config.auth.data; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.UserRestrictionTask; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.util.MiscUtil; +import at.gv.egovernment.moaspss.logging.Logger; + +@Service("UserWhiteList_Store") +public class UserWhitelistStore { + + @Autowired(required=true) AuthConfiguration authConfig; + + private List<String> whitelist = new ArrayList<String>(); + private String absWhiteListUrl = null; + + @PostConstruct + private void initialize() { + String whiteListUrl = authConfig.getBasicConfiguration(UserRestrictionTask.CONFIG_PROPS_CSV_USER_FILE); + String internalTarget = authConfig.getBasicConfiguration(UserRestrictionTask.CONFIG_PROPS_CSV_USER_SECTOR); + if (MiscUtil.isEmpty(whiteListUrl) || MiscUtil.isEmpty(internalTarget)) + Logger.debug("Do not initialize user whitelist. Reason: NO configuration path to CSV file or NO internal bPK target for whitelist"); + + else { + if (internalTarget.startsWith(MOAIDAuthConstants.PREFIX_CDID)) + internalTarget = internalTarget.substring(MOAIDAuthConstants.PREFIX_CDID.length()); + else if (internalTarget.startsWith(MOAIDAuthConstants.PREFIX_WPBK)) + internalTarget = internalTarget.substring(MOAIDAuthConstants.PREFIX_WPBK.length()); + else if (internalTarget.startsWith(MOAIDAuthConstants.PREFIX_EIDAS)) + internalTarget = internalTarget.substring(MOAIDAuthConstants.PREFIX_EIDAS.length()); + else { + Logger.warn("Sector: " + internalTarget + " is NOT supported for user whitelist."); + Logger.info("User whitelist-store MAY NOT contains all user from whitelist"); + } + + try { + absWhiteListUrl = new URL(FileUtils.makeAbsoluteURL(whiteListUrl, authConfig.getConfigurationRootDirectory())) + .toURI().toString().substring("file:".length()); + InputStream is = new FileInputStream(new File(absWhiteListUrl)); + String whiteListString = IOUtils.toString(new InputStreamReader(is)); + List<String> preWhitelist = KeyValueUtils.getListOfCSVValues(KeyValueUtils.normalizeCSVValueString(whiteListString)); + + + + //remove prefix if required + for (String bPK : preWhitelist) { + String[] bPKSplit = bPK.split(":"); + if (bPKSplit.length == 1) + whitelist.add(bPK); + + else if (bPKSplit.length ==2 ) { + if (internalTarget.equals(bPKSplit[0])) + whitelist.add(bPKSplit[1]); + else + Logger.info("Whitelist entry: " + bPK + " has an unsupported target. Entry will be removed ..."); + + } else + Logger.info("Whitelist entry: " + bPK + " has an unsupported format. Entry will be removed ..."); + + } + + Logger.info("User whitelist is initialized with " + whitelist.size() + " entries."); + + + } catch (FileNotFoundException e) { + Logger.warn("Do not initialize user whitelist. Reason: CSV file with bPKs NOT found", e); + + } catch (IOException e) { + Logger.warn("Do not initialize user whitelist. Reason: CSV file is NOT readable", e); + + } catch (URISyntaxException e) { + Logger.warn("Do not initialize user whitelist. Reason: CSV file looks wrong", e); + + } + + } + + } + + /** + * Get the number of entries of the static whitelist + * + * @return + */ + public int getNumberOfEntries() { + return whitelist.size(); + } + + /** + * Check if bPK is in whitelist + * + * @param bPK + * @return true if bPK is in whitelist, otherwise false + */ + public boolean isUserbPKInWhitelist(String bPK) { + if (whitelist != null) + return whitelist.contains(bPK); + else + return false; + + } + + public boolean isUserbPKInWhitelistDynamic(String bPK) { + return isUserbPKInWhitelistDynamic(bPK, false); + + } + + public boolean isUserbPKInWhitelistDynamic(String bPK, boolean onlyDynamic) { + try { + if (absWhiteListUrl != null) { + InputStream is = new FileInputStream(new File(absWhiteListUrl)); + String whiteListString = IOUtils.toString(new InputStreamReader(is)); + if (whiteListString != null && whiteListString.contains(bPK)) { + Logger.trace("Find user with dynamic whitelist check"); + return true; + + } else { + Logger.debug("Can NOT find user in dynamic loaded user whitelist. Switch to static version ... "); + if (!onlyDynamic) + return isUserbPKInWhitelist(bPK); + } + + } + } catch (Exception e) { + Logger.warn("Dynamic user whitelist check FAILED. Switch to static version ... ", e); + + } + if (!onlyDynamic) + return isUserbPKInWhitelist(bPK); + + + return false; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MOAAuthenticationData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MOAAuthenticationData.java index b5d46fea3..ca0ae0687 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MOAAuthenticationData.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/MOAAuthenticationData.java @@ -105,6 +105,9 @@ public class MOAAuthenticationData extends AuthenticationData implements IMOAAut @Override public List<String> getEncbPKList() { + if (this.encbPKList == null) + this.encbPKList = new ArrayList<String>(); + return this.encbPKList; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index c2dd7b4ba..6544766b2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -95,7 +95,7 @@ public class AuthenticationManager extends AbstractAuthenticationManager { } if (MiscUtil.isEmpty(internalSSOId)) - internalSSOId = pendingReq.getSSOSessionIdentifier(); + internalSSOId = pendingReq.getInternalSSOSessionIdentifier(); } else { AuthenticationSessionExtensions sessionExt; 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 1274a0407..97c4f40cd 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 @@ -43,11 +43,12 @@ import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionExtensions; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; -import at.gv.egovernment.moa.id.commons.api.data.IAuthenticationSession; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.SessionDataStorageException; import at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore; @@ -85,7 +86,7 @@ public class SSOManager implements ISSOManager { //@Autowired private MOASessionDBUtils moaSessionDBUtils; - + @Override public boolean checkAndValidateSSOSession(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp) throws EAAFSSOException { try { //get SSO cookie from http request @@ -112,10 +113,7 @@ public class SSOManager implements ISSOManager { //check if SSO Session is valid boolean isSSOValid = isValidSSOSession(ssoId, pendingReq); - - if (isSSOValid) - pendingReq.setSSOSessionIdentifier(ssoId); - + return isSSOValid; @@ -130,7 +128,7 @@ public class SSOManager implements ISSOManager { } - + @Override public void isSSOAllowedForSP(IRequest pendingReq, HttpServletRequest httpReq) { // check if Service-Provider allows SSO sessions IOAAuthParameters oaConfig = pendingReq.getServiceProviderConfiguration(OAAuthParameterDecorator.class); @@ -155,11 +153,11 @@ public class SSOManager implements ISSOManager { } + @Override public void populatePendingRequestWithSSOInformation(IRequest pendingReq) throws EAAFSSOException { //populate pending request with eID data from SSO session if no userConsent is required - try { - String ssoSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(pendingReq.getSSOSessionIdentifier()); - AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(ssoSessionId); + try { + AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(pendingReq.getInternalSSOSessionIdentifier()); if (ssoMOASession == null) Logger.info("No MOASession FOUND with provided SSO-Cookie."); @@ -176,8 +174,7 @@ public class SSOManager implements ISSOManager { } catch (EAAFStorageException e) { Logger.warn("Can NOT populate pending request from SSO session.", e); - throw new EAAFSSOException("", new Object[] {}, - "Can NOT populate pending request from SSO session", e); + throw new EAAFSSOException("", new Object[] {}, e); } @@ -187,20 +184,23 @@ public class SSOManager implements ISSOManager { @Override public boolean destroySSOSessionOnIDPOnly(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) throws EAAFSSOException { //get SSO token from request - String ssoid = null; - if (pendingReq != null && MiscUtil.isNotEmpty(pendingReq.getSSOSessionIdentifier())) { - ssoid = pendingReq.getSSOSessionIdentifier(); - - } else { - ssoid = getSSOSessionID(httpReq); - - } + String internalSSOSessionId = null; try { - if (isValidSSOSession(ssoid, null)) { + if (pendingReq != null && MiscUtil.isNotEmpty(pendingReq.getInternalSSOSessionIdentifier())) { + internalSSOSessionId = pendingReq.getInternalSSOSessionIdentifier(); + + } else { + String ssoid = getSSOSessionID(httpReq); + if (isValidSSOSession(ssoid, null)) { + internalSSOSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoid); + + } + } - //delete SSO session and MOA session - String ssoSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoid); - AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(ssoSessionId); + //destroy SSO session if it was found + if (StringUtils.isNotEmpty(internalSSOSessionId)) { + //delete SSO session and MOA session + AuthenticationSession ssoMOASession = authenticatedSessionStore.getInternalSSOSession(internalSSOSessionId); if (ssoMOASession == null) { Logger.info("No internal MOA SSO-Session found. Nothing to destroy"); @@ -219,7 +219,7 @@ public class SSOManager implements ISSOManager { } } catch (ConfigurationException | SessionDataStorageException | EAAFStorageException e) { - Logger.info("NO MOA Authentication data for ID " + ssoid); + Logger.info("NO MOA Authentication data for ID " + internalSSOSessionId); return false; } @@ -232,6 +232,56 @@ public class SSOManager implements ISSOManager { } + @Override + public String createNewSSOSessionCookie(HttpServletRequest httpReq, HttpServletResponse httpResp, IRequest pendingReq) + throws EAAFSSOException { + Logger.debug("Creating new SSO session-cookie for http response ... "); + + //Store SSO information into database + String newSSOSessionId = Random.nextHexRandom32(); + + //set SSO cookie to response + if (StringUtils.isNotEmpty(newSSOSessionId)) + setSSOSessionID(httpReq, httpResp, newSSOSessionId); + else + deleteSSOSessionID(httpReq, httpResp); + + return newSSOSessionId; + } + + +@Override +public void createNewSSOSession(IRequest pendingReq, String newSSOSessionId) throws EAAFSSOException { + AuthenticationSession internalDBSSOSession; + try { + internalDBSSOSession = authenticatedSessionStore.createInternalSSOSession(pendingReq); + pendingReq.setInternalSSOSessionIdentifier(internalDBSSOSession.getSSOSessionID()); + + } catch (MOADatabaseException | BuildException e) { + Logger.warn("Can NOT create SSO session.", e); + throw new EAAFSSOException("builder.10", null, e); + + } + +} + + +@Override +public void updateSSOSession(IRequest pendingReq, String newSSOSessionId, SLOInformationInterface sloInformation) throws EAAFSSOException { + try { + authenticatedSessionStore.addSSOInformation( + pendingReq.getInternalSSOSessionIdentifier(), + newSSOSessionId, + sloInformation, + pendingReq); + + } catch (AuthenticationException e) { + Logger.warn("Can NOT update SSO session.", e); + throw new EAAFSSOException("builder.10", null, e); + } + +} + //*********************************** old ************************************** @@ -287,26 +337,6 @@ public class SSOManager implements ISSOManager { } - protected String createNewSSOSessionCookie(HttpServletRequest req, HttpServletResponse resp, - IRequest pendingReq, IAuthenticationSession moaSession) { - Logger.debug("Add SSO information to MOASession."); - - //Store SSO information into database - String newSSOSessionId = createSSOSessionInformations(moaSession.getSSOSessionID(), - pendingReq.getSPEntityId()); - - //set SSO cookie to response - if (StringUtils.isNotEmpty(newSSOSessionId)) { - setSSOSessionID(req, resp, newSSOSessionId); - - } else { - deleteSSOSessionID(req, resp); - - } - - return newSSOSessionId; - } - public boolean isValidSSOSession(String ssoSessionID, IRequest protocolRequest) throws ConfigurationException, SessionDataStorageException, EAAFStorageException { // search SSO Session @@ -363,7 +393,11 @@ public class SSOManager implements ISSOManager { return false; } - + + //set internal SSO SessionID + if (protocolRequest != null) + protocolRequest.setInternalSSOSessionIdentifier(storedSession.getSessionid()); + return true; } @@ -381,7 +415,10 @@ public class SSOManager implements ISSOManager { String ssoSessionId = authenticatedSessionStore.getInternalSSOSessionWithSSOID(ssoSessionID); if (MiscUtil.isNotEmpty(ssoSessionId)) { AuthenticationSessionExtensions extSessionInformation = authenticatedSessionStore.getAuthenticationSessionExtensions(ssoSessionId); + if (extSessionInformation != null) return extSessionInformation.getUniqueSessionId(); + else + Logger.warn("Extended SSO-Session Information ARE NULL. Something looks wrong!"); } } @@ -392,55 +429,13 @@ public class SSOManager implements ISSOManager { return null; } - - public String existsOldSSOSession(String ssoId) { - - Logger.trace("Check that the SSOID has already been used"); - - OldSSOSessionIDStore oldSSOSession = authenticatedSessionStore.checkSSOTokenAlreadyUsed(ssoId); - - if (oldSSOSession == null) { - Logger.debug("SSO session-cookie was not used in parst"); - return null; - } - - AuthenticatedSessionStore correspondingMoaSession = oldSSOSession.getMoasession(); - - if (correspondingMoaSession == null) { - Logger.info("Get request with old SSO SessionID but no corresponding SSO Session is found."); - return null; - } - - return correspondingMoaSession.getSessionid(); - - } - - public String createSSOSessionInformations(String moaSessionID, String OAUrl) { - - String newSSOId = Random.nextRandom(); - - if (MiscUtil.isEmpty(moaSessionID) || MiscUtil.isEmpty(OAUrl)) { - Logger.warn("MoaSessionID or OAUrl are empty -> SSO is not enabled!"); - return null; - } - - return newSSOId; - - } - - public void setSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp, String ssoId) { - setCookie(httpReq, httpResp, SSOCOOKIE, ssoId, -1); - - } - + public String getSSOSessionID(HttpServletRequest httpReq) { return getValueFromCookie(httpReq, SSOCOOKIE); } - public void deleteSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp) { - deleteCookie(httpReq, httpResp, SSOCOOKIE); - } + /** * @param entityID @@ -477,7 +472,41 @@ public class SSOManager implements ISSOManager { return false; } - + + + private String existsOldSSOSession(String ssoId) { + + Logger.trace("Check that the SSOID has already been used"); + + OldSSOSessionIDStore oldSSOSession = authenticatedSessionStore.checkSSOTokenAlreadyUsed(ssoId); + + if (oldSSOSession == null) { + Logger.debug("SSO session-cookie was not used in parst"); + return null; + } + + AuthenticatedSessionStore correspondingMoaSession = oldSSOSession.getMoasession(); + + if (correspondingMoaSession == null) { + Logger.info("Get request with old SSO SessionID but no corresponding SSO Session is found."); + return null; + } + + return correspondingMoaSession.getSessionid(); + + } + + + private void setSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp, String ssoId) { + setCookie(httpReq, httpResp, SSOCOOKIE, ssoId, -1); + + } + + private void deleteSSOSessionID(HttpServletRequest httpReq, HttpServletResponse httpResp) { + deleteCookie(httpReq, httpResp, SSOCOOKIE); + + } + private String getValueFromCookie(HttpServletRequest httpReq, String cookieName) { Cookie[] cookies = httpReq.getCookies(); @@ -505,30 +534,7 @@ public class SSOManager implements ISSOManager { private void deleteCookie(HttpServletRequest httpReq, HttpServletResponse httpResp, String cookieName) { setCookie(httpReq, httpResp, cookieName, "", 0); - } - - - - @Override - public void createNewSSOSession(IRequest arg0, String arg1, SLOInformationInterface arg2) throws EAAFSSOException { - // TODO Auto-generated method stub } - - - - @Override - public String createNewSSOSessionCookie(HttpServletRequest arg0, HttpServletResponse arg1, IRequest arg2) - throws EAAFSSOException { - // TODO Auto-generated method stub - return null; - } - - - @Override - public void updateSSOSession(IRequest arg0, String arg1, SLOInformationInterface arg2) throws EAAFSSOException { - // TODO Auto-generated method stub - - } - + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java index 9e7f18842..e98e1cb78 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -131,10 +131,10 @@ public class AttributQueryAction implements IAction { try { //get Single Sign-On information for the Service-Provider // which sends the Attribute-Query request - AuthenticationSession moaSession = authenticationSessionStorage.getInternalSSOSession(pendingReq.getSSOSessionIdentifier()); + AuthenticationSession moaSession = authenticationSessionStorage.getInternalSSOSession(pendingReq.getInternalSSOSessionIdentifier()); if (moaSession == null) { - Logger.warn("No MOASession with ID:" + pendingReq.getSSOSessionIdentifier() + " FOUND."); - throw new MOAIDException("auth.02", new Object[]{pendingReq.getSSOSessionIdentifier()}); + Logger.warn("No MOASession with ID:" + pendingReq.getInternalSSOSessionIdentifier() + " FOUND."); + throw new MOAIDException("auth.02", new Object[]{pendingReq.getInternalSSOSessionIdentifier()}); } InterfederationSessionStore nextIDPInformation = @@ -178,9 +178,9 @@ public class AttributQueryAction implements IAction { throw new MOAIDException("pvp2.01", null, e); } catch (MOADatabaseException e) { - Logger.error("MOASession with SessionID=" + pendingReq.getSSOSessionIdentifier() + Logger.error("MOASession with SessionID=" + pendingReq.getInternalSSOSessionIdentifier() + " is not found in Database", e); - throw new MOAIDException("init.04", new Object[] { pendingReq.getSSOSessionIdentifier() }); + throw new MOAIDException("init.04", new Object[] { pendingReq.getInternalSSOSessionIdentifier() }); } 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 a59033177..5c71852f2 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 @@ -107,7 +107,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { public void PVPMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { if (!moaAuthConfig.getAllowedProtocols().isPVP21Active()) { Logger.info("PVP2.1 is deaktivated!"); - throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); + throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }); } @@ -120,7 +120,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { public void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { if (!moaAuthConfig.getAllowedProtocols().isPVP21Active()) { Logger.info("PVP2.1 is deaktivated!"); - throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); + throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }); } @@ -133,7 +133,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { public void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { if (!AuthConfigurationProviderFactory.getInstance().getAllowedProtocols().isPVP21Active()) { Logger.info("PVP2.1 is deaktivated!"); - throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); + throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }); } @@ -183,7 +183,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { if (pendingReq != null) revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}, e.getMessage()); + throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}); } catch (SecurityException e) { String samlRequest = req.getParameter("SAMLRequest"); @@ -193,7 +193,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { if (pendingReq != null) revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); - throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}, e.getMessage()); + throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}); } catch (MOAIDException e) { //write revision log entries @@ -385,7 +385,7 @@ public class PVP2XProtocol extends AbstractPVP2XProtocol { pendingReq.setAction(AttributQueryAction.class.getName()); //add moasession - pendingReq.setSSOSessionIdentifier(session.getSSOSessionID()); + pendingReq.setInternalSSOSessionIdentifier(session.getSSOSessionID()); //write revisionslog entry revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROTOCOL_PVP_REQUEST_ATTRIBUTQUERY); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java index ab88a765e..68158cd61 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java @@ -135,7 +135,7 @@ public class SingleLogOutAction implements IAction { } } - pvpReq.setSSOSessionIdentifier(ssoSessionId); + pvpReq.setInternalSSOSessionIdentifier(ssoSessionId); ISLOInformationContainer sloInformationContainer = authManager.performSingleLogOut(httpReq, httpResp, pvpReq, ssoSessionId); @@ -165,25 +165,7 @@ public class SingleLogOutAction implements IAction { //TODO: add counter to prevent deadlock synchronized(this){ while (!storageSuccess) { - // tx = session.beginTransaction(); - // - // List result; - // Query query = session.getNamedQuery("getAssertionWithArtifact"); - // query.setParameter("artifact", relayState); - // result = query.list(); - // - // - // Logger.trace("Found entries: " + result.size()); - // - // //Assertion requires an unique artifact - // if (result.size() != 1) { - // Logger.trace("No entries found."); - // throw new MOADatabaseException("No sessioninformation found with this ID"); - // } - // - // AssertionStore element = (AssertionStore) result.get(0); - // Object data = SerializationUtils.deserialize(element.getAssertion()); - Logger.debug("Current Thread getAssertionStore: "+Thread.currentThread().getId()); + Logger.debug("Current Thread: " +Thread.currentThread().getId() + " requests TransactionStore"); Object o = transactionStorage.getRaw(relayState); if(o==null){ Logger.trace("No entries found."); @@ -204,35 +186,35 @@ public class SingleLogOutAction implements IAction { byte[] serializedSLOContainer = SerializationUtils.serialize((Serializable) sloContainer); element.setAssertion(serializedSLOContainer); element.setType(sloContainer.getClass().getName()); - - // session.saveOrUpdate(element); - // tx.commit(); - Logger.debug("Current Thread putAssertionStore: "+Thread.currentThread().getId()); + Logger.debug("Current Thread: " + Thread.currentThread().getId() + " puts SLOInformation into TransactionStore"); transactionStorage.putRaw(element.getArtifact(), element); //sloContainer could be stored to database storageSuccess = true; } catch(EAAFException e) { - //tx.rollback(); - counter++; Logger.debug("SLOContainter could not stored to database. Wait some time and restart storage process ... "); - java.util.Random rand = new java.util.Random(); - + if (counter > 1000) { + Logger.warn("Stopping SLO process with an error, because it runs in a loop.", e); + throw new EAAFException("internal.01", null, e); + + } + + try { + java.util.Random rand = new java.util.Random(); Thread.sleep(rand.nextInt(20)*10); } catch (InterruptedException e1) { Logger.warn("Thread could not stopped. ReStart storage process immediately", e1); + } } } else { - Logger.debug("Current Thread removeElement by Artifact: "+Thread.currentThread().getId()); + Logger.debug("Current Thread: " + Thread.currentThread().getId() + " remove SLOInformation from TransactionStore"); transactionStorage.remove(element.getArtifact()); - // session.delete(element); - // tx.commit(); storageSuccess = true; String redirectURL = null; @@ -292,16 +274,7 @@ public class SingleLogOutAction implements IAction { throw new AuthenticationException("pvp2.13", new Object[]{}); } - - // finally { - // if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) { - // tx.commit(); - // - // } - // } - - - + } else { Logger.error("Process SingleLogOutAction but request is NOT of type LogoutRequest or LogoutResponse."); throw new MOAIDException("pvp2.13", null); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java index 53606b341..8229fb405 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.builder; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collection; +import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -35,6 +36,7 @@ import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import org.apache.commons.lang.SerializationUtils; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.common.SAMLObject; @@ -97,6 +99,7 @@ import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.frontend.builder.DefaultGUIFormBuilderConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; 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; @@ -201,7 +204,12 @@ public class SingleLogOutBuilder { } //put SLO process-information into transaction storage - transactionStorage.put(relayState, sloContainer, -1); + AssertionStore rawContainer = new AssertionStore(); + rawContainer.setArtifact(relayState); + rawContainer.setDatatime(new Date()); + rawContainer.setAssertion(SerializationUtils.serialize(sloContainer)); + rawContainer.setType(sloContainer.getClass().getName()); + transactionStorage.putRaw(relayState, rawContainer); if (MiscUtil.isEmpty(authUrl)) authUrl = sloContainer.getSloRequest().getAuthURL(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java index e8aa93d43..1286c2351 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/EntityVerifier.java @@ -38,7 +38,7 @@ import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.SAMLRequestNotSignedException; +import at.gv.egiz.eaaf.modules.pvp2.exception.SAMLMetadataSignatureException; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; @@ -65,7 +65,7 @@ public class EntityVerifier { public static void verify(EntityDescriptor entityDescriptor, Credential cred) throws EAAFException { if (entityDescriptor.getSignature() == null) { - throw new SAMLRequestNotSignedException(); + throw new SAMLMetadataSignatureException(); } try { @@ -73,7 +73,7 @@ public class EntityVerifier { sigValidator.validate(entityDescriptor.getSignature()); } catch (ValidationException e) { Logger.error("Failed to validate Signature", e); - throw new SAMLRequestNotSignedException(e); + throw new SAMLMetadataSignatureException(e); } SignatureValidator sigValidator = new SignatureValidator(cred); @@ -81,14 +81,14 @@ public class EntityVerifier { sigValidator.validate(entityDescriptor.getSignature()); } catch (ValidationException e) { Logger.error("Failed to verfiy Signature", e); - throw new SAMLRequestNotSignedException(e); + throw new SAMLMetadataSignatureException(e); } } public static void verify(EntitiesDescriptor entityDescriptor, Credential cred) throws EAAFException { if (entityDescriptor.getSignature() == null) { - throw new SAMLRequestNotSignedException(); + throw new SAMLMetadataSignatureException(); } try { @@ -96,7 +96,7 @@ public class EntityVerifier { sigValidator.validate(entityDescriptor.getSignature()); } catch (ValidationException e) { Logger.error("Failed to validate Signature", e); - throw new SAMLRequestNotSignedException(e); + throw new SAMLMetadataSignatureException(e); } SignatureValidator sigValidator = new SignatureValidator(cred); @@ -105,7 +105,7 @@ public class EntityVerifier { } catch (ValidationException e) { Logger.error("Failed to verfiy Signature", e); - throw new SAMLRequestNotSignedException(e); + throw new SAMLMetadataSignatureException(e); } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java index f303adfe5..0f75cf63b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java @@ -78,26 +78,11 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt private static JsonMapper mapper = new JsonMapper(); @Override - public boolean isAuthenticated(String internalSsoSessionID) { - - AuthenticatedSessionStore session; - - try { - session = searchInDatabase(internalSsoSessionID); - return session.isAuthenticated(); - - } catch (MOADatabaseException e) { - return false; - } - } - - @Override public AuthenticationSession createInternalSSOSession(IRequest target) throws MOADatabaseException, BuildException { String id = Random.nextLongRandom(); try { AuthenticatedSessionStore dbsession = new AuthenticatedSessionStore(); dbsession.setSessionid(id); - dbsession.setAuthenticated(false); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 Date now = new Date(); @@ -107,7 +92,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt //set additional session informations AuthenticationSessionExtensions sessionExt = new AuthenticationSessionExtensions(); sessionExt.setUniqueSessionId(target.getUniqueSessionIdentifier()); - dbsession.setAdditionalInformation(mapper.serialize(sessionExt).getBytes("UTF-8")); + dbsession.setAdditionalInformationBytes(mapper.serialize(sessionExt).getBytes("UTF-8")); AuthenticationSession session = new AuthenticationSession(id, now, new AuthenticationSessionWrapper(target.genericFullDataStorage())); @@ -155,9 +140,9 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt public AuthenticationSessionExtensions getAuthenticationSessionExtensions(String sessionID) throws MOADatabaseException { AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); - if (MiscUtil.isNotEmpty(dbsession.getAdditionalInformation())) { + if (dbsession.getAdditionalInformationBytes() != null) { try { - return (AuthenticationSessionExtensions)mapper.deserialize(new String(dbsession.getAdditionalInformation(), "UTF-8"), + return (AuthenticationSessionExtensions)mapper.deserialize(new String(dbsession.getAdditionalInformationBytes(), "UTF-8"), AuthenticationSessionExtensions.class); } catch (Exception e) { @@ -173,7 +158,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt try { AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); - dbsession.setAdditionalInformation( + dbsession.setAdditionalInformationBytes( mapper.serialize(sessionExtensions).getBytes("UTF-8")); entityManager.merge(dbsession); @@ -292,11 +277,11 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } @Override - public void addSSOInformation(String moaSessionID, String SSOSessionID, + public void addSSOInformation(String internalSSOSessionID, String externalSSOSessionID, SLOInformationInterface SLOInfo, IRequest protocolRequest) throws AuthenticationException { Query query = entityManager.createNamedQuery("getSessionWithID"); - query.setParameter("sessionid", moaSessionID); + query.setParameter("sessionid", internalSSOSessionID); List<AuthenticatedSessionStore> results = query.getResultList(); Logger.trace("Found entries: " + results.size()); @@ -355,8 +340,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } dbsession.setSSOSession(true); - dbsession.setSSOsessionid(SSOSessionID); - dbsession.setAuthenticated(false); + dbsession.setSSOsessionid(externalSSOSessionID); //Store MOASession entityManager.merge(dbsession); @@ -551,23 +535,23 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public void addFederatedSessionInformation(IRequest req, String idpEntityID, AssertionAttributeExtractor extractor) throws MOADatabaseException, AssertionAttributeExtractorExeption, BuildException, EAAFConfigurationException { AuthenticatedSessionStore dbsession = null; - String ssoSessionId = null; + String internalSSOSessionId = null; Date now = new Date(); //search for active session - if (MiscUtil.isNotEmpty(req.getSSOSessionIdentifier())) { - Logger.debug("Internal SSO-Session object: " + req.getSSOSessionIdentifier() + " used for federated SSO"); - ssoSessionId = getInternalSSOSessionWithSSOID(req.getSSOSessionIdentifier()); + if (MiscUtil.isNotEmpty(req.getInternalSSOSessionIdentifier())) { + Logger.debug("Internal SSO-Session object: " + req.getInternalSSOSessionIdentifier() + " used for federated SSO"); + internalSSOSessionId = req.getInternalSSOSessionIdentifier(); } else { Logger.debug("No internal SSO-Session object exists for federated SSO --> create new session object"); - ssoSessionId = createInternalSSOSession(req).getSSOSessionID(); + internalSSOSessionId = createInternalSSOSession(req).getSSOSessionID(); } - if (MiscUtil.isNotEmpty(ssoSessionId)) { + if (MiscUtil.isNotEmpty(internalSSOSessionId)) { try { - dbsession = searchInDatabase(ssoSessionId); + dbsession = searchInDatabase(internalSSOSessionId); }catch (MOADatabaseException e) { Logger.error("NO MOASession found but MOASession MUST already exist!"); @@ -797,7 +781,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt Query query = entityManager.createNamedQuery("getSSOSessionWithOldSessionID"); query.setParameter("sessionid", ssoId); List<OldSSOSessionIDStore> results = query.getResultList(); - + Logger.trace("Found entries: " + results.size()); // Assertion requires an unique artifact diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java index 27d9d394d..61c83aaf2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java @@ -249,8 +249,14 @@ public class DBTransactionStorage implements ITransactionStorage { @Override public void putRaw(String key, Object element) throws MOADatabaseException { - entityManager.merge(element); + if (element instanceof AssertionStore) + entityManager.merge(element); + else { + Logger.error("Can not persist Object of type: " + element.getClass().getName()); + throw new RuntimeException("Can not persist Object of type: " + element.getClass().getName()); + + } } private void cleanDelete(AssertionStore element) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java index 5f2ec046a..add697a85 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/IAuthenticationSessionStoreage.java @@ -46,14 +46,6 @@ import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; * */ public interface IAuthenticationSessionStoreage { - - /** - * Check if the stored MOASession is already authenticated - * - * @param internalSsoSessionID Internal MOA SSO-Session identifier - * @return true if the MOASession is authenticated, otherwise false - */ - public boolean isAuthenticated(String internalSsoSessionID); /** * Create a new MOA SSO-Session object in database diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java index 397e28bc2..a44d8c1b6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java @@ -522,6 +522,7 @@ public class ParamValidatorUtils extends MOAIDAuthConstants{ String bkuURL = req.getParameter(PARAM_BKU);
String useMandate = req.getParameter(PARAM_USEMANDATE);
String ccc = req.getParameter(PARAM_CCC);
+ String useeIDAS = req.getParameter("useeIDAS");
// check parameter
@@ -532,6 +533,8 @@ public class ParamValidatorUtils extends MOAIDAuthConstants{ throw new WrongParametersException("StartAuthentication", PARAM_BKU, "auth.12");
if (!ParamValidatorUtils.isValidUseMandate(useMandate))
throw new WrongParametersException("StartAuthentication", PARAM_USEMANDATE, "auth.12");
+ if (!ParamValidatorUtils.isValidUseMandate(useeIDAS))
+ throw new WrongParametersException("StartAuthentication", "useeIDAS", "auth.12");
if (!ParamValidatorUtils.isValidCCC(ccc))
throw new WrongParametersException("StartAuthentication", PARAM_CCC, "auth.12");
@@ -539,7 +542,7 @@ public class ParamValidatorUtils extends MOAIDAuthConstants{ return false;
}
- if (StringUtils.isEmpty(bkuURL))
+ if (StringUtils.isEmpty(bkuURL) && StringUtils.isEmpty(useeIDAS))
return false;
else
return true;
|