/******************************************************************************* * 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.protocols.pvp2x; import java.io.StringWriter; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.metadata.ContactPerson; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml2.metadata.KeyDescriptor; import org.opensaml.saml2.metadata.NameIDFormat; import org.opensaml.saml2.metadata.SingleSignOnService; 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.X509KeyInfoGeneratorFactory; import org.opensaml.xml.signature.Signature; import org.opensaml.xml.signature.Signer; import org.w3c.dom.Document; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; public class MetadataAction implements IAction { private static final int VALIDUNTIL_IN_HOURS = 24; public String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession moasession) throws MOAIDException { try { EntitiesDescriptor idpEntitiesDescriptor = SAML2Utils.createSAMLObject(EntitiesDescriptor.class); idpEntitiesDescriptor.setName(PVPConfiguration.getInstance().getIDPIssuerName()); idpEntitiesDescriptor.setID(SAML2Utils.getSecureIdentifier()); DateTime date = new DateTime(); idpEntitiesDescriptor.setValidUntil(date.plusHours(VALIDUNTIL_IN_HOURS)); EntityDescriptor idpEntityDescriptor = SAML2Utils .createSAMLObject(EntityDescriptor.class); idpEntitiesDescriptor.getEntityDescriptors().add(idpEntityDescriptor); //TODO: maybe change EntityID to Metadata URL //idpEntityDescriptor // .setEntityID(PVPConfiguration.getInstance().getIDPSSOMetadataService()); idpEntityDescriptor .setEntityID(PVPConfiguration.getInstance().getIDPPublicPath()); idpEntityDescriptor.setValidUntil(date.plusDays(VALIDUNTIL_IN_HOURS)); List persons = PVPConfiguration.getInstance() .getIDPContacts(); idpEntityDescriptor.getContactPersons().addAll(persons); idpEntityDescriptor.setOrganization(PVPConfiguration.getInstance() .getIDPOrganisation()); X509KeyInfoGeneratorFactory keyInfoFactory = new X509KeyInfoGeneratorFactory(); keyInfoFactory.setEmitPublicKeyValue(true); keyInfoFactory.setEmitEntityIDAsKeyName(true); keyInfoFactory.setEmitEntityCertificate(true); KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); Credential metadataSigningCredential = CredentialProvider.getIDPMetaDataSigningCredential(); Signature signature = CredentialProvider .getIDPSignature(metadataSigningCredential); idpEntitiesDescriptor.setSignature(signature); // //set SignatureMethode // signature.setSignatureAlgorithm(PVPConstants.DEFAULT_SIGNING_METHODE); // // //set DigestMethode // List contentList = signature.getContentReferences(); // for (ContentReference content : contentList) { // // if (content instanceof SAMLObjectContentReference) { // // SAMLObjectContentReference el = (SAMLObjectContentReference) content; // el.setDigestAlgorithm(PVPConstants.DEFAULT_DIGESTMETHODE); // // } // } // KeyInfoBuilder metadataKeyInfoBuilder = new KeyInfoBuilder(); // KeyInfo metadataKeyInfo = metadataKeyInfoBuilder.buildObject(); // //KeyInfoHelper.addCertificate(metadataKeyInfo, metadataSigningCredential.); // signature.setKeyInfo(metadataKeyInfo ); IDPSSODescriptor idpSSODescriptor = SAML2Utils .createSAMLObject(IDPSSODescriptor.class); idpSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); idpSSODescriptor.setWantAuthnRequestsSigned(true); if (PVPConfiguration.getInstance().getIDPSSOPostService() != null) { SingleSignOnService postSingleSignOnService = SAML2Utils .createSAMLObject(SingleSignOnService.class); postSingleSignOnService.setLocation(PVPConfiguration .getInstance().getIDPSSOPostService()); postSingleSignOnService .setBinding(SAMLConstants.SAML2_POST_BINDING_URI); idpSSODescriptor.getSingleSignOnServices().add( postSingleSignOnService); } if (PVPConfiguration.getInstance().getIDPSSORedirectService() != null) { SingleSignOnService redirectSingleSignOnService = SAML2Utils .createSAMLObject(SingleSignOnService.class); redirectSingleSignOnService.setLocation(PVPConfiguration .getInstance().getIDPSSORedirectService()); redirectSingleSignOnService .setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); idpSSODescriptor.getSingleSignOnServices().add( redirectSingleSignOnService); } /*if (PVPConfiguration.getInstance().getIDPResolveSOAPService() != null) { ArtifactResolutionService artifactResolutionService = SAML2Utils .createSAMLObject(ArtifactResolutionService.class); artifactResolutionService .setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); artifactResolutionService.setLocation(PVPConfiguration .getInstance().getIDPResolveSOAPService()); artifactResolutionService.setIndex(0); idpSSODescriptor.getArtifactResolutionServices().add( artifactResolutionService); }*/ //set assertion signing key Credential assertionSigingCredential = CredentialProvider .getIDPAssertionSigningCredential(); KeyDescriptor signKeyDescriptor = SAML2Utils .createSAMLObject(KeyDescriptor.class); signKeyDescriptor.setUse(UsageType.SIGNING); signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(assertionSigingCredential)); idpSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); idpSSODescriptor.getAttributes().addAll(PVPAttributeBuilder.buildSupportedEmptyAttributes()); NameIDFormat persistenNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); persistenNameIDFormat.setFormat(NameIDType.PERSISTENT); idpSSODescriptor.getNameIDFormats().add(persistenNameIDFormat); NameIDFormat transientNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); transientNameIDFormat.setFormat(NameIDType.TRANSIENT); idpSSODescriptor.getNameIDFormats().add(transientNameIDFormat); NameIDFormat unspecifiedNameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); unspecifiedNameIDFormat.setFormat(NameIDType.UNSPECIFIED); idpSSODescriptor.getNameIDFormats().add(unspecifiedNameIDFormat); idpEntityDescriptor.getRoleDescriptors().add(idpSSODescriptor); DocumentBuilder builder; DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Marshaller out = Configuration.getMarshallerFactory() .getMarshaller(idpEntitiesDescriptor); out.marshall(idpEntitiesDescriptor, document); Signer.signObject(signature); 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(); System.out.println("METADATA: " + metadataXML); httpResp.setContentType("text/xml"); httpResp.getOutputStream().write(metadataXML.getBytes()); httpResp.getOutputStream().close(); return null; } catch (Exception e) { Logger.error("Failed to generate metadata", e); throw new MOAIDException("pvp2.13", null); } } public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { return false; } public String getDefaultActionName() { return (PVP2XProtocol.METADATA); } }