org.xacml4j.saml.XACMLAuthzDecisionQueryEndpointTest.java Source code

Java tutorial

Introduction

Here is the source code for org.xacml4j.saml.XACMLAuthzDecisionQueryEndpointTest.java

Source

package org.xacml4j.saml;

/*
 * #%L
 * XACML/OpenSAML Integration
 * %%
 * Copyright (C) 2009 - 2014 Xacml4J.org
 * %%
 * This program 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 3 of the
 * License, or (at your option) any later version.
 * 
 * This program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
 * #L%
 */

import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.security.utils.XMLUtils;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opensaml.DefaultBootstrap;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.xacml.profile.saml.XACMLAuthzDecisionQueryType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.w3c.dom.Document;
import org.xacml4j.opensaml.IDPConfiguration;
import org.xacml4j.opensaml.OpenSamlObjectBuilder;
import org.xacml4j.opensaml.XACMLAuthzDecisionQueryEndpoint;
import org.xacml4j.opensaml.XACMLAuthzDecisionQuerySigner;
import org.xacml4j.v30.Decision;
import org.xacml4j.v30.RequestContext;
import org.xacml4j.v30.ResponseContext;
import org.xacml4j.v30.Result;
import org.xacml4j.v30.Status;
import org.xacml4j.v30.pdp.PolicyDecisionPoint;

import com.google.common.io.Closeables;

@ContextConfiguration(locations = { "classpath:testApplicationContext.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class XACMLAuthzDecisionQueryEndpointTest {
    @Autowired
    private IDPConfiguration idpConfiguration;
    private XACMLAuthzDecisionQueryEndpoint endpoint;
    private PolicyDecisionPoint pdp;
    private IMocksControl control;

    private static PrivateKey spPrivateKey;
    private static X509Certificate spPublicKey;
    private static XACMLAuthzDecisionQuerySigner signer;

    @BeforeClass
    public static void init() throws Exception {
        DefaultBootstrap.bootstrap();
        KeyStore spKeyStore = getKeyStore("JCEKS", "/test-sp.jceks", "changeme");
        KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) spKeyStore.getEntry("mykey",
                new KeyStore.PasswordProtection("changeme".toCharArray()));
        spPrivateKey = entry.getPrivateKey();
        spPublicKey = (X509Certificate) entry.getCertificate();

        signer = new XACMLAuthzDecisionQuerySigner(spKeyStore, "mykey", "changeme");
    }

    @Before
    public void testInit() throws Exception {
        this.control = EasyMock.createControl();
        this.pdp = control.createMock(PolicyDecisionPoint.class);
        this.endpoint = new XACMLAuthzDecisionQueryEndpoint(idpConfiguration, pdp);
    }

    @Test
    public void testInvalidSignature() throws Exception {
        Document query = parse("TestXacmlSamlRequest-invalidSignature.xml");
        XACMLAuthzDecisionQueryType xacmlSamlQuery = OpenSamlObjectBuilder
                .unmarshallXacml20AuthzDecisionQuery(query.getDocumentElement());

        control.replay();
        Response response = endpoint.handle(xacmlSamlQuery);
        control.verify();

        assertThat(response, notNullValue());
        assertThat(response.getStatus().getStatusCode().getValue(), is(StatusCode.REQUESTER_URI));
    }

    @Test
    public void testInvalidSignature_SignatureValidationDisabled() throws Exception {
        endpoint.setRequireSignatureValidation(false);

        Document query = parse("TestXacmlSamlRequest-invalidSignature.xml");
        XACMLAuthzDecisionQueryType xacmlSamlQuery = OpenSamlObjectBuilder
                .unmarshallXacml20AuthzDecisionQuery(query.getDocumentElement());
        Capture<RequestContext> captureRequest = new Capture<RequestContext>();
        expect(pdp.decide(capture(captureRequest)))
                .andReturn(ResponseContext.builder().result(createIndeterminateProcessingError()).build());

        control.replay();
        Response response = endpoint.handle(xacmlSamlQuery);
        control.verify();

        assertThat(response, notNullValue());
        assertThat(response.getStatus().getStatusCode().getValue(), is(StatusCode.SUCCESS_URI));
    }

    @Test
    public void testCorrectSignature() throws Exception {
        Document query = parse("TestXacmlSamlRequest-nosignature.xml");
        new ApacheXMLDsigGenerator().signSamlRequest(query.getDocumentElement(), spPrivateKey, spPublicKey);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        XMLUtils.outputDOMc14nWithComments(query, bos);

        XACMLAuthzDecisionQueryType xacmlSamlQuery = OpenSamlObjectBuilder
                .unmarshallXacml20AuthzDecisionQuery(query.getDocumentElement());
        Capture<RequestContext> captureRequest = new Capture<RequestContext>();
        expect(pdp.decide(capture(captureRequest)))
                .andReturn(ResponseContext.builder().result(createIndeterminateProcessingError()).build());
        control.replay();
        Response response1 = endpoint.handle(xacmlSamlQuery);

        assertThat(response1, notNullValue());
        assertThat(response1.getStatus().getStatusCode().getValue(), is(StatusCode.SUCCESS_URI));

        control.verify();
    }

    private static Result createIndeterminateProcessingError() {
        return Result.builder(Decision.INDETERMINATE,
                Status.builder(org.xacml4j.v30.StatusCode.createProcessingError()).build()).build();
    }

    private static KeyStore getKeyStore(String ksType, String resource, String ksPwd) throws Exception {
        InputStream is = null;
        try {
            is = XACMLAuthzDecisionQueryEndpointTest.class.getResourceAsStream(resource);
            KeyStore ks = KeyStore.getInstance(ksType);
            ks.load(is, ksPwd.toCharArray());
            return ks;
        } finally {
            Closeables.closeQuietly(is);
        }
    }

    public static Document parse(String resourcePath) throws Exception {
        InputStream in = null;
        try {
            in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath);
            assertThat(in, notNullValue());
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            return dbf.newDocumentBuilder().parse(in);
        } finally {
            Closeables.closeQuietly(in);
        }
    }

}