/******************************************************************************* * Copyright 2015 e-SENS project * * 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://ec.europa.eu/idabc/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. *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.eidas; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.metadata.ContactPerson; import org.opensaml.saml2.metadata.Organization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.IAction; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.NewMoaEidasMetadata; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.engine.ProtocolEngineI; import eu.eidas.auth.engine.metadata.ContactData; import eu.eidas.auth.engine.metadata.MetadataConfigParams; import eu.eidas.auth.engine.metadata.MetadataConfigParams.Builder; import eu.eidas.auth.engine.metadata.OrganizationData; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; /** * First version to provide some valid metadata to an asking eIDaS node */ @Service("EidasMetaDataRequest") public class EidasMetaDataRequest implements IAction { @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; @Autowired(required=true) AuthConfiguration authConfig; @Autowired(required=true) IPVP2BasicConfiguration pvpConfiguration; /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @Override public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { try { String pubURLPrefix = req.getAuthURL(); String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST; //generate eIDAS metadata String metaData = generateMetadata(req, metadata_url, sp_return_url); //write content to response byte[] content = metaData.getBytes("UTF-8"); httpResp.setStatus(HttpServletResponse.SC_OK); httpResp.setContentType(MediaType.APPLICATION_XML.toString()); httpResp.setContentLength(content.length); httpResp.getOutputStream().write(content); //write log if required Logger.trace(metaData); } catch (Exception e) { Logger.error("eIDAS Metadata generation FAILED.", e); throw new MOAIDException("eIDAS.05", new Object[]{e.getMessage()}, e); } return null; } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { return false; } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName() */ @Override public String getDefaultActionName() { return "eIDAS-Metadata Action"; } public String generateMetadata(IRequest pendingReq, String metadata_url, String sp_return_url) throws EIDASSAMLEngineException, EIDASEngineException{ String metadata="invalid metadata"; ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); //configura metadata builder Builder metadataConfigBuilder = MetadataConfigParams.builder(); metadataConfigBuilder.entityID(metadata_url); metadataConfigBuilder.assertionConsumerUrl(sp_return_url); metadataConfigBuilder.addProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI); metadataConfigBuilder.addProtocolBindingLocation( SAMLConstants.SAML2_POST_BINDING_URI, pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST); //TODO: make it configurable metadataConfigBuilder.authnRequestsSigned(true); metadataConfigBuilder.wantAssertionsSigned(true); metadataConfigBuilder.assuranceLevel( authConfig.getBasicConfiguration( Constants.CONIG_PROPS_EIDAS_NODE_LoA, MOAIDAuthConstants.eIDAS_LOA_HIGH)); //must be set in request, because it could be different for every online-application //mcp.setSpType(SPType.DEFAULT_VALUE); metadataConfigBuilder.digestMethods(Constants.METADATA_ALLOWED_ALG_DIGIST); metadataConfigBuilder.signingMethods(Constants.METADATA_ALLOWED_ALG_SIGN); metadataConfigBuilder.encryptionAlgorithms(Constants.METADATA_ALLOWED_ALG_ENCRYPT); //add organisation information from PVP metadata information Organization pvpOrganisation = null; try { pvpOrganisation = pvpConfiguration.getIDPOrganisation(); eu.eidas.auth.engine.metadata.ContactData.Builder technicalContact = ContactData.builder(); List contacts = pvpConfiguration.getIDPContacts(); if (contacts != null && contacts.size() >= 1) { ContactPerson contact = contacts.get(0); technicalContact.givenName(contact.getGivenName().getName()); technicalContact.surName(contact.getSurName().getName()); if (!contact.getEmailAddresses().isEmpty()) technicalContact.email(contact.getEmailAddresses().get(0).getAddress()); if (!contact.getTelephoneNumbers().isEmpty()) technicalContact.phone(contact.getTelephoneNumbers().get(0).getNumber()); } if (pvpOrganisation != null) { eu.eidas.auth.engine.metadata.OrganizationData.Builder organizationConfig = OrganizationData.builder(); organizationConfig.url(pvpOrganisation.getURLs().get(0).getURL().getLocalString()); organizationConfig.name(authConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRY, "Austria")); //TODO: add display name and maybe update name metadataConfigBuilder.organization(organizationConfig.build()); technicalContact.company(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString()); } metadataConfigBuilder.technicalContact(technicalContact.build()); //TODO: add correct support contact metadataConfigBuilder.supportContact(ContactData.builder(technicalContact.build()).build()); } catch (NullPointerException | EAAFException e) { Logger.warn("Can not load Organisation or Contact from Configuration", e); } metadataConfigBuilder.idpEngine(engine); metadataConfigBuilder.spEngine(engine); //TODO: // MOAeIDASMetadataGenerator generator = new MOAeIDASMetadataGenerator(); // generator.initialize(engine); // generator.addSPRole(); // generator.addIDPRole(); // metadata = generator.generateMetadata(); //use own implementation that solves some problems in original implementation NewMoaEidasMetadata.Generator generator = NewMoaEidasMetadata.generator(); generator.configParams(metadataConfigBuilder.build()); NewMoaEidasMetadata eidasMetadata = generator.build(); metadata = eidasMetadata.getMetadata(); return metadata; } }