/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ package at.gv.egovernment.moa.id.advancedlogging; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Date; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import org.apache.commons.lang3.StringEscapeUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandator; import at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; import at.gv.egovernment.moa.id.auth.exception.ServiceException; import at.gv.egovernment.moa.id.client.SZRGWClientException; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.data.IAuthenticationSession; import at.gv.egovernment.moa.id.commons.api.data.IMISMandate; import at.gv.egovernment.moa.id.commons.api.exceptions.BKUException; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MISSimpleClientException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.dao.statistic.StatisticLog; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.config.auth.OAAuthParameterDecorator; import at.gv.egovernment.moa.id.data.IMOAAuthData; import at.gv.egovernment.moa.id.moduls.SSOManager; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @Repository("StatisticLogger") @Transactional("statisticLogTransactionManager") public class StatisticLogger implements IStatisticLogger{ private static final String GENERIC_LOCALBKU = ":3496/https-security-layer-request"; private static final String GENERIC_HANDYBKU = "https://www.handy-signatur.at/"; private static final String GENERIC_ONLINE_BKU = "bkuonline"; private static final String MANTATORTYPE_JUR = "jur"; private static final String MANTATORTYPE_NAT = "nat"; private static final int MAXERRORLENGTH = 200; private static final int MAXOAIDENTIFIER_LENGTH = 254; private static final String ERRORTYPE_UNKNOWN = "unkown"; private static final String ERRORTYPE_BKU = "bku"; private static final String ERRORTYPE_MOASP = "moa-sp"; private static final String ERRORTYPE_MANDATE = "mandate"; private static final String ERRORTYPE_MOAID = "moa-id"; private static final String ERRORTYPE_SZRGW = "szrgw"; @Autowired AuthConfiguration authConfig; @Autowired IAuthenticationSessionStoreage authenticatedSessionStorage; @PersistenceContext(unitName="statistic") private EntityManager entityManager; @Override public void internalTesting() throws Exception { long testId = 1; Query query = entityManager.createNamedQuery("getTestEntity"); query.setParameter("testid", testId); query.getResultList(); } public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession) { if ( authConfig.isAdvancedLoggingActive() && protocolRequest != null && authData != null) { IOAAuthParameters dbOA = null; dbOA = protocolRequest.getServiceProviderConfiguration(OAAuthParameterDecorator.class); if (dbOA == null) { Logger.warn("Advanced logging failed: OA can not be found in database."); return; } StatisticLog dblog = new StatisticLog(); //set actual date and time dblog.setTimestamp(new Date()); //log basic AuthInformation dblog.setOaurlprefix(getMessageWithMaxLength(dbOA.getPublicURLPrefix(), MAXOAIDENTIFIER_LENGTH)); dblog.setOafriendlyName(dbOA.getFriendlyName()); try { dblog.setBusinessservice(dbOA.hasBaseIdTransferRestriction()); } catch (Exception e) { Logger.warn("Can not extract some information for StatisticLogger.", e); } dblog.setProtocoltype(protocolRequest.requestedModule()); dblog.setProtocolsubtype(protocolRequest.requestedAction()); dblog.setSsosession(isSSOSession); if (authData instanceof IMOAAuthData) { IMOAAuthData moaAuthData = (IMOAAuthData) authData; dblog.setOatarget(moaAuthData.getBPKType()); boolean isFederatedAuthentication = protocolRequest.getRawData(SSOManager.DATAID_INTERFEDERATIOIDP_RESPONSE) != null; dblog.setInterfederatedSSOSession(isFederatedAuthentication); if (isFederatedAuthentication) { dblog.setBkutype(IOAAuthParameters.INDERFEDERATEDIDP); dblog.setBkuurl(protocolRequest.getRawData(SSOManager.DATAID_INTERFEDERATIOIDP_ENTITYID, String.class)); } else if (moaAuthData.isForeigner()) { dblog.setBkutype(IOAAuthParameters.EIDAS); } else { dblog.setBkuurl(moaAuthData.getBkuURL()); dblog.setBkutype(findBKUType(moaAuthData.getBkuURL(), dbOA)); } //log MandateInforamtion if (moaAuthData.isUseMandate()) { dblog.setMandatelogin(moaAuthData.isUseMandate()); IMISMandate mandate = moaAuthData.getMISMandate(); if (mandate != null) { if (MiscUtil.isNotEmpty(mandate.getProfRep())) { dblog.setMandatetype(mandate.getProfRep()); dblog.setPv(true); dblog.setPvOID(mandate.getProfRep()); } else { dblog.setPv(false); } InputStream is = null; try { is = new ByteArrayInputStream(mandate.getMandate()); JAXBContext jc = JAXBContext.newInstance(Mandate.class); Unmarshaller u = jc.createUnmarshaller(); Object mismandateobj = u.unmarshal(is); if (mismandateobj != null && mismandateobj instanceof Mandate) { Mandate mismandate = (Mandate) mismandateobj; if (MiscUtil.isEmpty(mandate.getProfRep())) dblog.setMandatetype(mismandate.getAnnotation()); Mandator mandator = mismandate.getMandator(); CorporateBodyType corp = mandator.getCorporateBody(); if (corp != null) { dblog.setMandatortype(MANTATORTYPE_JUR); } else { dblog.setMandatortype(MANTATORTYPE_NAT); } } else { Logger.warn("Advancted logging can not unmarshall MISMandate"); } } catch (JAXBException e) { Logger.warn("Advancted logging can not parse mandate.", e); } finally { if (is!=null) { try { is.close(); } catch (IOException e) { Logger.warn("Close InputStream failed." , e); } } } } } } else Logger.info("'AuthData' is NOT of type 'IMOAAuthData'. StatisticLogger logs only basic infos"); try { entityManager.persist(dblog); } catch (Exception e) { Logger.warn("Write 'success' statisticLog to database FAILED.", e); } } } public void logErrorOperation(Throwable throwable) { if ( authConfig.isAdvancedLoggingActive() ) { StatisticLog dblog = new StatisticLog(); //set actual date and time dblog.setTimestamp(new Date()); if (throwable != null) generateErrorLogFormThrowable(throwable, dblog); else { dblog.setErrormessage("UNKOWN ERROR DETECTED!"); dblog.setErrortype(ERRORTYPE_UNKNOWN); } try { entityManager.persist(dblog); } catch (Exception e) { Logger.warn("Write 'error' statisticLog to database FAILED.", e); } } } public void logErrorOperation(Throwable throwable, IRequest errorRequest) { if (authConfig.isAdvancedLoggingActive() && throwable != null && errorRequest != null) { StatisticLog dblog = new StatisticLog(); //set actual date and time dblog.setTimestamp(new Date()); dblog.setOaurlprefix(getMessageWithMaxLength(errorRequest.getSPEntityId(), MAXOAIDENTIFIER_LENGTH)); dblog.setProtocoltype(errorRequest.requestedModule()); dblog.setProtocolsubtype(errorRequest.requestedAction()); generateErrorLogFormThrowable(throwable, dblog); IOAAuthParameters dbOA = errorRequest.getServiceProviderConfiguration(OAAuthParameterDecorator.class); if (dbOA != null) { dblog.setOaurlprefix(getMessageWithMaxLength(dbOA.getPublicURLPrefix(), MAXOAIDENTIFIER_LENGTH)); dblog.setOafriendlyName(dbOA.getFriendlyName()); try { dblog.setOatarget(dbOA.getAreaSpecificTargetIdentifier()); dblog.setBusinessservice(dbOA.hasBaseIdTransferRestriction()); } catch (Exception e) { Logger.warn("Can not extract some information for StatisticLogger.", e); } IAuthenticationSession moasession = null; if (MiscUtil.isNotEmpty(errorRequest.getInternalSSOSessionIdentifier())) { Logger.debug("Use MOA session information from SSO session for ErrorLogging"); try { moasession = authenticatedSessionStorage.getInternalSSOSession(errorRequest.getInternalSSOSessionIdentifier()); } catch (MOADatabaseException e) { Logger.error("Error during database communication", e); } } else { Logger.debug("Use MOA session information from pending-req for ErrorLogging"); moasession = (IAuthenticationSession) errorRequest.getSessionData(AuthenticationSessionWrapper.class); } if (moasession != null) { if (MiscUtil.isNotEmpty(moasession.getBkuURL())) { dblog.setBkuurl(moasession.getBkuURL()); if (moasession.isForeigner()) { dblog.setBkutype(IOAAuthParameters.EIDAS); } else dblog.setBkutype(findBKUType(moasession.getBkuURL(), dbOA)); } dblog.setMandatelogin(moasession.isMandateUsed()); } } try { entityManager.persist(dblog); } catch (Exception e) { Logger.warn("Write 'error' statisticLog to database FAILED.", e); } } } private String getMessageWithMaxLength(String msg, int maxlength) { return getErrorMessageWithMaxLength(msg, maxlength); } private String getErrorMessageWithMaxLength(String error, int maxlength) { if (error != null) { if (error.length() > maxlength) return StringEscapeUtils.escapeHtml4(error.substring(0, maxlength)); else return StringEscapeUtils.escapeHtml4(error); } else return new String(); } private void generateErrorLogFormThrowable(Throwable throwable, StatisticLog dblog) { if (throwable instanceof BKUException) { BKUException error = (BKUException) throwable; dblog.setErrortype(ERRORTYPE_BKU); dblog.setErrorcode(error.getBkuErrorCode()); dblog.setErrormessage(getErrorMessageWithMaxLength(error.getBkuErrorMessage(), MAXERRORLENGTH)); } else if (throwable instanceof SZRGWClientException) { SZRGWClientException error = (SZRGWClientException) throwable; dblog.setErrortype(ERRORTYPE_SZRGW); dblog.setErrorcode(error.getSzrErrorCode()); dblog.setErrormessage(getErrorMessageWithMaxLength(error.getSzrErrorMessage(), MAXERRORLENGTH)); } else if (throwable instanceof MISSimpleClientException) { MISSimpleClientException error = (MISSimpleClientException) throwable; dblog.setErrortype(ERRORTYPE_MANDATE); dblog.setErrorcode(error.getMISErrorCode()); if (MiscUtil.isEmpty(error.getMISErrorMessage())) dblog.setErrormessage(getErrorMessageWithMaxLength(error.getMessage(), MAXERRORLENGTH)); else dblog.setErrormessage(getErrorMessageWithMaxLength(error.getMISErrorMessage(), MAXERRORLENGTH)); } else if (throwable instanceof ServiceException) { ServiceException error = (ServiceException) throwable; dblog.setErrortype(ERRORTYPE_MOASP); dblog.setErrorcode(error.getMessageId()); dblog.setErrormessage(getErrorMessageWithMaxLength(error.getMessage(), MAXERRORLENGTH)); } else if (throwable instanceof MOAIDException) { MOAIDException error = (MOAIDException) throwable; dblog.setErrortype(ERRORTYPE_MOAID); dblog.setErrorcode(error.getMessageId()); dblog.setErrormessage(getErrorMessageWithMaxLength(error.getMessage(), MAXERRORLENGTH)); } else { dblog.setErrortype(ERRORTYPE_UNKNOWN); dblog.setErrormessage(getErrorMessageWithMaxLength(throwable.getMessage(), MAXERRORLENGTH)); } } private String findBKUType(String bkuURL, IOAAuthParameters dbOA) { if (bkuURL != null) { if (dbOA != null) { if (bkuURL.equals(dbOA.getBKUURL(OAAuthParameterDecorator.HANDYBKU))) return IOAAuthParameters.HANDYBKU; if (bkuURL.equals(dbOA.getBKUURL(OAAuthParameterDecorator.LOCALBKU))) return IOAAuthParameters.LOCALBKU; if (bkuURL.equals(dbOA.getBKUURL(OAAuthParameterDecorator.THIRDBKU))) return IOAAuthParameters.THIRDBKU; } Logger.trace("Staticic Log search BKUType from DefaultBKUs"); try { if (bkuURL.equals(authConfig.getDefaultBKUURL(IOAAuthParameters.THIRDBKU))) return IOAAuthParameters.THIRDBKU; if (bkuURL.equals(authConfig.getDefaultBKUURL(IOAAuthParameters.LOCALBKU))) return IOAAuthParameters.LOCALBKU; if (bkuURL.equals(authConfig.getDefaultBKUURL(IOAAuthParameters.HANDYBKU))) return IOAAuthParameters.HANDYBKU; } catch (ConfigurationException e) { Logger.info("Advanced Logging: Default BKUs read failed"); } Logger.debug("Staticic Log search BKUType from generneric Parameters"); if (bkuURL.endsWith(GENERIC_LOCALBKU)) { Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.LOCALBKU); return IOAAuthParameters.LOCALBKU; } if (bkuURL.startsWith(GENERIC_HANDYBKU)) { Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.HANDYBKU); return IOAAuthParameters.HANDYBKU; } } Logger.debug("BKUURL " + bkuURL + " is mapped to " + IOAAuthParameters.AUTHTYPE_OTHERS); return IOAAuthParameters.AUTHTYPE_OTHERS; } }