org.aselect.server.request.handler.xsaml20.Saml20_Metadata.java Source code

Java tutorial

Introduction

Here is the source code for org.aselect.server.request.handler.xsaml20.Saml20_Metadata.java

Source

/*
 * * Copyright (c) Anoigo. All rights reserved.
 *
 * A-Select is a trademark registered by SURFnet bv.
 *
 * This program is distributed under the EUPL 1.0 (http://osor.eu/eupl)
 * See the included LICENSE file for details.
 *
 * If you did not receive a copy of the LICENSE
 * please contact Anoigo. (http://www.anoigo.nl) 
 */
package org.aselect.server.request.handler.xsaml20;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.KeyStore;
import java.util.Enumeration;
import java.util.logging.Level;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.aselect.server.config.ASelectConfigManager;
import org.aselect.server.request.RequestState;
import org.aselect.server.request.handler.ProtoRequestHandler;
import org.aselect.system.error.Errors;
import org.aselect.system.exception.ASelectConfigException;
import org.aselect.system.exception.ASelectException;
import org.aselect.system.utils.Utils;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObjectBuilderFactory;

public class Saml20_Metadata extends ProtoRequestHandler {
    private final static String MODULE = "Saml20_Metadata";

    public final static String PUBLIC_KEYSTORE_NAME = "aselect.keystore";
    public final static String singleSignOnServiceBindingConstantREDIRECT = SAMLConstants.SAML2_REDIRECT_BINDING_URI;
    public final static String singleSignOnServiceBindingConstantPOST = SAMLConstants.SAML2_POST_BINDING_URI;
    public final static String artifactResolutionServiceBindingConstantSOAP = SAMLConstants.SAML2_SOAP11_BINDING_URI;
    public final static String assertionConsumerServiceBindingConstantARTIFACT = SAMLConstants.SAML2_ARTIFACT_BINDING_URI;
    public final static String singleLogoutServiceBindingConstantREDIRECT = SAMLConstants.SAML2_REDIRECT_BINDING_URI;
    public final static String singleLogoutServiceBindingConstantSOAP = SAMLConstants.SAML2_SOAP11_BINDING_URI;
    public final static String authzServiceBindingConstantSOAP = SAMLConstants.SAML2_SOAP11_BINDING_URI;

    private String workingDir = null;
    private String redirectURL;
    private String signingCertificate;
    private String publicKeyAlias;
    private String entityIdIdp;

    private Long validUntil = null; // validity period after now() of metadata (seconds)
    private Long cacheDuration = null; // advised period (in seconds) for peer to keep metadata in cache

    // SP
    private String assertionConsumerTarget = "";

    private String spSloHttpLocation = null;
    private String spSloHttpResponse = null;
    private String spSloSoapLocation = null;
    private String spSloSoapResponse = null;

    // IdP
    private String idpSsoUrl = "";
    private String idpArtifactResolverUrl = "";
    private String idpSloSoapRequestUrl = "";
    private String idpSloSoapResponseUrl = "";
    private String idpSloHttpRequestUrl = "";
    private String idpSloHttpResponseUrl = "";
    private String idpSyncUrl = "";

    private String singleSignOnServiceTarget = "";
    private String artifactResolverTarget = "";
    private String idpSloSoapLocation = null;
    private String idpSloSoapResponse = null;
    private String idpSloHttpLocation = null;
    private String idpSloHttpResponse = null;
    private String idpSSSoapLocation = null;

    protected XMLObjectBuilderFactory _oBuilderFactory;

