package at.asitplus.eidas.specific.modules.auth.idaustria.controller; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.google.common.net.MediaType; import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants; import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthMetadataConfiguration; import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider; import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.http.HttpUtils; import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; import lombok.extern.slf4j.Slf4j; /** * Controller that generates SAML2 metadata for ID Austria authentication client. * * @author tlenz * */ @Slf4j @Controller public class IdAustriaAuthMetadataController extends AbstractController { private static final String ERROR_CODE_INTERNAL_00 = "eaaf.core.00"; @Autowired PvpMetadataBuilder metadatabuilder; @Autowired IdAustriaAuthCredentialProvider credentialProvider; @Autowired IPvp2BasicConfiguration pvpConfiguration; /** * Default construction with logging. * */ public IdAustriaAuthMetadataController() { super(); log.debug("Registering servlet " + getClass().getName() + " with mappings '" + IdAustriaAuthConstants.ENDPOINT_METADATA + "'."); } /** * End-point that produce PVP2 metadata for ID Austria authentication client. * * @param req http Request * @param resp http Response * @throws IOException In case of an I/O error * @throws EaafException In case of a metadata generation error */ @RequestMapping(value = IdAustriaAuthConstants.ENDPOINT_METADATA, method = { RequestMethod.GET }) public void getSpMetadata(HttpServletRequest req, HttpServletResponse resp) throws IOException, EaafException { // check PublicURL prefix try { final String authUrl = getAuthUrlFromHttpContext(req); // initialize metadata builder configuration final IdAustriaAuthMetadataConfiguration metadataConfig = new IdAustriaAuthMetadataConfiguration(authUrl, credentialProvider, pvpConfiguration); metadataConfig.setAdditionalRequiredAttributes(getAdditonalRequiredAttributes()); // build metadata final String xmlMetadata = metadatabuilder.buildPvpMetadata(metadataConfig); // write response final byte[] content = xmlMetadata.getBytes("UTF-8"); resp.setStatus(HttpServletResponse.SC_OK); resp.setContentLength(content.length); resp.setContentType(MediaType.XML_UTF_8.toString()); resp.getOutputStream().write(content); } catch (final Exception e) { log.warn("Build PVP metadata for ID Austria client FAILED.", e); protAuthService.handleErrorNoRedirect(e, req, resp, false); } } private String getAuthUrlFromHttpContext(HttpServletRequest req) throws EaafException { // check if End-Point is valid final String authUrlString = HttpUtils.extractAuthUrlFromRequest(req); URL authReqUrl; try { authReqUrl = new URL(authUrlString); } catch (final MalformedURLException e) { log.warn("Requested URL: {} is not a valid URL.", authUrlString); throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString }, e); } final String idpAuthUrl = authConfig.validateIdpUrl(authReqUrl); if (idpAuthUrl == null) { log.warn("Requested URL: {} is NOT found in configuration.", authReqUrl); throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString }); } return idpAuthUrl; } private List> getAdditonalRequiredAttributes() { final List> result = new ArrayList<>(); // load attributes from configuration final Map addReqAttributes = authConfig.getBasicConfigurationWithPrefix( IdAustriaAuthConstants.CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST); for (final String el : addReqAttributes.values()) { if (StringUtils.isNotEmpty(el)) { log.trace("Parse additional attr. definition: " + el); final List attr = KeyValueUtils.getListOfCsvValues(el.trim()); if (attr.size() == 2) { result.add(Pair.newInstance(attr.get(0), Boolean.parseBoolean(attr.get(1)))); } else { log.info("IGNORE additional attr. definition: " + el + " Reason: Format not valid"); } } } return result; } }