Package org.picketlink.test.identity.federation.web.saml.handlers

Source Code of org.picketlink.test.identity.federation.web.saml.handlers.SAML2EncryptionHandlerUnitTestCase

/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.picketlink.test.identity.federation.web.saml.handlers;

import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;

import java.io.IOException;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.picketlink.identity.federation.api.saml.v2.request.SAML2Request;
import org.picketlink.identity.federation.api.saml.v2.response.SAML2Response;
import org.picketlink.identity.federation.core.config.IDPType;
import org.picketlink.identity.federation.core.config.ProviderType;
import org.picketlink.identity.federation.core.config.SPType;
import org.picketlink.identity.federation.core.exceptions.ConfigurationException;
import org.picketlink.identity.federation.core.exceptions.ParsingException;
import org.picketlink.identity.federation.core.exceptions.ProcessingException;
import org.picketlink.identity.federation.core.saml.v2.common.SAMLDocumentHolder;
import org.picketlink.identity.federation.core.saml.v2.factories.SAML2HandlerChainFactory;
import org.picketlink.identity.federation.core.saml.v2.impl.DefaultSAML2HandlerChainConfig;
import org.picketlink.identity.federation.core.saml.v2.impl.DefaultSAML2HandlerConfig;
import org.picketlink.identity.federation.core.saml.v2.impl.DefaultSAML2HandlerRequest;
import org.picketlink.identity.federation.core.saml.v2.impl.DefaultSAML2HandlerResponse;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2Handler;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2Handler.HANDLER_TYPE;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerChain;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerChainConfig;
import org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil;
import org.picketlink.identity.federation.core.sts.PicketLinkCoreSTS;
import org.picketlink.identity.federation.core.util.TransformerUtil;
import org.picketlink.identity.federation.saml.v2.assertion.NameIDType;
import org.picketlink.identity.federation.saml.v2.protocol.AuthnRequestType;
import org.picketlink.identity.federation.web.constants.GeneralConstants;
import org.picketlink.identity.federation.web.core.HTTPContext;
import org.picketlink.identity.federation.web.core.IdentityServer;
import org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler;
import org.picketlink.identity.federation.web.handlers.saml2.SAML2EncryptionHandler;
import org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler;
import org.picketlink.identity.federation.web.roles.DefaultRoleValidator;
import org.picketlink.test.identity.federation.web.mock.MockHttpServletRequest;
import org.picketlink.test.identity.federation.web.mock.MockHttpServletResponse;
import org.picketlink.test.identity.federation.web.mock.MockHttpSession;
import org.picketlink.test.identity.federation.web.mock.MockServletContext;
import org.w3c.dom.Document;

/**
* @author <a href="mailto:psilva@redhat.com">Pedro Silva</a>
*
*/
public class SAML2EncryptionHandlerUnitTestCase {

    private static final String SERVICE_PROVIDER_URL = "http://service-provider.picketlink.org";
    private static final String IDENTITY_PROVIDER_URL = "http://identity-provider.picketlink.org";
   
    private MockServletContext servletContext = new MockServletContext();
    private KeyPair keyPair;

    @Before
    public void onSetup() throws NoSuchAlgorithmException {
        // install the STS default configurations
        PicketLinkCoreSTS.instance().installDefaultConfiguration();
       
        // register a identity server into the ServletContext
        servletContext.setAttribute(GeneralConstants.IDENTITY_SERVER, new IdentityServer());
       
        // creates a random and temporary keypair for encryption and signing
        this.keyPair = KeyPairGenerator.getInstance("RSA").genKeyPair();
    }

    /**
     * <p>
     * Try to issue an encrypted and signed SAML Assertion and to process it by the SP.
     * </p>
     *
     * @throws Exception
     */
    @Test
    public void testEncryptAssertion() throws Exception {
        Document assertionDocument = issueSAMLAssertion();
       
        assertNotNull(assertionDocument);

        System.out.println(prettyPrintDocument(assertionDocument).getBuffer().toString());

        processSAMLAssertion(assertionDocument);
    }