    /* (non-Javadoc)
     * @see org.aselect.server.request.handler.ProtoRequestHandler#init(javax.servlet.ServletConfig, java.lang.Object)
     */
    @Override
    public void init(ServletConfig oServletConfig, Object oConfig) throws ASelectException {
        String sMethod = "init";

        try {
            super.init(oServletConfig, oConfig);
            try {
                _systemLogger.log(Level.INFO, MODULE, sMethod, "Saml Bootstrap");
                DefaultBootstrap.bootstrap();
            } catch (ConfigurationException e) {
                _systemLogger.log(Level.WARNING, MODULE, sMethod, "OpenSAML library could not be initialized", e);
                throw new ASelectException(Errors.ERROR_ASELECT_INIT_ERROR, e);
            }
            _systemLogger.log(Level.FINEST, MODULE, sMethod, "Bootstrap done");
            _oBuilderFactory = org.opensaml.xml.Configuration.getBuilderFactory();

            setWorkingDir(oServletConfig.getInitParameter("working_dir")); // from web.xml!
            _systemLogger.log(Level.FINEST, MODULE, sMethod, "Working directory: " + getWorkingDir());

            Object oASelect = null;
            try {
                oASelect = _configManager.getSection(null, "aselect");
                setRedirectURL(_configManager.getParam(oASelect, "redirect_url"));
                // redirect_url will be used as entityIdIdp in metadata
                setEntityIdIdp(_configManager.getParam(oASelect, "redirect_url"));

                String sValidUntil = ASelectConfigManager.getSimpleParam(oConfig, "valid_until", false);
                if (sValidUntil != null) {
                    setValidUntil(new Long(Long.parseLong(sValidUntil) * 1000));
                }
                String sCacheDuration = ASelectConfigManager.getSimpleParam(oConfig, "cache_duration", false);
                if (sCacheDuration != null) {
                    setCacheDuration(new Long(Long.parseLong(sCacheDuration) * 1000));
                }
            } catch (ASelectConfigException e) {
                _systemLogger.log(Level.WARNING, MODULE, sMethod,
                        "No config item 'redirect_url' in section 'aselect' found", e);
                throw new ASelectException(Errors.ERROR_ASELECT_INIT_ERROR, e);
            }
        } catch (ASelectException e) {
            throw e;
        } catch (Exception e) {
            _systemLogger.log(Level.SEVERE, MODULE, sMethod, "Could not initialize", e);
            throw new ASelectException(Errors.ERROR_ASELECT_INTERNAL_ERROR, e);
        }
    }

    /**
     * Read meta data public key cert.
     * 
     * @param sWorkingDir
     *            the s working dir
     * @throws ASelectException
     *             the a select exception
     */
    private void readMetaDataPublicKeyCert(String sWorkingDir) throws ASelectException {
        String sMethod = "readMetaDataPublicKeyCert";

        try {
            StringBuffer sbKeystoreLocation = new StringBuffer(sWorkingDir);
            sbKeystoreLocation.append(File.separator);
            sbKeystoreLocation.append("aselectserver");
            sbKeystoreLocation.append(File.separator);
            sbKeystoreLocation.append("keystores");
            sbKeystoreLocation.append(File.separator);
            sbKeystoreLocation.append(PUBLIC_KEYSTORE_NAME);
            _systemLogger.log(Level.INFO, MODULE, sMethod, "Read:" + sbKeystoreLocation);

            File fKeystore = new File(sbKeystoreLocation.toString());
            if (!fKeystore.exists()) {
                StringBuffer sbError = new StringBuffer("Keystore cannot be found: ");
                sbError.append(sbKeystoreLocation.toString());
                _systemLogger.log(Level.WARNING, MODULE, sMethod, sbError.toString());
                throw new ASelectException(Errors.ERROR_ASELECT_NOT_FOUND);
            }

            KeyStore ksASelect = KeyStore.getInstance("JKS");
            ksASelect.load(new FileInputStream(sbKeystoreLocation.toString()), null);

            Enumeration<?> enumAliases = ksASelect.aliases();
            while (enumAliases.hasMoreElements()) {
                String sAlias = (String) enumAliases.nextElement();

                sAlias = sAlias.toLowerCase();
                if (sAlias.equals(getPublicKeyAlias())) { // server_id A-Select IdP
                    java.security.cert.X509Certificate x509Cert = (java.security.cert.X509Certificate) ksASelect
                            .getCertificate(sAlias);

                    String encodedCert = new String(Base64.encodeBase64(x509Cert.getEncoded()));
                    _systemLogger.log(Level.INFO, MODULE, sMethod, "Found public key alias for : "
                            + getPublicKeyAlias() + " retrieved encoded signing certificate");
                    setSigningCertificate(encodedCert);
                }
            }
            if (getSigningCertificate() == null) {
                _systemLogger.log(Level.WARNING, MODULE, sMethod,
                        "No alias found for idp public key with name : " + getPublicKeyAlias());
                throw new ASelectException(Errors.ERROR_ASELECT_CONFIG_ERROR);
            }
        } catch (Exception e) {
            StringBuffer sbError = new StringBuffer(" Error loading public keys from directory: '");
            sbError.append(sWorkingDir);
            sbError.append("'");
            _systemLogger.log(Level.WARNING, MODULE, sMethod, sbError.toString(), e);
            throw new ASelectException(Errors.ERROR_ASELECT_INTERNAL_ERROR, e);
        }
    }

