at.gv.egovernment.moa.id.protocols.pvp2x.MetadataAction.java Source code

Java tutorial

Introduction

Here is the source code for at.gv.egovernment.moa.id.protocols.pvp2x.MetadataAction.java

Source

/*******************************************************************************
 * 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.AssertionConsumerService;
import org.opensaml.saml2.metadata.AttributeConsumingService;
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.LocalizedString;
import org.opensaml.saml2.metadata.NameIDFormat;
import org.opensaml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.saml2.metadata.ServiceName;
import org.opensaml.saml2.metadata.SingleLogoutService;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.SecurityHelper;
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.X509Credential;
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.exception.MOAIDException;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
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.signer.CredentialsNotAvailableException;
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 SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq,
            HttpServletResponse httpResp, IAuthData authData) 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<ContactPerson> 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);

            //set KeyInfo Element
            SecurityHelper.prepareSignatureParams(signature, metadataSigningCredential, null, null);

            idpEntitiesDescriptor.setSignature(signature);

            //set IDP metadata
            idpEntityDescriptor.getRoleDescriptors().add(generateIDPMetadata(keyInfoGenerator));

            //set SP metadata for interfederation
            idpEntityDescriptor.getRoleDescriptors().add(generateSPMetadata(keyInfoGenerator));

            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();
            Logger.debug("METADATA: " + metadataXML);

            httpResp.setContentType("text/xml");
            httpResp.getOutputStream().write(metadataXML.getBytes("UTF-8"));

            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);
    }

    private RoleDescriptor generateSPMetadata(KeyInfoGenerator keyInfoGenerator)
            throws CredentialsNotAvailableException, SecurityException, ConfigurationException {

        Logger.debug("Set SP Metadata key information");

        SPSSODescriptor spSSODescriptor = SAML2Utils.createSAMLObject(SPSSODescriptor.class);

        spSSODescriptor.setAuthnRequestsSigned(true);
        spSSODescriptor.setWantAssertionsSigned(false);

        //Set AuthRequest Signing certificate
        X509Credential authcredential = CredentialProvider.getIDPAssertionSigningCredential();

        KeyDescriptor signKeyDescriptor = SAML2Utils.createSAMLObject(KeyDescriptor.class);
        signKeyDescriptor.setUse(UsageType.SIGNING);
        signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential));
        spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor);

        //set AuthRequest encryption certificate

        X509Credential authEncCredential = CredentialProvider.getIDPAssertionEncryptionCredential();

        if (authEncCredential != null) {
            KeyDescriptor encryKeyDescriptor = SAML2Utils.createSAMLObject(KeyDescriptor.class);
            encryKeyDescriptor.setUse(UsageType.ENCRYPTION);
            encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential));
            spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor);

        } else {
            Logger.warn("No Assertion Encryption-Key defined. This setting is not recommended!");

        }

        NameIDFormat persistentnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class);
        persistentnameIDFormat.setFormat(NameIDType.PERSISTENT);

        spSSODescriptor.getNameIDFormats().add(persistentnameIDFormat);

        NameIDFormat transientnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class);
        transientnameIDFormat.setFormat(NameIDType.TRANSIENT);

        spSSODescriptor.getNameIDFormats().add(transientnameIDFormat);

        NameIDFormat unspecifiednameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class);
        unspecifiednameIDFormat.setFormat(NameIDType.UNSPECIFIED);

        spSSODescriptor.getNameIDFormats().add(unspecifiednameIDFormat);

        //add assertion consumer services
        AssertionConsumerService postassertionConsumerService = SAML2Utils
                .createSAMLObject(AssertionConsumerService.class);
        postassertionConsumerService.setIndex(0);
        postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
        postassertionConsumerService.setLocation(PVPConfiguration.getInstance().getSPSSOPostService());
        postassertionConsumerService.setIsDefault(true);
        spSSODescriptor.getAssertionConsumerServices().add(postassertionConsumerService);

        AssertionConsumerService redirectassertionConsumerService = SAML2Utils
                .createSAMLObject(AssertionConsumerService.class);
        redirectassertionConsumerService.setIndex(1);
        redirectassertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
        redirectassertionConsumerService.setLocation(PVPConfiguration.getInstance().getSPSSORedirectService());
        spSSODescriptor.getAssertionConsumerServices().add(redirectassertionConsumerService);

        //add SLO descriptor
        //      SingleLogoutService postSLOService = 
        //            SAML2Utils.createSAMLObject(SingleLogoutService.class);         
        //      postSLOService.setLocation(PVPConfiguration
        //            .getInstance().getIDPSSOPostService());
        //      postSLOService
        //            .setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
        //      spSSODescriptor.getSingleLogoutServices().add(postSLOService);

        SingleLogoutService redirectSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class);
        redirectSLOService.setLocation(PVPConfiguration.getInstance().getSPSSORedirectService());
        redirectSLOService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
        spSSODescriptor.getSingleLogoutServices().add(redirectSLOService);

        spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS);

        AttributeConsumingService attributeService = SAML2Utils.createSAMLObject(AttributeConsumingService.class);

        attributeService.setIndex(0);
        attributeService.setIsDefault(true);
        ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class);
        serviceName.setName(new LocalizedString("Default Service", "de"));
        attributeService.getNames().add(serviceName);

        return spSSODescriptor;
    }

    private IDPSSODescriptor generateIDPMetadata(KeyInfoGenerator keyInfoGenerator)
            throws ConfigurationException, CredentialsNotAvailableException, SecurityException {

        //      //set SignatureMethode
        //      signature.setSignatureAlgorithm(PVPConstants.DEFAULT_SIGNING_METHODE);
        //      
        //      //set DigestMethode
        //      List<ContentReference> 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) {
            //add SSO descriptor
            SingleSignOnService postSingleSignOnService = SAML2Utils.createSAMLObject(SingleSignOnService.class);
            postSingleSignOnService.setLocation(PVPConfiguration.getInstance().getIDPSSOPostService());
            postSingleSignOnService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
            idpSSODescriptor.getSingleSignOnServices().add(postSingleSignOnService);

            //add SLO descriptor
            //         SingleLogoutService postSLOService = 
            //               SAML2Utils.createSAMLObject(SingleLogoutService.class);         
            //         postSLOService.setLocation(PVPConfiguration
            //               .getInstance().getIDPSSOPostService());
            //         postSLOService
            //               .setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
            //         idpSSODescriptor.getSingleLogoutServices().add(postSLOService);

        }

        if (PVPConfiguration.getInstance().getIDPSSORedirectService() != null) {
            //add SSO descriptor
            SingleSignOnService redirectSingleSignOnService = SAML2Utils
                    .createSAMLObject(SingleSignOnService.class);
            redirectSingleSignOnService.setLocation(PVPConfiguration.getInstance().getIDPSSORedirectService());
            redirectSingleSignOnService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
            idpSSODescriptor.getSingleSignOnServices().add(redirectSingleSignOnService);

            //add SLO descriptor
            SingleLogoutService redirectSLOService = SAML2Utils.createSAMLObject(SingleLogoutService.class);
            redirectSLOService.setLocation(PVPConfiguration.getInstance().getIDPSSORedirectService());
            redirectSLOService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
            idpSSODescriptor.getSingleLogoutServices().add(redirectSLOService);
        }

        /*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);

        return idpSSODescriptor;

    }

}