diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2014-01-27 16:27:02 +0100 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2014-01-27 16:27:02 +0100 |
commit | cea2f395ec773b386ec628d60120752cf320f6b6 (patch) | |
tree | 2145dbbe25f0b4f99c89e60834176ea8fa1d435c /id/oa/src/main | |
parent | 653fd79254188db598c0b980640fab912c9e39f7 (diff) | |
download | moa-id-spss-cea2f395ec773b386ec628d60120752cf320f6b6.tar.gz moa-id-spss-cea2f395ec773b386ec628d60120752cf320f6b6.tar.bz2 moa-id-spss-cea2f395ec773b386ec628d60120752cf320f6b6.zip |
add PVP2 Demo Application
change SZRGWClient to JAXWs
Diffstat (limited to 'id/oa/src/main')
23 files changed, 1974 insertions, 183 deletions
diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java new file mode 100644 index 000000000..0ca5464a7 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java @@ -0,0 +1,243 @@ +package at.gv.egovernment.moa.id.demoOA; + + +import iaik.x509.X509Certificate; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Properties; +import java.util.Timer; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.httpclient.HttpClient; +import org.opensaml.DefaultBootstrap; +import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.x509.BasicX509Credential; + +import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; +import at.gv.egovernment.moa.id.demoOA.utils.MetaDataVerificationFilter; +import at.iaik.commons.util.MiscUtil; + + +public class Configuration { + + private Properties props; + private static final String SYSTEM_PROP_CONFIG = "moa.id.demoOA"; + + private HTTPMetadataProvider idpMetadataProvider = null; + private boolean pvp2logininitialzied = false; + + private String publicURLPreFix = null; + private KeyStore keyStore = null; + + private static Configuration instance = null; + + public static Configuration getInstance() throws ConfigurationException { + if (instance == null) { + instance = new Configuration(); + + } + + return instance; + } + + public String getPublicUrlPreFix(HttpServletRequest request) { + publicURLPreFix = props.getProperty("general.publicURLContext"); + + if (MiscUtil.isEmpty(publicURLPreFix) && request != null) { + String url = request.getRequestURL().toString(); + String contextpath = request.getContextPath(); + int index = url.indexOf(contextpath); + publicURLPreFix = url.substring(0, index + contextpath.length() + 1); + } + + return publicURLPreFix; + } + + public KeyStore getPVP2KeyStore() throws ConfigurationException { + + try { + if (keyStore == null) { + String keystoretype = getPVP2MetadataKeystoreType(); + if (MiscUtil.isEmpty(keystoretype)) { + keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + + } else { + keyStore = KeyStore.getInstance(keystoretype); + + } + + + String file = getPVP2MetadataKeystoreURL(); + if (MiscUtil.isEmpty(file)) { + throw new ConfigurationException("KeyStoreURL is empty"); + } + + FileInputStream inputStream = new FileInputStream(file); + keyStore.load(inputStream, getPVP2MetadataKeystorePassword().toCharArray()); + inputStream.close(); + } + + return keyStore; + + } catch (Exception e){ + throw new ConfigurationException("KeyStore intialization FAILED", e); + + } + + } + + public String getPVP2LoginEntityName() { + return props.getProperty("general.login.pvp2.OA.metadata.entity.name"); + } + + public String getPVP2MetadataEntitiesName() { + return props.getProperty("general.login.pvp2.OA.metadata.entities.name"); + } + + public String getPVP2MetadataKeystoreURL() { + return props.getProperty("general.login.pvp2.OA.keystore.url"); + } + + public String getPVP2MetadataKeystorePassword() { + return props.getProperty("general.login.pvp2.OA.keystore.password"); + } + + public String getPVP2MetadataKeystoreType() { + return props.getProperty("general.login.pvp2.OA.keystore.type"); + } + + public String getPVP2KeystoreMetadataKeyAlias() { + return props.getProperty("general.login.pvp2.OA.keystore.metadata.sign.key.alias"); + } + + public String getPVP2KeystoreMetadataKeyPassword() { + return props.getProperty("general.login.pvp2.OA.keystore.metadata.sign.key.password"); + } + + public String getPVP2KeystoreAuthRequestKeyAlias() { + return props.getProperty("general.login.pvp2.keystore.authrequest.sign.key.alias"); + } + + public String getPVP2KeystoreAuthRequestKeyPassword() { + return props.getProperty("general.login.pvp2.keystore.authrequest.sign.key.password"); + } + + public String getPVP2KeystoreAuthRequestEncryptionKeyAlias() { + return props.getProperty("general.login.pvp2.keystore.assertion.encryption.key.alias"); + } + + public String getPVP2KeystoreAuthRequestEncryptionKeyPassword() { + return props.getProperty("general.login.pvp2.keystore.assertion.encryption.key.password"); + } + + public String getPVP2IDPMetadataURL() { + return props.getProperty("general.login.pvp2.idp.metadata.url"); + } + + public String getPVP2IDPMetadataCertificate() { + return props.getProperty("general.login.pvp2.idp.metadata.certificate"); + } + + public String getPVP2IDPMetadataEntityName() { + return props.getProperty("general.login.pvp2.idp.metadata.entityID"); + } + + + public void initializePVP2Login() throws ConfigurationException { + if (!pvp2logininitialzied) + initalPVP2Login(); + + } + + public HTTPMetadataProvider getMetaDataProvier() throws ConfigurationException { + + if (!pvp2logininitialzied) + initalPVP2Login(); + + return idpMetadataProvider; + } + + + private Configuration() throws ConfigurationException { + inizialize(); + } + + private void inizialize() throws ConfigurationException { + + String configFileName = System.getProperty(SYSTEM_PROP_CONFIG); + + if (configFileName == null) { + throw new ConfigurationException("No DemoOA configuration found."); + } + + File propertiesFile = new File(configFileName); + FileInputStream fis; + props = new Properties(); + + try { + + fis = new FileInputStream(propertiesFile); + props.load(fis); + + fis.close(); + + DefaultBootstrap.bootstrap(); + + } catch ( FileNotFoundException e) { + throw new ConfigurationException("DemoOA configuration is not found at " + configFileName); + + + } catch (IOException e) { + throw new ConfigurationException("DemoOA configuration can not be read from file " + configFileName); + + } catch (org.opensaml.xml.ConfigurationException e) { + throw new ConfigurationException("OpenSAML library initialization FAILED"); + + } + } + + private void initalPVP2Login() throws ConfigurationException { + try { + + String metadataCert = getPVP2IDPMetadataCertificate(); + if (MiscUtil.isEmpty(metadataCert)) { + throw new ConfigurationException("NO IDP Certificate to verify IDP Metadata"); + } + + InputStream certstream = new FileInputStream(metadataCert); + X509Certificate cert = new X509Certificate(certstream); + BasicX509Credential idpCredential = new BasicX509Credential(); + idpCredential.setEntityCertificate(cert); + + + String metadataurl = getPVP2IDPMetadataURL(); + if (MiscUtil.isEmpty(metadataurl)) { + throw new ConfigurationException("NO IDP Metadata URL."); + } + + idpMetadataProvider = new HTTPMetadataProvider(new Timer(), new HttpClient(), metadataurl); + idpMetadataProvider.setRequireValidMetadata(true); + idpMetadataProvider.setParserPool(new BasicParserPool()); + idpMetadataProvider.setMetadataFilter(new MetaDataVerificationFilter(idpCredential)); + idpMetadataProvider.setMaxRefreshDelay(1000 * 3600 * 12 ); //refresh Metadata every 12h + idpMetadataProvider.initialize(); + + pvp2logininitialzied = true; + + } catch (Exception e) { + throw new ConfigurationException("PVP2 authentification can not be initialized.", e); + } + } + + +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Constants.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Constants.java new file mode 100644 index 000000000..1f5d4871b --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Constants.java @@ -0,0 +1,9 @@ +package at.gv.egovernment.moa.id.demoOA; + +public class Constants { + public static final String FILEPREFIX = "file:"; + + public static final String SERVLET_PVP2ASSERTION = "demoapplication"; + + public static final String SESSION_PVP2REQUESTID = "pvp2requestid"; +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/PVPConstants.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/PVPConstants.java new file mode 100644 index 000000000..facc2feb2 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/PVPConstants.java @@ -0,0 +1,230 @@ +package at.gv.egovernment.moa.id.demoOA; + +public interface PVPConstants { + public static final String URN_OID_PREFIX = "urn:oid:"; + + public static final String PVP_VERSION_OID = "1.2.40.0.10.2.1.1.261.10"; + public static final String PVP_VERSION_NAME = URN_OID_PREFIX + PVP_VERSION_OID; + public static final String PVP_VERSION_FRIENDLY_NAME = "PVP-VERSION"; + public static final String PVP_VERSION_2_1 = "2.1"; + + public static final String SECCLASS_FRIENDLY_NAME = "SECCLASS"; + + public static final String PRINCIPAL_NAME_OID = "1.2.40.0.10.2.1.1.261.20"; + public static final String PRINCIPAL_NAME_NAME = URN_OID_PREFIX + PRINCIPAL_NAME_OID; + public static final String PRINCIPAL_NAME_FRIENDLY_NAME = "PRINCIPAL-NAME"; + public static final int PRINCIPAL_NAME_MAX_LENGTH = 128; + + public static final String GIVEN_NAME_OID = "2.5.4.42"; + public static final String GIVEN_NAME_NAME = URN_OID_PREFIX + GIVEN_NAME_OID; + public static final String GIVEN_NAME_FRIENDLY_NAME = "GIVEN-NAME"; + public static final int GIVEN_NAME_MAX_LENGTH = 128; + + public static final String BIRTHDATE_OID = "1.2.40.0.10.2.1.1.55"; + public static final String BIRTHDATE_NAME = URN_OID_PREFIX + BIRTHDATE_OID; + public static final String BIRTHDATE_FRIENDLY_NAME = "BIRTHDATE"; + public static final String BIRTHDATE_FORMAT_PATTERN = "yyyy-MM-dd"; + + public static final String USERID_OID = "0.9.2342.19200300.100.1.1"; + public static final String USERID_NAME = URN_OID_PREFIX + USERID_OID; + public static final String USERID_FRIENDLY_NAME = "USERID"; + public static final int USERID_MAX_LENGTH = 128; + + public static final String GID_OID = "1.2.40.0.10.2.1.1.1"; + public static final String GID_NAME = URN_OID_PREFIX + GID_OID; + public static final String GID_FRIENDLY_NAME = "GID"; + public static final int GID_MAX_LENGTH = 128; + + public static final String BPK_OID = "1.2.40.0.10.2.1.1.149"; + public static final String BPK_NAME = URN_OID_PREFIX + BPK_OID; + public static final String BPK_FRIENDLY_NAME = "BPK"; + public static final int BPK_MAX_LENGTH = 1024; + + public static final String ENC_BPK_LIST_OID = "1.2.40.0.10.2.1.1.261.22"; + public static final String ENC_BPK_LIST_NAME = URN_OID_PREFIX+ENC_BPK_LIST_OID; + public static final String ENC_BPK_LIST_FRIENDLY_NAME = "ENC-BPK-LIST"; + public static final int ENC_BPK_LIST_MAX_LENGTH = 32767; + + public static final String MAIL_OID = "0.9.2342.19200300.100.1.3"; + public static final String MAIL_NAME = URN_OID_PREFIX + MAIL_OID; + public static final String MAIL_FRIENDLY_NAME = "MAIL"; + public static final int MAIL_MAX_LENGTH = 128; + + public static final String TEL_OID = "2.5.4.20"; + public static final String TEL_NAME = URN_OID_PREFIX + TEL_OID; + public static final String TEL_FRIENDLY_NAME = "TEL"; + public static final int TEL_MAX_LENGTH = 32; + + public static final String PARTICIPANT_ID_OID = "1.2.40.0.10.2.1.1.71"; + public static final String PARTICIPANT_ID_NAME = URN_OID_PREFIX + PARTICIPANT_ID_OID; + public static final String PARTICIPANT_ID_FRIENDLY_NAME = "PARTICIPANT-ID"; + public static final int PARTICIPANT_MAX_LENGTH = 39; + + public static final String PARTICIPANT_OKZ_OID = "1.2.40.0.10.2.1.1.261.24"; + public static final String PARTICIPANT_OKZ_NAME = URN_OID_PREFIX + PARTICIPANT_OKZ_OID; + public static final String PARTICIPANT_OKZ_FRIENDLY_NAME = "PARTICIPANT-OKZ"; + public static final int PARTICIPANT_OKZ_MAX_LENGTH = 32; + + public static final String OU_OKZ_OID = "1.2.40.0.10.2.1.1.153"; + public static final String OU_OKZ_NAME = URN_OID_PREFIX + OU_OKZ_OID; + public static final int OU_OKZ_MAX_LENGTH = 32; + + public static final String OU_GV_OU_ID_OID = "1.2.40.0.10.2.1.1.3"; + public static final String OU_GV_OU_ID_NAME = URN_OID_PREFIX + OU_GV_OU_ID_OID; + public static final String OU_GV_OU_ID_FRIENDLY_NAME = "OU-GV-OU-ID"; + public static final int OU_GV_OU_ID_MAX_LENGTH = 39; + + public static final String OU_OID = "2.5.4.11"; + public static final String OU_NAME = URN_OID_PREFIX + OU_OID; + public static final String OU_FRIENDLY_NAME = "OU"; + public static final int OU_MAX_LENGTH = 64; + + public static final String FUNCTION_OID = "1.2.40.0.10.2.1.1.33"; + public static final String FUNCTION_NAME = URN_OID_PREFIX + FUNCTION_OID; + public static final String FUNCTION_FRIENDLY_NAME = "FUNCTION"; + public static final int FUNCTION_MAX_LENGTH = 32; + + public static final String ROLES_OID = "1.2.40.0.10.2.1.1.261.30"; + public static final String ROLES_NAME = URN_OID_PREFIX + ROLES_OID; + public static final String ROLES_FRIENDLY_NAME = "ROLES"; + public static final int ROLES_MAX_LENGTH = 32767; + + public static final String EID_CITIZEN_QAA_LEVEL_OID = "1.2.40.0.10.2.1.1.261.94"; + public static final String EID_CITIZEN_QAA_LEVEL_NAME = URN_OID_PREFIX + EID_CITIZEN_QAA_LEVEL_OID; + public static final String EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME = "EID-CITIZEN-QAA-LEVEL"; + + public static final String EID_ISSUING_NATION_OID = "1.2.40.0.10.2.1.1.261.32"; + public static final String EID_ISSUING_NATION_NAME = URN_OID_PREFIX + EID_ISSUING_NATION_OID; + public static final String EID_ISSUING_NATION_FRIENDLY_NAME = "EID-ISSUING-NATION"; + public static final int EID_ISSUING_NATION_MAX_LENGTH = 2; + + public static final String EID_SECTOR_FOR_IDENTIFIER_OID = "1.2.40.0.10.2.1.1.261.34"; + public static final String EID_SECTOR_FOR_IDENTIFIER_NAME = URN_OID_PREFIX + EID_SECTOR_FOR_IDENTIFIER_OID; + public static final String EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME = "EID-SECTOR-FOR-IDENTIFIER"; + public static final int EID_SECTOR_FOR_IDENTIFIER_MAX_LENGTH = 255; + + public static final String EID_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.36"; + public static final String EID_SOURCE_PIN_NAME = URN_OID_PREFIX + EID_SOURCE_PIN_OID; + public static final String EID_SOURCE_PIN_FRIENDLY_NAME = "EID-SOURCE-PIN"; + public static final int EID_SOURCE_PIN_MAX_LENGTH = 128; + + public static final String EID_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.104"; + public static final String EID_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + EID_SOURCE_PIN_TYPE_OID; + public static final String EID_SOURCE_PIN_TYPE_FRIENDLY_NAME = "EID-SOURCE-PIN-TYPE"; + public static final int EID_SOURCE_PIN_TYPE_MAX_LENGTH = 128; + + public static final String EID_IDENTITY_LINK_OID = "1.2.40.0.10.2.1.1.261.38"; + public static final String EID_IDENTITY_LINK_NAME = URN_OID_PREFIX + EID_IDENTITY_LINK_OID; + public static final String EID_IDENTITY_LINK_FRIENDLY_NAME = "EID-IDENTITY-LINK"; + public static final int EID_IDENTITY_LINK_MAX_LENGTH = 32767; + + public static final String EID_AUTH_BLOCK_OID = "1.2.40.0.10.2.1.1.261.62"; + public static final String EID_AUTH_BLOCK_NAME = URN_OID_PREFIX + EID_AUTH_BLOCK_OID; + public static final String EID_AUTH_BLOCK_FRIENDLY_NAME = "EID-AUTH-BLOCK"; + public static final int EID_AUTH_BLOCK_MAX_LENGTH = 32767; + + public static final String EID_CCS_URL_OID = "1.2.40.0.10.2.1.1.261.64"; + public static final String EID_CCS_URL_NAME = URN_OID_PREFIX + EID_CCS_URL_OID; + public static final String EID_CCS_URL_FRIENDLY_NAME = "EID-CCS-URL"; + public static final int EID_CCS_URL_MAX_LENGTH = 1024; + + public static final String EID_SIGNER_CERTIFICATE_OID = "1.2.40.0.10.2.1.1.261.66"; + public static final String EID_SIGNER_CERTIFICATE_NAME = URN_OID_PREFIX + EID_SIGNER_CERTIFICATE_OID; + public static final String EID_SIGNER_CERTIFICATE_FRIENDLY_NAME = "EID-SIGNER-CERTIFICATE"; + public static final int EID_SIGNER_CERTIFICATE_MAX_LENGTH = 32767; + + public static final String EID_STORK_TOKEN_OID = "1.2.40.0.10.2.1.1.261.96"; + public static final String EID_STORK_TOKEN_NAME = URN_OID_PREFIX + EID_STORK_TOKEN_OID; + public static final String EID_STORK_TOKEN_FRIENDLY_NAME = "EID-STORK-TOKEN"; + public static final int EID_STORK_TOKEN_MAX_LENGTH = 32767; + + public static final String MANDATE_TYPE_OID = "1.2.40.0.10.2.1.1.261.68"; + public static final String MANDATE_TYPE_NAME = URN_OID_PREFIX + MANDATE_TYPE_OID; + public static final String MANDATE_TYPE_FRIENDLY_NAME = "MANDATE-TYPE"; + public static final int MANDATE_TYPE_MAX_LENGTH = 256; + + public static final String MANDATE_NAT_PER_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.70"; + public static final String MANDATE_NAT_PER_SOURCE_PIN_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_SOURCE_PIN_OID; + public static final String MANDATE_NAT_PER_SOURCE_PIN_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-SOURCE-PIN"; + public static final int MANDATE_NAT_PER_SOURCE_PIN_MAX_LENGTH = 128; + + public static final String MANDATE_LEG_PER_SOURCE_PIN_OID = "1.2.40.0.10.2.1.1.261.100"; + public static final String MANDATE_LEG_PER_SOURCE_PIN_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_SOURCE_PIN_OID; + public static final String MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-SOURCE-PIN"; + public static final int MANDATE_LEG_PER_SOURCE_PIN_MAX_LENGTH = 128; + + public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.102"; + public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_SOURCE_PIN_TYPE_OID; + public static final String MANDATE_NAT_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-SOURCE-PIN-TYPE"; + public static final int MANDATE_NAT_PER_SOURCE_PIN_TYPE_MAX_LENGTH = 128; + + public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_OID = "1.2.40.0.10.2.1.1.261.76"; + public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_SOURCE_PIN_TYPE_OID; + public static final String MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-SOURCE-PIN-TYPE"; + public static final int MANDATE_LEG_PER_SOURCE_PIN_TYPE_MAX_LENGTH = 128; + + public static final String MANDATE_NAT_PER_BPK_OID = "1.2.40.0.10.2.1.1.261.98"; + public static final String MANDATE_NAT_PER_BPK_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_BPK_OID; + public static final String MANDATE_NAT_PER_BPK_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-BPK"; + public static final int MANDATE_NAT_PER_BPK_MAX_LENGTH = 1024; + + public static final String MANDATE_NAT_PER_ENC_BPK_LIST_OID = "1.2.40.0.10.2.1.1.261.72"; + public static final String MANDATE_NAT_PER_ENC_BPK_LIST_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_ENC_BPK_LIST_OID; + public static final String MANDATE_NAT_PER_ENC_BPK_LIST_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-ENC-BPK-LIST"; + public static final int MANDATE_NAT_PER_ENC_BPK_LIST_MAX_LENGTH = 32767; + + public static final String MANDATE_NAT_PER_GIVEN_NAME_OID = "1.2.40.0.10.2.1.1.261.78"; + public static final String MANDATE_NAT_PER_GIVEN_NAME_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_GIVEN_NAME_OID; + public static final String MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-GIVEN-NAME"; + public static final int MANDATE_NAT_PER_GIVEN_NAME_MAX_LENGTH = 128; + + public static final String MANDATE_NAT_PER_FAMILY_NAME_OID = "1.2.40.0.10.2.1.1.261.80"; + public static final String MANDATE_NAT_PER_FAMILY_NAME_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_FAMILY_NAME_OID; + public static final String MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-FAMILY-NAME"; + public static final int MANDATE_NAT_PER_FAMILY_NAME_MAX_LENGTH = 128; + + public static final String MANDATE_NAT_PER_BIRTHDATE_OID = "1.2.40.0.10.2.1.1.261.82"; + public static final String MANDATE_NAT_PER_BIRTHDATE_NAME = URN_OID_PREFIX + MANDATE_NAT_PER_BIRTHDATE_OID; + public static final String MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME = "MANDATOR-NATURAL-PERSON-BIRTHDATE"; + public static final String MANDATE_NAT_PER_BIRTHDATE_FORMAT_PATTERN = BIRTHDATE_FORMAT_PATTERN; + + public static final String MANDATE_LEG_PER_FULL_NAME_OID = "1.2.40.0.10.2.1.1.261.84"; + public static final String MANDATE_LEG_PER_FULL_NAME_NAME = URN_OID_PREFIX + MANDATE_LEG_PER_FULL_NAME_OID; + public static final String MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME = "MANDATOR-LEGAL-PERSON-FULL-NAME"; + public static final int MANDATE_LEG_PER_FULL_NAME_MAX_LENGTH = 256; + + public static final String MANDATE_PROF_REP_OID_OID = "1.2.40.0.10.2.1.1.261.86"; + public static final String MANDATE_PROF_REP_OID_NAME = URN_OID_PREFIX + MANDATE_PROF_REP_OID_OID; + public static final String MANDATE_PROF_REP_OID_FRIENDLY_NAME = "MANDATOR-PROF-REP-OID"; + public static final int MANDATE_PROF_REP_OID_MAX_LENGTH = 256; + + public static final String MANDATE_PROF_REP_DESC_OID = "1.2.40.0.10.2.1.1.261.88"; + public static final String MANDATE_PROF_REP_DESC_NAME = URN_OID_PREFIX + MANDATE_PROF_REP_DESC_OID; + public static final String MANDATE_PROF_REP_DESC_FRIENDLY_NAME = "MANDATOR-PROF-REP-DESCRIPTION"; + public static final int MANDATE_PROF_REP_DESC_MAX_LENGTH = 1024; + + public static final String MANDATE_REFERENCE_VALUE_OID = "1.2.40.0.10.2.1.1.261.90"; + public static final String MANDATE_REFERENCE_VALUE_NAME = URN_OID_PREFIX + MANDATE_REFERENCE_VALUE_OID; + public static final String MANDATE_REFERENCE_VALUE_FRIENDLY_NAME = "MANDATE-REFERENCE-VALUE"; + public static final int MANDATE_REFERENCE_VALUE_MAX_LENGTH = 100; + + public static final String MANDATE_FULL_MANDATE_OID = "1.2.40.0.10.2.1.1.261.92"; + public static final String MANDATE_FULL_MANDATE_NAME = URN_OID_PREFIX + MANDATE_FULL_MANDATE_OID; + public static final String MANDATE_FULL_MANDATE_FRIENDLY_NAME = "MANDATE-FULL-MANDATE"; + public static final int MANDATE_FULL_MANDATE_MAX_LENGTH = 32767; + + public static final String INVOICE_RECPT_ID_OID = "1.2.40.0.10.2.1.1.261.40"; + public static final String INVOICE_RECPT_ID_NAME = URN_OID_PREFIX + INVOICE_RECPT_ID_OID; + public static final String INVOICE_RECPT_ID_FRIENDLY_NAME = "INVOICE-RECPT-ID"; + public static final int INVOICE_RECPT_ID_MAX_LENGTH = 64; + + public static final String COST_CENTER_ID_OID = "1.2.40.0.10.2.1.1.261.50"; + public static final String COST_CENTER_ID_NAME = URN_OID_PREFIX + COST_CENTER_ID_OID; + public static final String COST_CENTER_ID_FRIENDLY_NAME = "COST-CENTER-ID"; + public static final int COST_CENTER_ID_MAX_LENGTH = 32767; + + public static final String CHARGE_CODE_OID = "1.2.40.0.10.2.1.1.261.60"; + public static final String CHARGE_CODE_NAME = URN_OID_PREFIX + CHARGE_CODE_OID; + public static final String CHARGE_CODE_FRIENDLY_NAME = "CHARGE-CODE"; + public static final int CHARGE_CODE_MAX_LENGTH = 32767; +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/exception/ConfigurationException.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/exception/ConfigurationException.java new file mode 100644 index 000000000..77250d818 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/exception/ConfigurationException.java @@ -0,0 +1,20 @@ +package at.gv.egovernment.moa.id.demoOA.exception; + + +public class ConfigurationException extends Exception { + + private static final long serialVersionUID = 1L; + + public ConfigurationException(String errorname) { + super(errorname); + } + + public ConfigurationException(String errorname, Throwable e) { + super(errorname, e); + } + + public ConfigurationException(Throwable e) { + super(e); + } + +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java new file mode 100644 index 000000000..68fef277b --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java @@ -0,0 +1,222 @@ +package at.gv.egovernment.moa.id.demoOA.servlet.pvp2; + +import java.io.IOException; +import java.security.KeyStore; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.RuntimeConstants; +import org.joda.time.DateTime; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; +import org.opensaml.saml2.core.AuthnContextClassRef; +import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.NameIDPolicy; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.core.RequestedAuthnContext; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; +import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import at.gv.egovernment.moa.id.demoOA.Configuration; +import at.gv.egovernment.moa.id.demoOA.Constants; +import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; +import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; +import at.iaik.commons.util.MiscUtil; + + +/** + * Servlet implementation class Authenticate + */ +public class Authenticate extends HttpServlet { + private static final long serialVersionUID = 1L; + + private static final Logger log = LoggerFactory + .getLogger(Authenticate.class); + + /** + * @see HttpServlet#HttpServlet() + */ + public Authenticate() { + super(); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + builder = factory.newDocumentBuilder(); + + } catch (ParserConfigurationException e) { + log.warn("PVP2 AuthenticationServlet can not be initialized.", e); + } + } + + DocumentBuilder builder; + + + protected void process(HttpServletRequest request, + HttpServletResponse response, Map<String,String> legacyParameter) throws ServletException, IOException { + try { + + Configuration config = Configuration.getInstance(); + config.initializePVP2Login(); + + AuthnRequest authReq = SAML2Utils + .createSAMLObject(AuthnRequest.class); + SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + authReq.setID(gen.generateIdentifier()); + + HttpSession session = request.getSession(); + if (session != null) { + session.setAttribute(Constants.SESSION_PVP2REQUESTID, authReq.getID()); + } + + authReq.setAssertionConsumerServiceIndex(0); + authReq.setAttributeConsumingServiceIndex(0); + authReq.setIssueInstant(new DateTime()); + Subject subject = SAML2Utils.createSAMLObject(Subject.class); + NameID name = SAML2Utils.createSAMLObject(NameID.class); + Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); + + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) + serviceURL = serviceURL + "/"; + name.setValue(serviceURL); + issuer.setValue(serviceURL); + + subject.setNameID(name); + authReq.setSubject(subject); + issuer.setFormat(NameIDType.ENTITY); + authReq.setIssuer(issuer); + NameIDPolicy policy = SAML2Utils + .createSAMLObject(NameIDPolicy.class); + policy.setAllowCreate(true); + policy.setFormat(NameID.PERSISTENT); + authReq.setNameIDPolicy(policy); + + String entityname = config.getPVP2IDPMetadataEntityName(); + if (MiscUtil.isEmpty(entityname)) { + log.info("No IDP EntityName configurated"); + throw new ConfigurationException("No IDP EntityName configurated"); + } + + HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); + EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); + if (idpEntity == null) { + log.info("IDP EntityName is not found in IDP Metadata"); + throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); + } + + SingleSignOnService redirectEndpoint = null; + for (SingleSignOnService sss : + idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) { + + //Get the service address for the binding you wish to use + if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + redirectEndpoint = sss; + } + } + + authReq.setDestination(redirectEndpoint.getLocation()); + + RequestedAuthnContext reqAuthContext = + SAML2Utils.createSAMLObject(RequestedAuthnContext.class); + + AuthnContextClassRef authnClassRef = + SAML2Utils.createSAMLObject(AuthnContextClassRef.class); + + authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4"); + + reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); + + reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); + + authReq.setRequestedAuthnContext(reqAuthContext); + + KeyStore keyStore = config.getPVP2KeyStore(); + + X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + + Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(authcredential); + + authReq.setSignature(signer); + + VelocityEngine engine = new VelocityEngine(); + engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); + engine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8"); + engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); + engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + engine.setProperty("classpath.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + engine.init(); + + HTTPPostEncoder encoder = new HTTPPostEncoder(engine, + "templates/pvp_postbinding_template.html"); + HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); + SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); + service.setLocation(redirectEndpoint.getLocation());; + + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(authReq); + context.setOutboundMessageTransport(responseAdapter); + + encoder.encode(context); + + } catch (Exception e) { + log.warn("Authentication Request can not be generated", e); + throw new ServletException("Authentication Request can not be generated.", e); + } + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response, null); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response, null); + } + +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java new file mode 100644 index 000000000..f3821374a --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java @@ -0,0 +1,279 @@ +package at.gv.egovernment.moa.id.demoOA.servlet.pvp2; + +import java.io.IOException; +import java.io.StringWriter; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.log4j.Logger; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.AttributeConsumingService; +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.KeyDescriptor; +import org.opensaml.saml2.metadata.LocalizedString; +import org.opensaml.saml2.metadata.NameIDFormat; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.ServiceName; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; +import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureConstants; +import org.opensaml.xml.signature.Signer; +import org.w3c.dom.Document; + +import at.gv.egovernment.moa.id.demoOA.Configuration; +import at.gv.egovernment.moa.id.demoOA.Constants; +import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; +import at.gv.egovernment.moa.id.demoOA.utils.AttributeListBuilder; +import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; +import at.iaik.commons.util.MiscUtil; + +public class BuildMetadata extends HttpServlet { + private static final long serialVersionUID = 1L; + + private static final Logger log = Logger.getLogger(BuildMetadata.class); + + /** + * @see HttpServlet#HttpServlet() + */ + public BuildMetadata() { + super(); + } + + protected static Signature getSignature(Credential credentials) { + Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(credentials); + return signer; + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + Configuration config = Configuration.getInstance(); + + SecureRandomIdentifierGenerator idGen = new SecureRandomIdentifierGenerator(); + + EntitiesDescriptor spEntitiesDescriptor = SAML2Utils. + createSAMLObject(EntitiesDescriptor.class); + + String name = config.getPVP2MetadataEntitiesName(); + if (MiscUtil.isEmpty(name)) { + log.info("NO Metadata EntitiesName configurated"); + throw new ConfigurationException("NO Metadata EntitiesName configurated"); + } + + spEntitiesDescriptor.setName(name); + spEntitiesDescriptor.setID(idGen.generateIdentifier()); + + EntityDescriptor spEntityDescriptor = SAML2Utils + .createSAMLObject(EntityDescriptor.class); + + spEntitiesDescriptor.getEntityDescriptors().add(spEntityDescriptor); + + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) + serviceURL = serviceURL + "/"; + + log.debug("Set OnlineApplicationURL to " + serviceURL); + spEntityDescriptor.setEntityID(serviceURL); + + SPSSODescriptor spSSODescriptor = SAML2Utils + .createSAMLObject(SPSSODescriptor.class); + + spSSODescriptor.setAuthnRequestsSigned(true); + spSSODescriptor.setWantAssertionsSigned(true); + + X509KeyInfoGeneratorFactory keyInfoFactory = new X509KeyInfoGeneratorFactory(); + keyInfoFactory.setEmitEntityCertificate(true); + KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); + + + KeyStore keyStore = config.getPVP2KeyStore(); + + X509Credential signingcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreMetadataKeyAlias(), + config.getPVP2KeystoreMetadataKeyPassword().toCharArray()); + + + log.debug("Set Metadata key information"); + //Set MetaData Signing key + KeyDescriptor entitiesSignKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + entitiesSignKeyDescriptor.setUse(UsageType.SIGNING); + entitiesSignKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(signingcredential)); + Signature entitiesSignature = getSignature(signingcredential); + spEntitiesDescriptor.setSignature(entitiesSignature); + + + //Set AuthRequest Signing certificate + X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + KeyDescriptor signKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + signKeyDescriptor.setUse(UsageType.SIGNING); + signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential)); + spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); + + + //set AuthRequest encryption certificate + if (MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyAlias()) || + MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyPassword())) { + X509Credential authEncCredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), + config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); + KeyDescriptor encryKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + encryKeyDescriptor.setUse(UsageType.ENCRYPTION); + encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential)); + spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor); + + } else { + log.warn("No Assertion Encryption-Key defined. This setting is not recommended!"); + + } + + + NameIDFormat persistentnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + persistentnameIDFormat.setFormat(NameIDType.PERSISTENT); + + spSSODescriptor.getNameIDFormats().add(persistentnameIDFormat); + + NameIDFormat transientnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + transientnameIDFormat.setFormat(NameIDType.TRANSIENT); + + spSSODescriptor.getNameIDFormats().add(transientnameIDFormat); + + NameIDFormat unspecifiednameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + unspecifiednameIDFormat.setFormat(NameIDType.UNSPECIFIED); + + spSSODescriptor.getNameIDFormats().add(unspecifiednameIDFormat); + + AssertionConsumerService postassertionConsumerService = + SAML2Utils.createSAMLObject(AssertionConsumerService.class); + + postassertionConsumerService.setIndex(0); + postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + postassertionConsumerService.setLocation(serviceURL + Constants.SERVLET_PVP2ASSERTION); + + spSSODescriptor.getAssertionConsumerServices().add(postassertionConsumerService); + + spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + + spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); + + spSSODescriptor.setWantAssertionsSigned(true); + spSSODescriptor.setAuthnRequestsSigned(true); + + AttributeConsumingService attributeService = + SAML2Utils.createSAMLObject(AttributeConsumingService.class); + + attributeService.setIndex(0); + attributeService.setIsDefault(true); + ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class); + serviceName.setName(new LocalizedString("Default Service", "de")); + attributeService.getNames().add(serviceName); + + attributeService.getRequestAttributes().addAll(AttributeListBuilder.getRequestedAttributes()); + + spSSODescriptor.getAttributeConsumingServices().add(attributeService); + + DocumentBuilder builder; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + Marshaller out = org.opensaml.Configuration.getMarshallerFactory().getMarshaller(spEntitiesDescriptor); + out.marshall(spEntitiesDescriptor, document); + + Signer.signObject(entitiesSignature); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + + StringWriter sw = new StringWriter(); + StreamResult sr = new StreamResult(sw); + DOMSource source = new DOMSource(document); + transformer.transform(source, sr); + sw.close(); + + String metadataXML = sw.toString(); + + response.setContentType("text/xml"); + response.getOutputStream().write(metadataXML.getBytes()); + + response.getOutputStream().close(); + + } catch (ConfigurationException e) { + log.warn("Configuration can not be loaded.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (NoSuchAlgorithmException e) { + log.warn("Requested Algorithm could not found.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (ParserConfigurationException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (TransformerConfigurationException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (TransformerFactoryConfigurationError e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (TransformerException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + } + + catch (Exception e) { + log.warn("Unspecific PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + } + + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + } + +}
\ No newline at end of file diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java new file mode 100644 index 000000000..2d32ce9af --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java @@ -0,0 +1,264 @@ +package at.gv.egovernment.moa.id.demoOA.servlet.pvp2; + +import java.io.IOException; +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.EncryptedAssertion; +import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.encryption.Decrypter; +import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.security.MetadataCredentialResolver; +import org.opensaml.security.MetadataCredentialResolverFactory; +import org.opensaml.security.MetadataCriteria; +import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.ws.transport.http.HttpServletRequestAdapter; +import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver; +import org.opensaml.xml.encryption.InlineEncryptedKeyResolver; +import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver; +import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.security.CriteriaSet; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.criteria.EntityIDCriteria; +import org.opensaml.xml.security.criteria.UsageCriteria; +import org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver; +import org.opensaml.xml.security.keyinfo.KeyInfoCredentialResolver; +import org.opensaml.xml.security.keyinfo.KeyInfoProvider; +import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver; +import org.opensaml.xml.security.keyinfo.provider.DSAKeyValueProvider; +import org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider; +import org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider; +import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine; + +import at.gv.egovernment.moa.id.demoOA.Configuration; +import at.gv.egovernment.moa.id.demoOA.PVPConstants; +import at.gv.egovernment.moa.id.demoOA.utils.ApplicationBean; +import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; +import at.gv.egovernment.moa.util.DOMUtils; + + +public class DemoApplication extends HttpServlet { + + private static final long serialVersionUID = -2129228304760706063L; + private static final Logger log = Logger.getLogger(DemoApplication.class); + + + + private void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + + ApplicationBean bean = new ApplicationBean(); + + + String method = request.getMethod(); + HttpSession session = request.getSession(); + if (session == null) { + log.info("NO HTTP Session"); + bean.setErrorMessage("NO HTTP session"); + setAnser(request, response, bean); + return; + } + + if (method.equals("POST")) { + + try { + Configuration config = Configuration.getInstance(); + + //Decode with HttpPost Binding + HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); + BasicSAMLMessageContext<Response, ?, ?> messageContext = new BasicSAMLMessageContext<Response, SAMLObject, SAMLObject>(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter( + request)); + decode.decode(messageContext); + + Response samlResponse = (Response) messageContext.getInboundMessage(); + + Signature sign = samlResponse.getSignature(); + if (sign == null) { + log.info("Only http POST Requests can be used"); + bean.setErrorMessage("Only http POST Requests can be used"); + setAnser(request, response, bean); + return; + } + + //Validate Signature + SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + profileValidator.validate(sign); + + //Verify Signature + List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); + keyInfoProvider.add(new DSAKeyValueProvider()); + keyInfoProvider.add(new RSAKeyValueProvider()); + keyInfoProvider.add(new InlineX509DataProvider()); + + KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( + keyInfoProvider); + + MetadataCredentialResolverFactory credentialResolverFactory = MetadataCredentialResolverFactory.getFactory(); + MetadataCredentialResolver credentialResolver = credentialResolverFactory.getInstance(config.getMetaDataProvier()); + + CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); + criteriaSet.add(new EntityIDCriteria(config.getPVP2IDPMetadataEntityName())); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine(credentialResolver, keyInfoResolver); + trustEngine.validate(sign, criteriaSet); + + log.info("PVP2 Assertion is valid"); + + if (samlResponse.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + + List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); + + //check encrypted Assertion + List<EncryptedAssertion> encryAssertionList = samlResponse.getEncryptedAssertions(); + if (encryAssertionList != null && encryAssertionList.size() > 0) { + //decrypt assertions + + log.debug("Found encryped assertion. Start decryption ..."); + + KeyStore keyStore = config.getPVP2KeyStore(); + + X509Credential authDecCredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), + config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); + + + StaticKeyInfoCredentialResolver skicr = + new StaticKeyInfoCredentialResolver(authDecCredential); + + ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); + encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() ); + encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() ); + + Decrypter samlDecrypter = + new Decrypter(null, skicr, encryptedKeyResolver); + + for (EncryptedAssertion encAssertion : encryAssertionList) { + saml2assertions.add(samlDecrypter.decrypt(encAssertion)); + + } + + log.debug("Assertion decryption finished. "); + + } else { + saml2assertions = samlResponse.getAssertions(); + + } + + String givenName = null; + String familyName = null; + String birthday = null; + + for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { + + //loop through the nodes to get what we want + List<AttributeStatement> attributeStatements = saml2assertion.getAttributeStatements(); + for (int i = 0; i < attributeStatements.size(); i++) + { + List<Attribute> attributes = attributeStatements.get(i).getAttributes(); + for (int x = 0; x < attributes.size(); x++) + { + String strAttributeName = attributes.get(x).getDOM().getAttribute("Name"); + + if (strAttributeName.equals(PVPConstants.PRINCIPAL_NAME_NAME)) + familyName = attributes.get(x).getAttributeValues().get(0).getDOM().getTextContent(); + + if (strAttributeName.equals(PVPConstants.GIVEN_NAME_NAME)) + givenName = attributes.get(x).getAttributeValues().get(0).getDOM().getTextContent(); + + if (strAttributeName.equals(PVPConstants.BIRTHDATE_NAME)) { + birthday = attributes.get(x).getAttributeValues().get(0).getDOM().getTextContent(); + } + } + } + } + + org.w3c.dom.Document doc = SAML2Utils.asDOMDocument(samlResponse); + String assertion = DOMUtils.serializeNode(doc); + + bean.setAssertion(assertion); + bean.setDateOfBirth(birthday); + bean.setFamilyName(familyName); + bean.setGivenName(givenName); + bean.setLogin(true); + + setAnser(request, response, bean); + return; + + + } else { + bean.setErrorMessage("Der Anmeldevorgang wurde abgebrochen.<br>Eine genaue Beschreibung des Fehlers finden Sie in der darunterliegenden Assertion."); + setAnser(request, response, bean); + return; + + } + + } catch (Exception e) { + log.warn(e); + bean.setErrorMessage("Internal Error: " + e.getMessage()); + setAnser(request, response, bean); + return; + } + + } else { + bean.setErrorMessage("Die Demoapplikation unterstützt nur SAML2 POST-Binding."); + setAnser(request, response, bean); + return; + + } + } + + private void setAnser(HttpServletRequest request, HttpServletResponse response, ApplicationBean answersBean) throws ServletException, IOException { + // store bean in session + request.setAttribute("answers", answersBean); + + // you now can forward to some view, for example some results.jsp + request.getRequestDispatcher("demoapp.jsp").forward(request, response); + + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response); + } + + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/ApplicationBean.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/ApplicationBean.java new file mode 100644 index 000000000..83f9a8b2c --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/ApplicationBean.java @@ -0,0 +1,93 @@ +package at.gv.egovernment.moa.id.demoOA.utils; + +import java.io.Serializable; + +public class ApplicationBean implements Serializable { + + private static final long serialVersionUID = -1280536194708616850L; + + private String familyName; + private String givenName; + private String dateOfBirth; + private String assertion; + + private boolean isLogin = false; + + private String errorMessage; + + /** + * @return the familyName + */ + public String getFamilyName() { + return familyName; + } + /** + * @param familyName the familyName to set + */ + public void setFamilyName(String familyName) { + this.familyName = familyName; + } + /** + * @return the givenName + */ + public String getGivenName() { + return givenName; + } + /** + * @param givenName the givenName to set + */ + public void setGivenName(String givenName) { + this.givenName = givenName; + } + /** + * @return the dateOfBirth + */ + public String getDateOfBirth() { + return dateOfBirth; + } + /** + * @param dateOfBirth the dateOfBirth to set + */ + public void setDateOfBirth(String dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + /** + * @return the assertion + */ + public String getAssertion() { + return assertion; + } + /** + * @param assertion the assertion to set + */ + public void setAssertion(String assertion) { + this.assertion = assertion; + } + /** + * @return the errorMessage + */ + public String getErrorMessage() { + return errorMessage; + } + /** + * @param errorMessage the errorMessage to set + */ + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + /** + * @return the isLogin + */ + public boolean isLogin() { + return isLogin; + } + /** + * @param isLogin the isLogin to set + */ + public void setLogin(boolean isLogin) { + this.isLogin = isLogin; + } + + + +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java new file mode 100644 index 000000000..8c9d15d11 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java @@ -0,0 +1,57 @@ +package at.gv.egovernment.moa.id.demoOA.utils; + +import java.util.ArrayList; +import java.util.List; + +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.metadata.RequestedAttribute; + +import at.gv.egovernment.moa.id.demoOA.PVPConstants; + + + +public class AttributeListBuilder implements PVPConstants{ + + protected static RequestedAttribute buildReqAttribute(String name, String friendlyName, boolean required) { + RequestedAttribute attribute = SAML2Utils.createSAMLObject(RequestedAttribute.class); + attribute.setIsRequired(required); + attribute.setName(name); + attribute.setFriendlyName(friendlyName); + attribute.setNameFormat(Attribute.URI_REFERENCE); + return attribute; + } + + public static List<RequestedAttribute> getRequestedAttributes() { + List<RequestedAttribute> requestedAttributes = new ArrayList<RequestedAttribute>(); + + requestedAttributes.add(buildReqAttribute(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(GIVEN_NAME_NAME, GIVEN_NAME_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(BIRTHDATE_NAME, BIRTHDATE_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(BPK_NAME, BPK_FRIENDLY_NAME, true)); + + requestedAttributes.add(buildReqAttribute(EID_CITIZEN_QAA_LEVEL_NAME, EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_ISSUING_NATION_NAME, EID_ISSUING_NATION_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_SECTOR_FOR_IDENTIFIER_NAME, EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_SIGNER_CERTIFICATE_NAME, EID_SIGNER_CERTIFICATE_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_CCS_URL_NAME, EID_CCS_URL_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_AUTH_BLOCK_NAME, EID_AUTH_BLOCK_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_IDENTITY_LINK_NAME, EID_IDENTITY_LINK_FRIENDLY_NAME, true)); + + requestedAttributes.add(buildReqAttribute(MANDATE_TYPE_NAME, MANDATE_TYPE_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_FULL_MANDATE_NAME, MANDATE_FULL_MANDATE_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_LEG_PER_FULL_NAME_NAME, MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_LEG_PER_SOURCE_PIN_NAME, MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, false)); + + requestedAttributes.add(buildReqAttribute(MANDATE_NAT_PER_BIRTHDATE_NAME, MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_NAT_PER_BPK_NAME, MANDATE_NAT_PER_BPK_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_NAT_PER_FAMILY_NAME_NAME, MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_NAT_PER_GIVEN_NAME_NAME, MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, false)); + + requestedAttributes.add(buildReqAttribute(MANDATE_REFERENCE_VALUE_NAME, MANDATE_REFERENCE_VALUE_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_PROF_REP_OID_NAME, MANDATE_PROF_REP_OID_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(MANDATE_PROF_REP_DESC_NAME, MANDATE_PROF_REP_DESC_FRIENDLY_NAME, false)); + return requestedAttributes; + } +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/MetaDataVerificationFilter.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/MetaDataVerificationFilter.java new file mode 100644 index 000000000..2b4e20ba0 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/MetaDataVerificationFilter.java @@ -0,0 +1,54 @@ +package at.gv.egovernment.moa.id.demoOA.utils; + +import java.util.Iterator; + +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.provider.FilterException; +import org.opensaml.saml2.metadata.provider.MetadataFilter; +import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.security.x509.BasicX509Credential; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureValidator; +import org.opensaml.xml.validation.ValidationException; + +public class MetaDataVerificationFilter implements MetadataFilter { + + BasicX509Credential credential; + + public MetaDataVerificationFilter(BasicX509Credential credential) { + this.credential = credential; + } + + + public void doFilter(XMLObject metadata) throws FilterException { + if (metadata instanceof EntitiesDescriptor) { + EntitiesDescriptor entitiesDescriptor = (EntitiesDescriptor) metadata; + + if(entitiesDescriptor.getSignature() == null) { + throw new FilterException("IDP metadata is not signed", null); + } + + Signature sign = entitiesDescriptor.getSignature(); + + try { + + //Validate signature + SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + profileValidator.validate(sign); + + + //Verify signature + SignatureValidator sigValidator = new SignatureValidator(credential); + sigValidator.validate(sign); + + } catch (ValidationException e) { + throw new FilterException("IDP metadata validation error", e); + + } + + } + } + +} diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/SAML2Utils.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/SAML2Utils.java new file mode 100644 index 000000000..f04caf888 --- /dev/null +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/SAML2Utils.java @@ -0,0 +1,87 @@ +package at.gv.egovernment.moa.id.demoOA.utils; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.opensaml.Configuration; +import org.opensaml.DefaultBootstrap; +import org.opensaml.xml.ConfigurationException; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.XMLObjectBuilder; +import org.opensaml.xml.XMLObjectBuilderFactory; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.w3c.dom.Document; + + +public class SAML2Utils { + + static { + try { + DefaultBootstrap.bootstrap(); + } catch (ConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(false); + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static DocumentBuilder builder; + + public static <T> T createSAMLObject(final Class<T> clazz) { + try { + + XMLObjectBuilderFactory builderFactory = Configuration + .getBuilderFactory(); + + QName defaultElementName = (QName) clazz.getDeclaredField( + "DEFAULT_ELEMENT_NAME").get(null); + Map<QName, XMLObjectBuilder> builder = builderFactory.getBuilders(); + Iterator<QName> it = builder.keySet().iterator(); + + while (it.hasNext()) { + QName qname = it.next(); + if (qname.equals(defaultElementName)) { + System.out.printf("Builder for: %s\n", qname.toString()); + } + } + XMLObjectBuilder xmlBuilder = builderFactory + .getBuilder(defaultElementName); + + T object = (T) xmlBuilder.buildObject(defaultElementName); + return object; + } catch (Throwable e) { + System.out.printf("Failed to create object for: %s\n", + clazz.toString()); + e.printStackTrace(); + return null; + } + } + + public static Document asDOMDocument(XMLObject object) throws IOException, + MarshallingException, TransformerException { + org.w3c.dom.Document document = builder.newDocument(); + Marshaller out = Configuration.getMarshallerFactory().getMarshaller( + object); + out.marshall(object, document); + return (Document) document; + } + + + +} diff --git a/id/oa/src/main/resources/defaultConfig.properties b/id/oa/src/main/resources/defaultConfig.properties new file mode 100644 index 000000000..a15143ad3 --- /dev/null +++ b/id/oa/src/main/resources/defaultConfig.properties @@ -0,0 +1,20 @@ +general.login.pvp2.idp.metadata.url=https://labda.iaik.tugraz.at:8443/moa-id-auth/pvp2/metadata +general.login.pvp2.idp.metadata.certificate=D:/Projekte/svn/moa-id/configs/moa_idp.crt +general.login.pvp2.idp.metadata.entityID=https://labda.iaik.tugraz.at:8443/moa-id-auth + +general.login.pvp2.OA.metadata.entities.name=MOA-ID 2.x Configuration Tool +general.login.pvp2.OA.metadata.entity.name=https://labda.iaik.tugraz.at:8443/oa + +general.login.pvp2.OA.keystore.url=D:/Projekte/svn/moa-id/configs/pvp.p12 +general.login.pvp2.OA.keystore.password=123456 +general.login.pvp2.OA.keystore.type=PKCS12 + +general.login.pvp2.OA.keystore.metadata.sign.key.alias=pvpsp +general.login.pvp2.OA.keystore.metadata.sign.key.password=123456 + +general.login.pvp2.keystore.authrequest.sign.key.alias=pvpidp +general.login.pvp2.keystore.authrequest.sign.key.password=123456 + +general.login.pvp2.keystore.assertion.encryption.key.alias=pvpencryption +general.login.pvp2.keystore.assertion.encryption.key.password=123456 + diff --git a/id/oa/src/main/resources/templates/pvp_postbinding_template.html b/id/oa/src/main/resources/templates/pvp_postbinding_template.html new file mode 100644 index 000000000..1215c2b58 --- /dev/null +++ b/id/oa/src/main/resources/templates/pvp_postbinding_template.html @@ -0,0 +1,51 @@ +## +## Velocity Template for SAML 2 HTTP-POST binding +## +## Velocity context may contain the following properties +## action - String - the action URL for the form +## RelayState - String - the relay state for the message +## SAMLRequest - String - the Base64 encoded SAML Request +## SAMLResponse - String - the Base64 encoded SAML Response + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + + <body onload="document.forms[0].submit()"> + <noscript> + <p> + <strong>Note:</strong> Since your browser does not support JavaScript, + you must press the Continue button once to proceed. + </p> + </noscript> + + + <div id="alert">Your login is being processed. Thank you for waiting.</div> + + <style type="text/css"> + <!-- + #alert { + margin:100px 250px; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size:14px; + font-weight:normal; + } + --> + </style> + + <form action="${action}" method="post"> + <div> + #if($RelayState)<input type="hidden" name="RelayState" value="${RelayState}"/>#end + + #if($SAMLRequest)<input type="hidden" name="SAMLRequest" value="${SAMLRequest}"/>#end + + #if($SAMLResponse)<input type="hidden" name="SAMLResponse" value="${SAMLResponse}"/>#end + + </div> + <noscript> + <div> + <input type="submit" value="Continue"/> + </div> + </noscript> + </form> + + </body> +</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/WEB-INF/web.xml b/id/oa/src/main/webapp/WEB-INF/web.xml index 13158fdaa..85a1bbaeb 100644 --- a/id/oa/src/main/webapp/WEB-INF/web.xml +++ b/id/oa/src/main/webapp/WEB-INF/web.xml @@ -4,6 +4,40 @@ <web-app> <display-name>Sample OA</display-name> - <description>MOA Sample OA</description> + <description>MOA PVP2.1 Sample OA</description> + + <servlet> + <servlet-name>pvp2login</servlet-name> + <display-name>pvp2login</display-name> + <servlet-class>at.gv.egovernment.moa.id.demoOA.servlet.pvp2.Authenticate</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>pvp2login</servlet-name> + <url-pattern>/servlet/pvp2login</url-pattern> + </servlet-mapping> + + <servlet> + <servlet-name>pvp2metadata</servlet-name> + <display-name>Metadata</display-name> + <servlet-class>at.gv.egovernment.moa.id.demoOA.servlet.pvp2.BuildMetadata</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>pvp2metadata</servlet-name> + <url-pattern>/servlet/metadata</url-pattern> + </servlet-mapping> + + <servlet> + <servlet-name>pvp2demooa</servlet-name> + <display-name>Secure area</display-name> + <servlet-class>at.gv.egovernment.moa.id.demoOA.servlet.pvp2.DemoApplication</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>pvp2demooa</servlet-name> + <url-pattern>/demoapplication</url-pattern> + </servlet-mapping> + </web-app> diff --git a/id/oa/src/main/webapp/auth.jsp b/id/oa/src/main/webapp/auth.jsp deleted file mode 100644 index 0b563a83e..000000000 --- a/id/oa/src/main/webapp/auth.jsp +++ /dev/null @@ -1,48 +0,0 @@ -<html>
-<head>
-<title>MOA ID Auth Sample Login</title>
-</head>
-<body>
-<% /** assumes moa-id-auth and oa in the same servlet container,
- and moa-id-proxy on a different fixed location */
- String authUrlPath =
- request.getScheme() + "://"
- + request.getServerName() + ":" + request.getServerPort()
- + "/moa-id-auth/";
- String proxyUrlPath = "http://10.16.126.28:9080/moa-id-proxy/";
- String oaUrlPath =
- request.getScheme() + "://"
- + request.getServerName() + ":" + request.getServerPort()
- + "/oa/";
- String params =
- "Target=gb&" +
- "OA=" + proxyUrlPath + "index.jsp";
- String urlStartAuth =
- authUrlPath +
- "StartAuthentication?" +
- params;
- String templateParam =
- "&Template=" + oaUrlPath + "AuthTemplate.jsp";
- String urlStartAuthCustom =
- urlStartAuth +
- templateParam;
- String urlSelectBKU =
- authUrlPath +
- "SelectBKU?" +
- params;
- String urlSelectBKUCustom =
- urlSelectBKU +
- templateParam +
- "&BKUSelectionTemplate=" + oaUrlPath + "BKUSelectionTemplate.jsp";
-%>
-<a href="<%=urlStartAuth%>">Log in to sample application</a>
-<br>
-<a href="<%=urlStartAuthCustom%>">Log in to sample application using custom form</a>
-<br>
-<a href="<%=urlSelectBKU%>">Choose BKU (HTMLComplete or HTMLSelect) and log in</a>
-<br>
-<a href="<%=urlSelectBKUCustom%>">Choose BKU (HTMLSelect) using custom form and log in</a>
-<br>
-<a href="<%=authUrlPath+"StartAuthentication"%>">Wrong parameters example</a>
-</body>
-</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/chooseBKU.jsp b/id/oa/src/main/webapp/chooseBKU.jsp deleted file mode 100644 index 0135b6fdf..000000000 --- a/id/oa/src/main/webapp/chooseBKU.jsp +++ /dev/null @@ -1,19 +0,0 @@ -<html>
-<head>
-<title>BKU Auswahl</title>
-</head>
-<body>
-<h1>BKU Auswahl</h1>
-<p>
-<form method="post" action="<%=request.getParameter("returnURI")%>">
-<select name="bkuURI">
- <option value="http://localhost:3495/http-security-layer-request" selected>Lokale Bürgerkarte</option>
- <option value="https://provider1.at:3496/http-security-layer-request">Provider eins</option>
- <option value="https://provider2.at:3496/http-security-layer-request">Provider zwei</option>
- <option value="https://10.16.126.28:3496/http-security-layer-request">Bürgerkarte Arbeitsplatz Paul Ivancsics</option>
-</select>
-<input type="submit" value="Auswählen"/>
-</form>
-</p>
-</body>
-</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/css/index.css b/id/oa/src/main/webapp/css/index.css new file mode 100644 index 000000000..6ff99af63 --- /dev/null +++ b/id/oa/src/main/webapp/css/index.css @@ -0,0 +1,205 @@ +@charset "utf-8"; + +h2#demonstrator_tabheader, h2#demonstrator_contentheader { + padding:2px; + font-size:1.1em; + color:#fff; + border-bottom:2px solid #fff; +} + +#demonstrator_centercontent { + width:auto; + +} + +#demonstrator_content { + padding:20px; +} + +#demonstrator_content a { + text-decoration:underline; + color: #000; +} + +.logoutbuttons { + margin-bottom: 5px; + margin-top: 0; +} + +p { + margin-bottom:1em; +} + + +/* [OPTIONAL] Geben Sie hier die Farbe fuer den hellen Hintergrund an */ +.demonstrator_hell { + background-color : #DDDDDD; +} + +/* [OPTIONAL] Geben Sie hier die Farbe fuer den dunklen Hintergrund an */ +.demonstrator_dunkel { + background-color: #A02D2D; +} + +.demonstrator_logoutButton { + position: relative; + margin-left: 65%; + bottom: 15px; +} + +.demonstrator_button { +/* background: #efefef; + border:2px solid #000; */ + cursor: pointer; + width: 180px; + height: 25px; + text-align: center; + margin-bottom: 10px; + margin-top: 25px; + border-radius: 5px; + padding-top: 5px; + padding-bottom: 5px; +} + +#demonstrator_SAML-assertion { + display: none; +} + +#demonstrator_samlArea{ + width: 100%; +} + +/* Anmeldeframe */ +#demonstrator_main { + clear:both; +} + +#demonstrator_leftcontent { + /*float:left;*/ +/* width:255px; */ + margin-left: 40%; + position: relative; +/* margin: 0 auto; */ +} + +#submitbutton { + width: 150px; +} + +h2#demonstrator_tabheader, h2#demonstrator_contentheader { + padding:2px; + font-size:1.1em; + color:#fff; + border-bottom:2px solid #fff; +} + +#demonstrator_bkulogin { + overflow:hidden; +} + +#demonstrator_bkukarte { + float:left; + background: url(../img/karte.gif) no-repeat top center; + padding: 90px 10px 10px 10px; + text-align:center; + width:40%; +} + +#demonstrator_bkuhandy { + float:right; + background: url(../img/handy.gif) no-repeat top center; + padding: 90px 10px 10px 10px; + text-align:center; + width:40%; +} + +#demonstrator_mandate{ + text-align:center; + padding : 5px 5px 5px 5px; + clear: both; +} + +#demonstrator_stork{ + text-align:center; + padding-top: 5px; + padding-bottom: 5px; + clear: both; +} + +/* .demonstrator_button input { + background: #efefef; + border:1px solid #000; + cursor: pointer; +} */ + +#demonstrator_installJava, #demonstrator_BrowserNOK { + clear:both; + font-size:0.8em; + padding:4px; +} + +#demonstrator_localBKU { + padding:4px; +} + +#demonstrator_localBKU p{ + text-align: left; +} + +.demonstrator_sendButton { + background-color: DarkGray; + border-style: solid; + border-width: 1px; + border-color: black; +} + +#demonstrator_tab { + margin-top:2px; + padding:2px; + clear:both; +} + +#demonstrator_leftcontent a { + text-decoration:none; + color: #000; +/* display:block;*/ + padding:4px; +} + +#demonstrator_leftcontent a:hover, #demonstrator_leftcontent a:focus, #demonstrator_leftcontent a:active { + text-decoration:underline; + color: #000; +} + +#demonstrator_navlist { + margin-top:20px; +} + +#demonstrator_navlist ul { + list-style: none; + margin-left: 0; +} + +#demonstrator_navlist li { + border-bottom:1px solid #fff; +} + +/* iframe { + width:250px; +} */ + +.demonstrator_infobutton { + background-color: #005a00; + color: white; + font-family: serif; + text-decoration: none; + padding-top: 2px; + padding-right: 4px; + padding-bottom: 2px; + padding-left: 4px; + font-weight: bold; +} + +#demonstrator_cccSelection{ + margin-bottom: auto; +} diff --git a/id/oa/src/main/webapp/demoapp.jsp b/id/oa/src/main/webapp/demoapp.jsp new file mode 100644 index 000000000..c6b005deb --- /dev/null +++ b/id/oa/src/main/webapp/demoapp.jsp @@ -0,0 +1,73 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<%@ page import = "at.gv.egovernment.moa.id.demoOA.utils.ApplicationBean" %> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +<html> +<head> + <meta http-equiv="Content-Type\" content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" content="text/css"> + <link rel="stylesheet" type="text/css" href="css/index.css"> + <title>Demo Applikation</title> +</head> +<body> + + <% + ApplicationBean bean = (ApplicationBean) request.getAttribute("answers"); + %> + + <div id="demonstrator_main" class="demonstrator_main_success"> + + <div id="demonstrator_centercontent"> + <h2 id="demonstrator_contentheader" class="demonstrator_dunkel">Anmeldedaten</h2> + <div id="demonstrator_content" class="demonstrator_hell"> + + <% if (bean.isLogin()) {%> + <div id="demonstrator_centercontent"> + <div class="demonstrator_logoutButton"> + <p class="logoutbuttons"><a href="index.jsp" class="logoutbuttons">LogOut</a></p> + </div> + + <div id="demonstrator_loginInformation"> + <table> + <tr> + <td align="right">Benutzerdaten:</td> + <td><%= bean.getGivenName()%> + <%= bean.getFamilyName()%> + <%= bean.getDateOfBirth()%></td> + </tr> + </table> + + <%} else { %> + + <div class="demonstrator_logoutButton"> + <a href="index.jsp">LogIn</a> + </div> + <p><%= bean.getErrorMessage()%></p> + <%} %> + + + <div id="demonstrator_showSAMLButton" class="demonstrator_button"\> + <input type="button" + onclick="document.getElementById('demonstrator_SAML-assertion').style.display='block';document.getElementById('demonstrator_showSAMLButton').hidden='true';document.getElementById('demonstrator_hideSAMLButton').hidden='';" + value='Assertion anzeigen'/> + </div> + <div id="demonstrator_hideSAMLButton" class="demonstrator_button" hidden> + <input type="button" + onclick="document.getElementById('demonstrator_SAML-assertion').style.display='none';document.getElementById('demonstrator_showSAMLButton').hidden='';document.getElementById('demonstrator_hideSAMLButton').hidden='true';" + value='Assertion ausblenden'/> + </div> + + <div id="demonstrator_SAML-assertion"> + <p>SAML Assertion</p> + <form> + <textarea id="demonstrator_samlArea" rows="10"><%= bean.getAssertion()%></textarea> + </form> + </div> + </div> + </div> + </div> + </div> + +</body> +</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/form.jsp b/id/oa/src/main/webapp/form.jsp deleted file mode 100644 index d439fa84d..000000000 --- a/id/oa/src/main/webapp/form.jsp +++ /dev/null @@ -1,20 +0,0 @@ -<%@ page import="java.util.*" %>
-<html>
-<head>
-<title>Sample Online Application</title>
-</head>
-<body>
-<h1>Sample Form</h1>
-<p>
-<form action="form.jsp">
-<% String param1 = request.getParameter("param1");
- if (param1 == null) param1 = ""; %>
-Input some text:
-<input type="text" name="param1" size="10"/>
-<br>Previous text input: <%=param1%><br>
-<input type="submit" value="Send"/>
-</form>
-</p>
-<p><a href="index.jsp">Back</a></p>
-</body>
-</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/getBKUSelectTag.jsp b/id/oa/src/main/webapp/getBKUSelectTag.jsp deleted file mode 100644 index 028dbd348..000000000 --- a/id/oa/src/main/webapp/getBKUSelectTag.jsp +++ /dev/null @@ -1,6 +0,0 @@ -<select name="bkuURI">
- <option value="http://localhost:3495/http-security-layer-request" selected>Lokale Bürgerkarte</option>
- <option value="https://provider1.at:3496/http-security-layer-request">Provider eins</option>
- <option value="https://provider2.at:3496/http-security-layer-request">Provider zwei</option>
- <option value="https://10.16.126.28:3496/http-security-layer-request">Bürgerkarte Arbeitsplatz Paul Ivancsics</option>
-</select>
diff --git a/id/oa/src/main/webapp/index.jsp b/id/oa/src/main/webapp/index.jsp deleted file mode 100644 index 35e49d743..000000000 --- a/id/oa/src/main/webapp/index.jsp +++ /dev/null @@ -1,60 +0,0 @@ -<%@ page import="java.util.*,javax.servlet.http.*,sun.misc.BASE64Decoder" %>
-<html>
-<head>
-<title>Sample Online Application</title>
-</head>
-<body>
-<h1>Sample Online Application</h1>
-
-<p>Request headers:
-<table border="1">
- <%
- /* collect parameters from request */
- for (Enumeration headers = request.getHeaderNames(); headers.hasMoreElements(); ) {
- String key = (String) headers.nextElement();
- String value = request.getHeader(key); %>
- <tr><td><%=key%></td><td><%=value%></td></tr>
- <% } %>
-</table>
-</p>
-
-<% String query=request.getQueryString(); %>
-<p>QueryString: "<%=query%>"
-</p>
-
-<p>Request parameters:
-<table border="1">
- <%
- /* collect parameters from request */
- for (Enumeration params = request.getParameterNames(); params.hasMoreElements(); ) {
- String name = (String) params.nextElement();
- String value = request.getParameter(name); %>
- <tr><td><%=name%></td><td><%=value%></td></tr>
- <% } %>
-</table>
-</p>
-
-<p>Cookies:
-<table border="1">
- <%
- /* collect attributes from request */
- Cookie[] cookies = request.getCookies();
- if (cookies != null) {
- for (int i = 0; i < cookies.length; i++) {
- Cookie cookie = cookies[i]; %>
- <tr><td><%=cookie.getName()%></td><td><%=cookie.getValue()%></td></tr>
- <% }
- } %>
-</table>
-</p>
-
-<% String authHeader = request.getHeader("Authorization");
- if (authHeader != null) {
- authHeader = authHeader.substring(authHeader.indexOf(" ")+1);
- String decAuthHeader = new String(new BASE64Decoder().decodeBuffer(authHeader));
-%>
-<p>Basic authentication credentials: <%=decAuthHeader%></p>
-<% } %>
-<p><a href="form.jsp">Form sample</a></p>
-</body>
-</html>
\ No newline at end of file diff --git a/id/oa/src/main/webapp/js/common.js b/id/oa/src/main/webapp/js/common.js new file mode 100644 index 000000000..59b7b4e0e --- /dev/null +++ b/id/oa/src/main/webapp/js/common.js @@ -0,0 +1,32 @@ +function gup(name) { + name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + var regexS = "[\\?&]"+name+"=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( window.location.href ); + if( results == null ) + return ""; + else + return results[1]; +} +function jumpToAnker() { + var jump = gup("jump"); + if (jump != "") { + location.hash="#"+jump; + } +} +function PVP2LoginIframe(url) { + var el = document.getElementById("demonstrator_leftcontent"); + + var iframe = document.createElement("iframe"); + iframe.setAttribute("src", url); + iframe.setAttribute("width", "240"); + iframe.setAttribute("height", "220"); + iframe.setAttribute("frameborder", "0"); + iframe.setAttribute("scrolling", "no"); + iframe.setAttribute("title", "Login"); + + var button = document.getElementById("submitbutton"); + button.parentNode.removeChild(button); + + el.appendChild(iframe, el); +} diff --git a/id/oa/src/main/webapp/stateful_login.jsp b/id/oa/src/main/webapp/stateful_login.jsp deleted file mode 100644 index eaede507f..000000000 --- a/id/oa/src/main/webapp/stateful_login.jsp +++ /dev/null @@ -1,29 +0,0 @@ -<%@ page import="javax.servlet.http.*" %>
-<%
- /* check request's remote IP address - must be moa-id-proxy's address */
- String remoteIPAddress = request.getRemoteAddr();
- if (! "127.0.0.1".equals(remoteIPAddress)) { /* Substitute "127.0.0.1" for moa-id-proxy's IP address */
- response.setStatus(403);
- return;
- }
-
- /* store authentication data in cookies */
- String fn = request.getParameter("FamilyName");
- String gn = request.getParameter("GivenName");
- /* set cookie domain and cookie path ! */
- String cookieDomain = ".test.test"; /* Set this to the common domain of moa-id-proxy and of the online application */
- String cookiePath = request.getContextPath(); /* Set this to the context path of the online application */
-
- Cookie cfn = new Cookie("familyname", fn);
- cfn.setDomain(cookieDomain);
- cfn.setPath(cookiePath);
- response.addCookie(cfn);
-
- Cookie cgn = new Cookie("givenname", gn);
- cgn.setDomain(cookieDomain);
- cgn.setPath(cookiePath);
- response.addCookie(cgn);
-
- /* redirect to online application's start page */
- response.sendRedirect("http://oa.test.test:8080/oa/index.jsp"); /* Substitute for URL in online application */
-%>
|