    // Override this method!
    /**
     * Aselect reader.
     * Will read all non-handler specific config parameters for metadata request
     * 
     * @throws ASelectException
     *             the a select exception
     */
    protected void aselectReader() throws ASelectException {
        // setSingleLogoutServiceTarget(getRedirectURL()); // We use redirect_url for now
        setPublicKeyAlias(get_sASelectServerID());
        // Use server_id from aselect configuration (aselect.xml) as public key alias
    }

    /**
     * Handle meta data request.
     * 
     * @param servletRequest
     *            the http request
     * @param servletResponse
     *            the http response
     * @throws ASelectException
     *             the a select exception
     */
    private void handleMetaDataRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
            throws ASelectException {
        String sMethod = "handleMetaDataRequest";

        // 20100429, Bauke: the caller can replace the default EntityID by the specified partner's <issuer>
        String remoteID = servletRequest.getParameter("id");

        // remoteID can be null
        String mdxml = createMetaDataXML(remoteID); // RH, 20110111, n

        _systemLogger.log(Level.INFO, MODULE, sMethod,
                "metadatXML file for entityID " + getEntityIdIdp() + " " + mdxml);
        PrintWriter pwOut = null;
        try {
            pwOut = Utils.prepareForHtmlOutput(servletRequest, servletResponse, "application/samlmetadata+xml");
            pwOut.println(mdxml);
            pwOut.flush();
            pwOut.close();
        } catch (IOException e) {
            _systemLogger.log(Level.WARNING, MODULE, sMethod, "Could not handle the request", e);
            throw new ASelectException(Errors.ERROR_ASELECT_INTERNAL_ERROR, e);
        }
    }

    /**
     * Creates the meta data xml.
     * @param the remoteID
     *       The remote identity for whom to create the metadata. If null a default metadata xml will be created
     * @return the string
     * @throws ASelectException
     *             the a select exception
     */
    //   protected String createMetaDataXML(String localIssuer)
    protected String createMetaDataXML(String remoteID) throws ASelectException {
        String sMethod = "createMetaDataXML";
        String error = "This method should NOT be called directly but must be overridden!";
        _systemLogger.log(Level.SEVERE, MODULE, sMethod, error);
        throw new ASelectException(Errors.ERROR_ASELECT_INTERNAL_ERROR);
    }

    /* (non-Javadoc)
     * @see org.aselect.server.request.handler.IRequestHandler#process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public RequestState process(HttpServletRequest request, HttpServletResponse response) throws ASelectException {
        String sMethod = "process";
        try {
            // These method calls could be made more transparent
            // all kind of things get set that we don't know off
            aselectReader(); // among other things this sets the publicKeyAlias
            readMetaDataPublicKeyCert(getWorkingDir()); // This sets the signing certificate using the publicKeyAlias
            handleMetaDataRequest(request, response);
        } catch (Exception e) {
            _systemLogger.log(Level.SEVERE, MODULE, sMethod, "Could not process", e);
            throw new ASelectException(Errors.ERROR_ASELECT_INTERNAL_ERROR, e);
        }
        return new RequestState(null);
    }

    /**
     * Gets the entity id idp.
     * 
     * @return the entity id idp
     */
    public synchronized String getEntityIdIdp() {
        return entityIdIdp;
    }

