aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java372
1 files changed, 372 insertions, 0 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java
new file mode 100644
index 00000000..cec36d4b
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java
@@ -0,0 +1,372 @@
+package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.Handler;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.jaxws.DispatchImpl;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+import org.apache.xpath.XPathAPI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.w3._2000._09.xmldsig.KeyValueType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.SZRCommunicationException;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.LoggingHandler;
+import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.DOMUtils;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+import szrservices.GetBPK;
+import szrservices.GetBPKResponse;
+import szrservices.GetIdentityLink;
+import szrservices.GetIdentityLinkResponse;
+import szrservices.IdentityLinkType;
+import szrservices.PersonInfoType;
+import szrservices.SZR;
+import szrservices.SZRException_Exception;
+
+@Service("SZRClientForeIDAS")
+public class SZRClient {
+ private static final Logger log = LoggerFactory.getLogger(SZRClient.class);
+
+ private static final String CLIENT_DEFAULT = "DefaultClient";
+ private static final String CLIENT_RAW = "RawClient";
+
+ @Autowired private IConfiguration basicConfig;
+ @Resource private WebServiceContext wsContext;
+
+ //client for anything, without identitylink
+ private SZR szr = null;
+
+ //RAW client is needed for identitylink
+ private Dispatch<Source> dispatch = null;
+
+
+ private SZRService szrService = null;
+ private String szrURL = null;
+ private QName qname = null;
+
+ public IdentityLinkType getIdentityLink(PersonInfoType personInfo, List<KeyValueType> keyValue, Boolean insertERnP) throws SZRCommunicationException {
+ try {
+ return szr.getIdentityLink(
+ personInfo,
+ keyValue,
+ insertERnP);
+
+ } catch (SZRException_Exception e) {
+ log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e);
+ throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e);
+
+ }
+
+ }
+
+ public IdentityLinkType getIdentityLinkInRawMode(PersonInfoType personInfo, List<KeyValueType> keyValue, Boolean insertERnP) throws SZRCommunicationException {
+ try {
+ GetIdentityLink getIDL = new GetIdentityLink();
+ getIDL.setInsertERnP(insertERnP);
+ getIDL.setPersonInfo(personInfo);
+ getIDL.getKeyValue().addAll(keyValue);
+
+ JAXBContext jaxbContext = JAXBContext.newInstance(GetIdentityLink.class);
+ Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
+
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ jaxbMarshaller.marshal(getIDL, outputStream);
+ outputStream.flush();
+
+ Source source = new StreamSource(new ByteArrayInputStream(outputStream.toByteArray()));
+ outputStream.close();
+
+ log.trace("Requesting SZR ... ");
+ Source response = dispatch.invoke(source);
+ log.trace("Receive RAW response from SZR");
+
+ byte[] szrResponse = sourceToByteArray(response);
+ JAXBContext ctx = JAXBContext.newInstance(IdentityLinkType.class
+ .getPackage().getName());
+ GetIdentityLinkResponse jaxbElement = (GetIdentityLinkResponse) ctx
+ .createUnmarshaller().unmarshal(new ByteArrayInputStream(szrResponse));
+
+
+ //build response
+ log.trace(new String(szrResponse));
+ log.trace("Signature successfully created. Extracting from MOA-SS container.");
+
+ // ok, we have success
+ Document doc = DOMUtils.parseDocument(
+ new ByteArrayInputStream(szrResponse),
+ true, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, null
+ );
+ String xpathExpression = "//saml:Assertion";
+ Element nsNode = doc.createElementNS("urn:oasis:names:tc:SAML:1.0:assertion", "saml:NSNode");
+
+ log.trace("Selecting signed doc " + xpathExpression);
+ Element documentNode = (Element) XPathAPI.selectSingleNode(doc,
+ xpathExpression, nsNode);
+ log.trace("Signed document: " + DOMUtils.serializeNode(documentNode));
+
+
+ IdentityLinkType idl = new IdentityLinkType();
+ idl.setAssertion(documentNode);
+ idl.setPersonInfo(jaxbElement.getGetIdentityLinkReturn().getPersonInfo());
+
+ return idl;
+
+
+ //IdentityLinkType idlResp = this.szr.getIdentityLink(personInfo, keyValue, insertERnP);
+
+ } catch ( Exception e) {
+ log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e);
+ throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e);
+
+ }
+
+ }
+
+ public String getBPK(PersonInfoType personInfo, String target, String vkz) throws SZRCommunicationException {
+ try {
+ GetBPK parameters = new GetBPK();
+ parameters.setPersonInfo(personInfo);
+ parameters.setBereichsKennung(target);
+ parameters.setVKZ(vkz);
+ GetBPKResponse result = this.szr.getBPK(parameters);
+
+ return result.getGetBPKReturn();
+
+ } catch (SZRException_Exception e) {
+ log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e);
+ throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e);
+
+ }
+
+ }
+
+
+ @PostConstruct
+ private void initialize() {
+ log.info("Starting SZR-Client initialization .... ");
+ URL url = SZRClient.class.getResource("/szr_client/SZR-1.WSDL");
+
+ boolean useTestSZR = basicConfig.getBasicMOAIDConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE,
+ true);
+
+ if (useTestSZR) {
+ log.debug("Initializing SZR test environment configuration.");
+ qname = SZRService.SZRTestumgebung;
+ szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService"));
+ szr = szrService.getSZRTestumgebung();
+ szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST);
+
+
+ } else {
+ log.debug("Initializing SZR productive configuration.");
+ qname = SZRService.SZRProduktionsumgebung;
+ szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService"));
+ szr = szrService.getSZRProduktionsumgebung();
+ szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD);
+
+ }
+
+ //create raw client;
+ dispatch = szrService.createDispatch(qname, Source.class, javax.xml.ws.Service.Mode.PAYLOAD);
+
+ if (StringUtils.isEmpty(szrURL)) {
+ log.error("No SZR service-URL found. SZR-Client initalisiation failed.");
+ throw new RuntimeException("No SZR service URL found. SZR-Client initalisiation failed.");
+
+ }
+
+ log.info("Use SZR service-URL: " + szrURL);
+ injectBindingProvider((BindingProvider) szr, CLIENT_DEFAULT);
+ injectBindingProvider((BindingProvider) dispatch, CLIENT_RAW);
+
+ log.debug("Inject HTTP client settings ... ");
+ injectHTTPClient(szr, CLIENT_DEFAULT);
+ injectHTTPClient(dispatch, CLIENT_RAW);
+
+ log.info("SZR-Client initialization successfull");
+ }
+
+ private void injectHTTPClient(Object raw, String clientType) {
+ //extract client from implementation
+ Client client = null;
+ if (raw instanceof DispatchImpl<?>)
+ client = ((DispatchImpl<?>)raw).getClient();
+ else if (raw instanceof Client)
+ client = ClientProxy.getClient(raw);
+ else
+ throw new RuntimeException("SOAP Client for SZR connection is of UNSUPPORTED type: " + raw.getClass().getName());
+
+ //set basic connection policies
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+
+ //set timeout policy
+ HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
+ httpClientPolicy.setConnectionTimeout(
+ Integer.parseInt(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION,
+ Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION)) * 1000);
+ httpClientPolicy.setReceiveTimeout(
+ Integer.parseInt(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE,
+ Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE)) * 1000);
+ http.setClient(httpClientPolicy);
+
+ //inject SSL context in case of https
+ if (szrURL.toLowerCase().startsWith("https")) {
+ log.debug("Adding SSLContext to client: " + clientType +" ... ");
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setSSLSocketFactory(createSSLContext(clientType).getSocketFactory());
+ http.setTlsClientParameters(tlsParams );
+ log.info("SSLContext initialized for client: " + clientType);
+
+ }
+
+ }
+
+ private void injectBindingProvider(BindingProvider bindingProvider, String clientType) {
+ Map<String, Object> requestContext = bindingProvider.getRequestContext();
+ requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, szrURL);
+
+ log.trace("Adding JAX-WS request/response trace handler to client: " + clientType);
+ List<Handler> handlerList = bindingProvider.getBinding().getHandlerChain();
+ if (handlerList == null) {
+ handlerList = new ArrayList<Handler>();
+ bindingProvider.getBinding().setHandlerChain(handlerList);
+
+ }
+
+ //add logging handler to trace messages if required
+ if (basicConfig.getBasicMOAIDConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES,
+ false)) {
+ LoggingHandler loggingHandler = new LoggingHandler();
+ handlerList.add(loggingHandler);
+
+ }
+ }
+
+ private SSLContext createSSLContext(String clientType) {
+ try {
+ SSLContext context = SSLContext.getInstance("TLS");
+
+ //initialize key-mangager for SSL client-authentication
+ KeyManager[] keyManager = null;
+ String keyStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH);
+ String keyStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD);
+ if (StringUtils.isNotEmpty(keyStorePath)) {
+ log.trace("Find keyStore path: " + keyStorePath + " Injecting SSL client certificate ... ");
+ try {
+ KeyStore keyStore = KeyStoreUtils.loadKeyStore(
+ FileUtils.makeAbsoluteURL(keyStorePath, basicConfig.getConfigurationRootDirectory()),
+ keyStorePassword);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(keyStore, keyStorePassword.toCharArray());
+ keyManager = kmf.getKeyManagers();
+ log.debug("SSL client certificate injected to client: " + clientType);
+
+ } catch (KeyStoreException | IOException | UnrecoverableKeyException e) {
+ log.error("Can NOT load SSL client certificate from path: " + keyStorePath);
+ throw new RuntimeException("Can NOT load SSL client certificate from path: " + keyStorePath, e);
+
+ }
+ }
+
+
+ //initialize SSL TrustStore
+ TrustManager[] trustManager = null;
+ String trustStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH);
+ String trustStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD);
+ if (StringUtils.isNotEmpty(trustStorePath)) {
+ log.trace("Find trustStore path: " + trustStorePath + " Injecting SSL TrustStore ... ");
+ try {
+ KeyStore trustStore = KeyStoreUtils.loadKeyStore(
+ FileUtils.makeAbsoluteURL(trustStorePath, basicConfig.getConfigurationRootDirectory()),
+ trustStorePassword);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(trustStore);
+ trustManager = tmf.getTrustManagers();
+ log.debug("SSL TrustStore injected to client: " + clientType);
+
+ } catch (KeyStoreException | IOException e) {
+ log.error("Can NOT open SSL TrustStore from path: " + trustStorePath);
+ throw new RuntimeException("Can NOT open SSL TrustStore from path: " + trustStorePath, e);
+
+ }
+
+ }
+
+
+ context.init(keyManager, trustManager, new SecureRandom());
+ return context;
+
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ log.error("SSLContext initialization FAILED.", e);
+ throw new RuntimeException("SSLContext initialization FAILED.", e);
+
+ }
+
+ }
+
+ private byte[] sourceToByteArray(Source result) throws TransformerException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty("omit-xml-declaration", "yes");
+ transformer.setOutputProperty("method", "xml");
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ StreamResult streamResult = new StreamResult();
+ streamResult.setOutputStream(out);
+ transformer.transform(result, streamResult);
+ return out.toByteArray();
+ }
+
+
+
+}