at.gv.egovernment.moa.id.configuration.auth.pvp2.servlets.Authenticate.java Source code

Java tutorial

Introduction

Here is the source code for at.gv.egovernment.moa.id.configuration.auth.pvp2.servlets.Authenticate.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.configuration.auth.pvp2.servlets;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.NameIDPolicy;
import org.opensaml.saml2.core.NameIDType;
import org.opensaml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.security.x509.X509Credential;
import org.opensaml.xml.signature.AbstractSignableXMLObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import at.gv.egovernment.moa.id.configuration.Constants;
import at.gv.egovernment.moa.id.configuration.auth.pvp2.PVP2Utils;
import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider;
import at.gv.egovernment.moa.id.configuration.exception.ConfigurationException;
import at.gv.egovernment.moa.id.configuration.utils.SAML2Utils;
import at.gv.egovernment.moa.util.MiscUtil;

/**
 * Servlet implementation class Authenticate
 */
public class Authenticate extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static final Logger log = LoggerFactory.getLogger(Authenticate.class);

    private static DocumentBuilderFactory factory = null;

    static {
        initialDocumentBuilderFactory();
    }

    synchronized private static void initialDocumentBuilderFactory() {
        factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);

    }

    public Document asDOMDocument(XMLObject object)
            throws IOException, MarshallingException, TransformerException, ParserConfigurationException {
        try {
            DocumentBuilder builder = null;
            synchronized (factory) {
                builder = factory.newDocumentBuilder();

            }

            Document document = builder.newDocument();
            Marshaller out = Configuration.getMarshallerFactory().getMarshaller(object);
            out.marshall(object, document);
            return document;

        } catch (ParserConfigurationException e) {
            log.warn("PVP2 AuthenticationServlet can not be initialized.", e);
            throw e;
        }

    }

    protected void process(HttpServletRequest request, HttpServletResponse response,
            Map<String, String> legacyParameter) throws ServletException, IOException {
        try {

            ConfigurationProvider config = ConfigurationProvider.getInstance();
            config.initializePVP2Login();

            AuthnRequest authReq = SAML2Utils.createSAMLObject(AuthnRequest.class);
            SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
            authReq.setID(gen.generateIdentifier());

            HttpSession session = request.getSession();
            if (session != null) {
                session.setAttribute(Constants.SESSION_PVP2REQUESTID, authReq.getID());
            }

            authReq.setAssertionConsumerServiceIndex(0);
            authReq.setAttributeConsumingServiceIndex(0);
            authReq.setIssueInstant(new DateTime());
            Subject subject = SAML2Utils.createSAMLObject(Subject.class);
            NameID name = SAML2Utils.createSAMLObject(NameID.class);
            Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);

            String serviceURL = config.getPublicUrlPreFix(request);
            if (!serviceURL.endsWith("/"))
                serviceURL = serviceURL + "/";
            name.setValue(serviceURL);
            issuer.setValue(serviceURL);

            subject.setNameID(name);
            authReq.setSubject(subject);
            issuer.setFormat(NameIDType.ENTITY);
            authReq.setIssuer(issuer);
            NameIDPolicy policy = SAML2Utils.createSAMLObject(NameIDPolicy.class);
            policy.setAllowCreate(true);
            policy.setFormat(NameID.PERSISTENT);
            authReq.setNameIDPolicy(policy);

            String entityname = config.getPVP2IDPMetadataEntityName();
            if (MiscUtil.isEmpty(entityname)) {
                log.info("No IDP EntityName configurated");
                throw new ConfigurationException("No IDP EntityName configurated");
            }

            HTTPMetadataProvider idpmetadata = config.getMetaDataProvier();
            EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname);
            if (idpEntity == null) {
                log.info("IDP EntityName is not found in IDP Metadata");
                throw new ConfigurationException("IDP EntityName is not found in IDP Metadata");
            }

            SingleSignOnService redirectEndpoint = null;
            for (SingleSignOnService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS)
                    .getSingleSignOnServices()) {

                //Get the service address for the binding you wish to use
                if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
                    redirectEndpoint = sss;
                }
            }

            authReq.setDestination(redirectEndpoint.getLocation());

            RequestedAuthnContext reqAuthContext = SAML2Utils.createSAMLObject(RequestedAuthnContext.class);

            AuthnContextClassRef authnClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class);

            authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4");

            reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);

            reqAuthContext.getAuthnContextClassRefs().add(authnClassRef);

            authReq.setRequestedAuthnContext(reqAuthContext);

            //sign Message
            X509Credential authcredential = PVP2Utils.signMessage((AbstractSignableXMLObject) authReq, config);

            //encode message
            PVP2Utils.postBindingEncoder(request, response, authReq, authcredential, redirectEndpoint.getLocation(),
                    null);

        } catch (Exception e) {
            log.warn("Authentication Request can not be generated", e);
            throw new ServletException("Authentication Request can not be generated.", e);
        }
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        process(request, response, null);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        process(request, response, null);
    }

}