    /**
     * Sets the entity id idp.
     * 
     * @param entityIdIdp
     *            the new entity id idp
     */
    public synchronized void setEntityIdIdp(String entityIdIdp) {
        this.entityIdIdp = entityIdIdp;
    }

    /**
     * Gets the sp slo soap location.
     * 
     * @return the sp slo soap location
     */
    public synchronized String getSpSloSoapLocation() {
        return spSloSoapLocation;
    }

    /**
     * Sets the sp slo soap location.
     * 
     * @param logoutServiceLocation
     *            the new sp slo soap location
     */
    public synchronized void setSpSloSoapLocation(String logoutServiceLocation) {
        spSloSoapLocation = logoutServiceLocation;
    }

    /**
     * Gets the artifact resolver target.
     * 
     * @return the artifact resolver target
     */
    public synchronized String getArtifactResolverTarget() {
        return artifactResolverTarget;
    }

    /**
     * Sets the artifact resolver target.
     * 
     * @param target
     *            the new artifact resolver target
     */
    public synchronized void setArtifactResolverTarget(String target) {
        artifactResolverTarget = target;
    }

    /**
     * Gets the redirect url.
     * 
     * @return the redirect url
     */
    public synchronized String getRedirectURL() {
        return redirectURL;
    }

    /**
     * Sets the redirect url.
     * 
     * @param _redirecturl
     *            the new redirect url
     */
    public synchronized void setRedirectURL(String _redirecturl) {
        redirectURL = _redirecturl;
    }

    /**
     * Gets the working dir.
     * 
     * @return the working dir
     */
    public synchronized String getWorkingDir() {
        return workingDir;
    }

    /**
     * Sets the working dir.
     * 
     * @param workingDir
     *            the new working dir
     */
    public synchronized void setWorkingDir(String workingDir) {
        this.workingDir = workingDir;
    }

    /**
     * Gets the signing certificate.
     * 
     * @return the signing certificate
     */
    public synchronized String getSigningCertificate() {
        return signingCertificate;
    }

    /**
     * Sets the signing certificate.
     * 
     * @param certificate
     *            the new signing certificate
     */
    public synchronized void setSigningCertificate(String certificate) {
        signingCertificate = certificate;
    }

    /**
     * Gets the public key alias.
     * 
     * @return the public key alias
     */
    public synchronized String getPublicKeyAlias() {
        return publicKeyAlias;
    }

    /**
     * Sets the public key alias.
     * 
     * @param keyAlias
     *            the new public key alias
     */
    public synchronized void setPublicKeyAlias(String keyAlias) {
        publicKeyAlias = keyAlias;
    }

    /**
     * Gets the idp slo soap location.
     * 
     * @return the idp slo soap location
     */
    public synchronized String getIdpSloSoapLocation() {
        return idpSloSoapLocation;
    }

    /**
     * Sets the idp slo soap location.
     * 
     * @param logoutRequestTarget
     *            the new idp slo soap location
     */
    public synchronized void setIdpSloSoapLocation(String logoutRequestTarget) {
        idpSloSoapLocation = logoutRequestTarget;
    }

    /**
     * Gets the sp slo http location.
     * 
     * @return the sp slo http location
     */
    public synchronized String getSpSloHttpLocation() {
        _systemLogger.log(Level.INFO, MODULE, "getSpSloHttpLocation", "Get " + spSloHttpLocation);
        return spSloHttpLocation;
    }

    /**
     * Sets the sp slo http location.
     * 
     * @param singleLogoutTarget
     *            the new sp slo http location
     */
    public synchronized void setSpSloHttpLocation(String singleLogoutTarget) {
        _systemLogger.log(Level.INFO, MODULE, "setSpSloHttpLocation", "Set " + singleLogoutTarget);
        this.spSloHttpLocation = singleLogoutTarget;
    }

    /**
     * Gets the assertion consumer target.
     * 
     * @return the assertion consumer target
     */
    public synchronized String getAssertionConsumerTarget() {
        _systemLogger.log(Level.INFO, MODULE, "getAssertionConsumerTarget", "Get " + assertionConsumerTarget);
        return assertionConsumerTarget;
    }