    /**
     * <p>
     * This method asks the IDP for a new encrypted and signed SAML Assertion by sending an AuthnRequest.
     * </p>
     *
     * @return
     * @throws ConfigurationException
     * @throws ProcessingException
     */
    private Document issueSAMLAssertion() throws ConfigurationException, ProcessingException {
        NameIDType issuerNameID = new NameIDType();

        issuerNameID.setValue(IDENTITY_PROVIDER_URL);

        SAML2Request samlRequest = new SAML2Request();

        AuthnRequestType authnRequestType = samlRequest.createAuthnRequestType("AuthnRequest_FAKE_ID",
                SERVICE_PROVIDER_URL, SERVICE_PROVIDER_URL,
                SERVICE_PROVIDER_URL);

        DefaultSAML2HandlerRequest handlerAuthnRequest = new DefaultSAML2HandlerRequest(new HTTPContext(
                new MockHttpServletRequest(new MockHttpSession(), "POST"), new MockHttpServletResponse(), servletContext),
                issuerNameID, new SAMLDocumentHolder(authnRequestType), HANDLER_TYPE.IDP);

        handlerAuthnRequest.addOption(GeneralConstants.SENDER_PUBLIC_KEY, getKeyPair().getPublic());
       
        DefaultSAML2HandlerResponse handlerAuthnResponse = new DefaultSAML2HandlerResponse();

        try {
            for (SAML2Handler handler : getIDPHandlerChain().handlers()) {
                handler.handleRequestType(handlerAuthnRequest, handlerAuthnResponse);
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error while issuing encrypted and signed SAML Assertion.");
        }

        return handlerAuthnResponse.getResultingDocument();
    }

    /**
     * <p>
     * Given the SAML Assertion, process it by the SP and make sure it can be decrypted and have its signature validated.
     * </p>
     *
     * @param assertionDocument
     * @throws ParsingException
     * @throws ConfigurationException
     * @throws ProcessingException
     * @throws NoSuchAlgorithmException
     */
    private void processSAMLAssertion(Document assertionDocument) throws ParsingException, ConfigurationException,
            ProcessingException, NoSuchAlgorithmException {
        NameIDType issuerSPNameID = new NameIDType();

        issuerSPNameID.setValue(IDENTITY_PROVIDER_URL);

        DefaultSAML2HandlerRequest handlerAssertionResponseRequest = new DefaultSAML2HandlerRequest(new HTTPContext(
                new MockHttpServletRequest(new MockHttpSession(), "POST"), new MockHttpServletResponse(), servletContext),
                issuerSPNameID, new SAMLDocumentHolder(new SAML2Response().getSAML2ObjectFromStream(DocumentUtil
                        .getNodeAsStream(assertionDocument)), assertionDocument), HANDLER_TYPE.SP);

        handlerAssertionResponseRequest.addOption(GeneralConstants.DECRYPTING_KEY, getKeyPair().getPrivate());
        handlerAssertionResponseRequest.addOption(GeneralConstants.SENDER_PUBLIC_KEY, getKeyPair().getPublic());

        DefaultSAML2HandlerResponse handlerAssertionRequestResponse = new DefaultSAML2HandlerResponse();

        try {
            for (SAML2Handler handler : getSPHandlerChain().handlers()) {
                handler.handleStatusResponseType(handlerAssertionResponseRequest, handlerAssertionRequestResponse);
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error while processing the encrypted and signed SAML Assertion.");
        }

    }

    private SAML2HandlerChainConfig createHandlerChainConfig(ProviderType configuration) throws NoSuchAlgorithmException {
        SAML2HandlerChainConfig chainConfig = new DefaultSAML2HandlerChainConfig();

        Map<String, Object> chainOptions = new HashMap<String, Object>();

        chainOptions.put(GeneralConstants.CONFIGURATION, configuration);
        chainOptions.put(GeneralConstants.KEYPAIR, getKeyPair());
        chainOptions.put(GeneralConstants.ROLE_VALIDATOR, new DefaultRoleValidator());

        chainConfig.set(chainOptions);

        return chainConfig;
    }

    /**
     * <p>
     * Creates an return a random RSA {@link KeyPair} for testing.
     * </p>
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    private KeyPair getKeyPair() {
        return this.keyPair;
    }

    private SAML2HandlerChain getIDPHandlerChain() throws ConfigurationException {
        List<SAML2Handler> handlers = new ArrayList<SAML2Handler>();

        handlers.add(createAuthenticationHandler());
        handlers.add(createEncryptionHandler());

        IDPType idpType = new IDPType();

        idpType.setEncrypt(true);

        return getHandlerChain(idpType, handlers);
    }

    private SAML2HandlerChain getSPHandlerChain() throws ConfigurationException {
        List<SAML2Handler> handlers = new ArrayList<SAML2Handler>();

        handlers.add(createSignatureValidationHandler());
        handlers.add(createAuthenticationHandler());

        return getHandlerChain(new SPType(), handlers);
    }

    private SAML2HandlerChain getHandlerChain(ProviderType configuration, List<SAML2Handler> handlers) {
        SAML2HandlerChain handlerChain = null;

        try {
            SAML2HandlerChainConfig handlerChainConfig = createHandlerChainConfig(configuration);

            handlerChain = SAML2HandlerChainFactory.createChain();

            for (SAML2Handler saml2Handler : handlers) {
                saml2Handler.initChainConfig(handlerChainConfig);
                handlerChain.add(saml2Handler);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Assert.fail("Handler chain configuration error.");
        }

        return handlerChain;
    }

    private SAML2EncryptionHandler createEncryptionHandler() throws ConfigurationException {
        SAML2EncryptionHandler handler = new SAML2EncryptionHandler();

        DefaultSAML2HandlerConfig handlerConfig = new DefaultSAML2HandlerConfig();
       
        handler.initHandlerConfig(handlerConfig);

        return handler;
    }

    private SAML2SignatureValidationHandler createSignatureValidationHandler() throws ConfigurationException {
        SAML2SignatureValidationHandler handler = new SAML2SignatureValidationHandler();

        handler.initHandlerConfig(new DefaultSAML2HandlerConfig());

        return handler;
    }

    private SAML2AuthenticationHandler createAuthenticationHandler() throws ConfigurationException {
        SAML2AuthenticationHandler handler = new SAML2AuthenticationHandler();

        handler.initHandlerConfig(new DefaultSAML2HandlerConfig());

        return handler;
    }

    private StringWriter prettyPrintDocument(Document authnRequestDocument) {
        StringWriter writer = new StringWriter();

        try {
            Transformer transformer = TransformerUtil.getTransformer();

            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

            transformer.transform(DocumentUtil.getXMLSource(authnRequestDocument), new StreamResult(writer));
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error printing the document.");
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return writer;
    }
}
TOP

Related Classes of org.picketlink.test.identity.federation.web.saml.handlers.SAML2EncryptionHandlerUnitTestCase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.