    /**
     * Sets the assertion consumer target.
     * 
     * @param assertionConsumerLocation
     *            the new assertion consumer target
     */
    public synchronized void setAssertionConsumerTarget(String assertionConsumerLocation) {
        _systemLogger.log(Level.INFO, MODULE, "setAssertionConsumerTarget", "Set " + assertionConsumerLocation);
        this.assertionConsumerTarget = assertionConsumerLocation;
    }

    /**
     * Gets the single sign on service target.
     * 
     * @return the single sign on service target
     */
    public synchronized String getSingleSignOnServiceTarget() {
        return singleSignOnServiceTarget;
    }

    /**
     * Sets the single sign on service target.
     * 
     * @param signOnServiceLocation
     *            the new single sign on service target
     */
    public synchronized void setSingleSignOnServiceTarget(String signOnServiceLocation) {
        singleSignOnServiceTarget = signOnServiceLocation;
    }

    /**
     * Gets the idp slo http location.
     * 
     * @return the idp slo http location
     */
    public synchronized String getIdpSloHttpLocation() {
        return idpSloHttpLocation;
    }

    /**
     * Sets the idp slo http location.
     * 
     * @param sloTarget
     *            the new idp slo http location
     */
    public synchronized void setIdpSloHttpLocation(String sloTarget) {
        this.idpSloHttpLocation = sloTarget;
    }

    /**
     * Gets the idp slo http response.
     * 
     * @return the idp slo http response
     */
    public synchronized String getIdpSloHttpResponse() {
        return idpSloHttpResponse;
    }

    /**
     * Sets the idp slo http response.
     * 
     * @param idpSloHttpResponse
     *            the new idp slo http response
     */
    public synchronized void setIdpSloHttpResponse(String idpSloHttpResponse) {
        this.idpSloHttpResponse = idpSloHttpResponse;
    }

    /**
     * Gets the idp slo soap response.
     * 
     * @return the idp slo soap response
     */
    public String getIdpSloSoapResponse() {
        return idpSloSoapResponse;
    }

    /**
     * Sets the idp slo soap response.
     * 
     * @param idpSloSoapResponse
     *            the new idp slo soap response
     */
    public void setIdpSloSoapResponse(String idpSloSoapResponse) {
        this.idpSloSoapResponse = idpSloSoapResponse;
    }

    /**
     * Gets the sp slo soap response.
     * 
     * @return the sp slo soap response
     */
    public String getSpSloSoapResponse() {
        return spSloSoapResponse;
    }

    /**
     * Sets the sp slo soap response.
     * 
     * @param spSloSoapResponse
     *            the new sp slo soap response
     */
    public void setSpSloSoapResponse(String spSloSoapResponse) {
        this.spSloSoapResponse = spSloSoapResponse;
    }

    /**
     * Gets the sp slo http response.
     * 
     * @return the sp slo http response
     */
    public String getSpSloHttpResponse() {
        _systemLogger.log(Level.INFO, MODULE, "getSpSloHttpResponse", "Get " + spSloHttpResponse);
        return spSloHttpResponse;
    }

    /**
     * Sets the sp slo http response.
     * 
     * @param spSloHttpResponse
     *            the new sp slo http response
     */
    public void setSpSloHttpResponse(String spSloHttpResponse) {
        _systemLogger.log(Level.INFO, MODULE, "setSpSloHttpResponse", "Set " + spSloHttpResponse);
        this.spSloHttpResponse = spSloHttpResponse;
    }

    /**
     * Gets the idp ss soap location.
     * 
     * @return the idp ss soap location
     */
    public synchronized String getIdpSSSoapLocation() {
        return idpSSSoapLocation;
    }

    /**
     * Sets the idp ss soap location.
     * 
     * @param idpSSSoapLocation
     *            the new idp ss soap location
     */
    public synchronized void setIdpSSSoapLocation(String idpSSSoapLocation) {
        this.idpSSSoapLocation = idpSSSoapLocation;
    }

    /**
     * Gets the valid until.
     * 
     * @return the valid until
     */
    public synchronized Long getValidUntil() {
        return validUntil;
    }

    /**
     * Sets the valid until.
     * 
     * @param validUntil
     *            the new valid until
     */
    public synchronized void setValidUntil(Long validUntil) {
        this.validUntil = validUntil;
    }

    /**
     * Gets the cache duration.
     * 
     * @return the cache duration
     */
    public synchronized Long getCacheDuration() {
        return cacheDuration;
    }

    /**
     * Sets the cache duration.
     * 
     * @param cacheDuration
     *            the new cache duration
     */
    public synchronized void setCacheDuration(Long cacheDuration) {
        this.cacheDuration = cacheDuration;
    }

    /**
     * Gets the idp artifact resolver url.
     * 
     * @return the idp artifact resolver url
     */
    public String getIdpArtifactResolverUrl() {
        return idpArtifactResolverUrl;
    }

    /**
     * Sets the idp artifact resolver url.
     * 
     * @param idpArtifactResolverUrl
     *            the new idp artifact resolver url
     */
    public void setIdpArtifactResolverUrl(String idpArtifactResolverUrl) {
        this.idpArtifactResolverUrl = idpArtifactResolverUrl;
    }

    /**
     * Gets the idp slo http request url.
     * 
     * @return the idp slo http request url
     */
    public String getIdpSloHttpRequestUrl() {
        return idpSloHttpRequestUrl;
    }

    /**
     * Sets the idp slo http request url.
     * 
     * @param idpSloHttpUrl
     *            the new idp slo http request url
     */
    public void setIdpSloHttpRequestUrl(String idpSloHttpUrl) {
        this.idpSloHttpRequestUrl = idpSloHttpUrl;
    }

    /**
     * Gets the idp slo soap request url.
     * 
     * @return the idp slo soap request url
     */
    public String getIdpSloSoapRequestUrl() {
        return idpSloSoapRequestUrl;
    }

    /**
     * Sets the idp slo soap request url.
     * 
     * @param idpSloSoapUrl
     *            the new idp slo soap request url
     */
    public void setIdpSloSoapRequestUrl(String idpSloSoapUrl) {
        this.idpSloSoapRequestUrl = idpSloSoapUrl;
    }

    /**
     * Gets the idp sso url.
     * 
     * @return the idp sso url
     */
    public String getIdpSsoUrl() {
        return idpSsoUrl;
    }

    /**
     * Sets the idp sso url.
     * 
     * @param idpSsoUrl
     *            the new idp sso url
     */
    public void setIdpSsoUrl(String idpSsoUrl) {
        this.idpSsoUrl = idpSsoUrl;
    }

    /**
     * Gets the idp sync url.
     * 
     * @return the idp sync url
     */
    public String getIdpSyncUrl() {
        return idpSyncUrl;
    }

    /**
     * Sets the idp sync url.
     * 
     * @param idpSyncUrl
     *            the new idp sync url
     */
    public void setIdpSyncUrl(String idpSyncUrl) {
        this.idpSyncUrl = idpSyncUrl;
    }

    /**
     * Gets the idp slo http response url.
     * 
     * @return the idp slo http response url
     */
    public String getIdpSloHttpResponseUrl() {
        return idpSloHttpResponseUrl;
    }

    /**
     * Sets the idp slo http response url.
     * 
     * @param idpSloHttpResponseUrl
     *            the new idp slo http response url
     */
    public void setIdpSloHttpResponseUrl(String idpSloHttpResponseUrl) {
        this.idpSloHttpResponseUrl = idpSloHttpResponseUrl;
    }

    /**
     * Gets the idp slo soap response url.
     * 
     * @return the idp slo soap response url
     */
    public String getIdpSloSoapResponseUrl() {
        return idpSloSoapResponseUrl;
    }

    /**
     * Sets the idp slo soap response url.
     * 
     * @param idpSloSoapResponseUrl
     *            the new idp slo soap response url
     */
    public void setIdpSloSoapResponseUrl(String idpSloSoapResponseUrl) {
        this.idpSloSoapResponseUrl = idpSloSoapResponseUrl;
    }
}