fr.mby.saml2.sp.opensaml.core.OpenSaml20IntegrationTest.java Source code

Java tutorial

Introduction

Here is the source code for fr.mby.saml2.sp.opensaml.core.OpenSaml20IntegrationTest.java

Source

/**
 * Copyright (C) 2012 RECIA http://www.recia.fr
 * @Author (C) 2012 Maxime Bossard <mxbossard@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * 
 */

package fr.mby.saml2.sp.opensaml.core;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SignableSAMLObject;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.LogoutRequest;
import org.opensaml.saml2.core.LogoutResponse;
import org.opensaml.saml2.core.impl.IssuerBuilder;
import org.opensaml.saml2.core.impl.LogoutRequestBuilder;
import org.opensaml.saml2.core.impl.LogoutResponseBuilder;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.signature.Signature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import fr.mby.saml2.sp.api.core.ISaml20IdpConnector;
import fr.mby.saml2.sp.api.core.ISaml20Storage;
import fr.mby.saml2.sp.api.core.SamlBindingEnum;
import fr.mby.saml2.sp.api.om.IIncomingSaml;
import fr.mby.saml2.sp.api.om.IOutgoingSaml;
import fr.mby.saml2.sp.api.om.IRequestWaitingForResponse;
import fr.mby.saml2.sp.impl.helper.SamlTestResourcesHelper;
import fr.mby.saml2.sp.impl.om.BasicSamlAuthentication;
import fr.mby.saml2.sp.impl.query.QueryAuthnRequest;

/**
 * Integration Test for opensaml2 implementations.
 * 
 * @author Maxime Bossard - 2013
 * 
 */
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:openSaml20IntegrationContext.xml")
public class OpenSaml20IntegrationTest {

    @SuppressWarnings("unused")
    private static final String SP_ENTITY_ID = "http://www.recia.fr/service";

    private static final String REQUEST_ID = "SOME_REQUEST_ID_12487";

    private static final String IDP1_ENTITY_ID = "http://www.recia.fr/idp";

    private static final String IDP2_ENTITY_ID = "http://www.recia.fr/idp2";

    private static final String RESPONSE_ID = "SOME_RESPONSE_ID_56093";

    private static final String AUTH_SUBJECT_ID = "AUTH_SUBJECT_ID_03476";

    private static final String SESSION_INDEX_1 = "SESSION_INDEX_1_23785";

    private static final String SP_AUTHN_SERVER_NAME_ENDPOINT = "www.recia.fr";

    private static final String SP_AUTHN_POST_URI_ENDPOINT = "/cas/Shibboleth.sso/SAML2/POST";

    private static final String SP_AUTHN_REDIRECT_URI_ENDPOINT = "/cas/Shibboleth.sso/SAML2/Redirect";

    private static final String SP_SLO_POST_URI_ENDPOINT = "/cas/Shibboleth.sso/SLO/POST";

    private static final String SP_SLO_REDIRECT_URI_ENDPOINT = "/cas/Shibboleth.sso/SLO/Redirect";

    @javax.annotation.Resource(name = "authnRequest")
    private ClassPathResource authnRequest;

    @javax.annotation.Resource(name = "incomingResponseFullSignedRedirectEncoded")
    private ClassPathResource incomingResponseFullSignedRedirectEncoded;

    @javax.annotation.Resource(name = "incomingResponseFullSignedPostEncoded")
    private ClassPathResource incomingResponseFullSignedPostEncoded;

    @javax.annotation.Resource(name = "incomingSloRequestRedirectEncoded")
    private ClassPathResource incomingSloRequestRedirectEncoded;

    @javax.annotation.Resource(name = "incomingSloRequestPostEncoded")
    private ClassPathResource incomingSloRequestPostEncoded;

    @javax.annotation.Resource(name = "incomingSloResponseRedirectEncoded")
    private ClassPathResource incomingSloResponseRedirectEncoded;

    @javax.annotation.Resource(name = "incomingSloResponsePostEncoded")
    private ClassPathResource incomingSloResponsePostEncoded;

    @Autowired
    @Qualifier("idpConnector")
    private OpenSaml20IdpConnector idpConnector1;

    @Autowired
    @Qualifier("idpConnector2")
    private OpenSaml20IdpConnector idpConnector2;

    @Autowired
    private ISaml20Storage samlStorage;

    @Autowired
    private OpenSaml20SpProcessor spProcessor;

    private final LogoutRequestBuilder logoutRequestBuilder = new LogoutRequestBuilder();

    private final LogoutResponseBuilder logoutResponseBuilder = new LogoutResponseBuilder();

    private final IssuerBuilder issuerBuilder = new IssuerBuilder();

    @BeforeClass
    public static void initOpenSaml() throws ConfigurationException {
        DefaultBootstrap.bootstrap();
    }

    /**
     * Initialize the Storage by adding the original requests in the storage.
     * 
     * @throws Exception
     */
    @Before
    public void addAuthnRequestInMockedStorage() throws Exception {
        // Store AuthnRequest in mocked storage
        final AuthnRequest openSamlAuthnRequest = (AuthnRequest) SamlTestResourcesHelper
                .buildOpenSamlXmlObjectFromResource(this.authnRequest);
        final String authnRequestId = openSamlAuthnRequest.getID();

        final Map<String, String[]> parametersMap = new HashMap<String, String[]>();
        final IRequestWaitingForResponse authnRequestData = new QueryAuthnRequest(authnRequestId,
                this.idpConnector1, parametersMap);
        Mockito.when(this.samlStorage.findRequestWaitingForResponse(authnRequestId)).thenReturn(authnRequestData);
    }

    /**
     * The SP receive  LogoutRequest from the IdP. Which IdPConnector to choose ?
     * 
     * @throws Exception
     */
    @Test
    public void testFindSaml20IdpConnectorToUseToProcessRequests() throws Exception {
        final LogoutRequest logoutRequest = this.logoutRequestBuilder.buildObject();
        final Issuer issuer = issuerBuilder.buildObject();

        // Issuer
        issuer.setValue(IDP2_ENTITY_ID);

        // Request
        logoutRequest.setIssuer(issuer);
        logoutRequest.setID(REQUEST_ID);

        final ISaml20IdpConnector connectorToUse = this.spProcessor.findSaml20IdpConnectorToUse(logoutRequest);
        Assert.assertNotNull("No IdPConnector to use found !", connectorToUse);
        Assert.assertEquals("Wrong IdPConnector used !", this.idpConnector2, connectorToUse);
    }

    /**
     * The SP receive  LogoutResponse from the IdP. Which IdPConnector to choose ?
     * @throws Exception
     */
    @Test
    public void testFindSaml20IdpConnectorToUseToProcessResponses() throws Exception {
        // Mock the Original Request the response is responding to.
        Mockito.when(this.samlStorage.findAuthentication(SESSION_INDEX_1))
                .thenReturn(this.buildBasicSamlAuthentication());
        // Build the original request with IdpConnector1
        final IOutgoingSaml logoutRequest = this.idpConnector1.buildSaml20SingleLogoutRequest(SESSION_INDEX_1,
                SamlBindingEnum.SAML_20_HTTP_POST);
        Mockito.when(this.samlStorage.findRequestWaitingForResponse(REQUEST_ID))
                .thenReturn((IRequestWaitingForResponse) logoutRequest.getSamlQuery());

        final LogoutResponse logoutResponse = this.logoutResponseBuilder.buildObject();
        final Issuer issuer = issuerBuilder.buildObject();

        // Issuer
        issuer.setValue(IDP1_ENTITY_ID);

        // Request
        logoutResponse.setIssuer(issuer);
        logoutResponse.setID(RESPONSE_ID);
        logoutResponse.setInResponseTo(REQUEST_ID);

        final ISaml20IdpConnector connectorToUse = this.spProcessor.findSaml20IdpConnectorToUse(logoutResponse);
        Assert.assertNotNull("No IdPConnector to use found !", connectorToUse);
        Assert.assertEquals("Wrong IdPConnector used !", this.idpConnector1, connectorToUse);
    }

    protected BasicSamlAuthentication buildBasicSamlAuthentication() {
        final BasicSamlAuthentication auth = new BasicSamlAuthentication();
        auth.setSubjectId(AUTH_SUBJECT_ID);
        return auth;
    }

    @Test
    public void testBuildSaml20AuthnRequest() throws Exception {
        // Loop on all bindings available
        for (final SamlBindingEnum binding : SamlBindingEnum.values()) {
            final Map<String, String[]> parametersMap = new HashMap<String, String[]>();

            final IOutgoingSaml outgoingSaml = this.idpConnector1.buildSaml20AuthnRequest(parametersMap, binding);
            Assert.assertNotNull("AuthnRequest's IOutgoingSaml cannot be null !", outgoingSaml);

            // TODO implement checks
        }
    }

    @Test
    public void testBuildSaml20SingleLogoutRequest() throws Exception {
        final String sessionIndex = "sessionIndex_789654_sessionIndex_123654";

        // Put the original Auth in the mocked storage.
        Mockito.when(this.samlStorage.findAuthentication(sessionIndex))
                .thenReturn(this.buildBasicSamlAuthentication());

        // Loop on all bindings available
        for (final SamlBindingEnum binding : SamlBindingEnum.values()) {
            // Try to build the SloRequest
            final IOutgoingSaml outgoingSaml = this.idpConnector1.buildSaml20SingleLogoutRequest(sessionIndex,
                    binding);
            Assert.assertNotNull("SloRequest's IOutgoingSaml cannot be null !", outgoingSaml);

            // TODO implement checks
        }
    }

    @Test
    public void testBuildSaml20SingleLogoutResponse() throws Exception {
        // Loop on all bindings available
        for (final SamlBindingEnum binding : SamlBindingEnum.values()) {
            final String originRequestId = "originRequestId_258741_originRequestId_963258";
            final String relayState = "relayState852789";

            final IOutgoingSaml outgoingSaml = this.idpConnector1.buildSaml20SingleLogoutResponse(binding,
                    originRequestId, relayState);
            Assert.assertNotNull("SloResponse's IOutgoingSaml cannot be null !", outgoingSaml);

            // TODO implement checks
        }
    }

    @Test
    public void testProcessSaml20IncomingRequestWithPostAuthnResponse() throws Exception {
        final String relayState = "rs_18743";

        // Store AuthnRequest in mocked storage
        final AuthnRequest openSamlAuthnRequest = (AuthnRequest) SamlTestResourcesHelper
                .buildOpenSamlXmlObjectFromResource(this.authnRequest);
        final String authnRequestId = openSamlAuthnRequest.getID();

        final Map<String, String[]> parametersMap = new HashMap<String, String[]>();
        final IRequestWaitingForResponse authnRequestData = new QueryAuthnRequest(authnRequestId,
                this.idpConnector1, parametersMap);
        Mockito.when(this.samlStorage.findRequestWaitingForResponse(authnRequestId)).thenReturn(authnRequestData);

        final MockHttpServletRequest request = this.buildAuthnPostResponse(relayState,
                this.incomingResponseFullSignedPostEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("AuthnResponse's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testProcessSaml20IncomingRequestWithRedirectAuthnResponse() throws Exception {
        final String relayState = "rs_28435";
        final MockHttpServletRequest request = this.buildAuthnRedirectResponse(relayState,
                this.incomingResponseFullSignedRedirectEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("AuthnResponse's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testProcessSaml20IncomingRequestWithRedirectSloRequest() throws Exception {
        final String relayState = "rs_69437";
        final MockHttpServletRequest request = this.buildSloRedirectRequest(relayState,
                this.incomingSloRequestRedirectEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("SloRequest's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testProcessSaml20IncomingRequestWithPostSloRequest() throws Exception {
        final String relayState = "rs_19346";
        final MockHttpServletRequest request = this.buildSloPostRequest(relayState,
                this.incomingSloRequestPostEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("SloRequest's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testProcessSaml20IncomingRequestWithRedirectSloResponse() throws Exception {
        final String relayState = "rs_83946";
        final MockHttpServletRequest request = this.buildSloRedirectResponse(relayState,
                this.incomingSloResponseRedirectEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("SloResponse's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testProcessSaml20IncomingRequestWithPostSloResponse() throws Exception {
        final String relayState = "rs_83946";
        final MockHttpServletRequest request = this.buildSloPostResponse(relayState,
                this.incomingSloResponsePostEncoded);

        final IIncomingSaml incomingSaml = this.spProcessor.processSaml20IncomingRequest(request);

        Assert.assertNotNull("SloResponse's IIncomingSaml cannot be null !", incomingSaml);

        // TODO implement checks
    }

    @Test
    public void testSignSamlObject() throws Exception {
        // TODO implement this test
        final SignableSAMLObject signable = null;
        final Signature signature = this.spProcessor.signSamlObject(signable);

        Assert.assertNotNull("Signature cannot be null !", signature);
    }

    @Test
    public void testLogout() throws Exception {
        // TODO implement this test
        final String sessionIndex = "index_de_folie";
        this.spProcessor.logout(sessionIndex);
    }

    protected MockHttpServletRequest buildAuthnRedirectResponse(final String relayState,
            final Resource redirectEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(redirectEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("GET", SP_AUTHN_REDIRECT_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setQueryString("?SAMLResponse=" + encodedRequest + "&RelayState=" + relayState);
        request.setParameter("SAMLResponse", URLDecoder.decode(encodedRequest, "UTF-8"));
        request.setParameter("RelayState", relayState);
        return request;
    }

    protected MockHttpServletRequest buildAuthnPostResponse(final String relayState,
            final Resource postEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(postEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("POST", SP_AUTHN_POST_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setParameter("SAMLResponse", encodedRequest);
        request.setParameter("RelayState", relayState);
        return request;
    }

    protected MockHttpServletRequest buildSloRedirectRequest(final String relayState,
            final Resource redirectEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(redirectEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("GET", SP_SLO_REDIRECT_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setQueryString("?SAMLRequest=" + encodedRequest + "&RelayState=" + relayState);
        request.setParameter("SAMLRequest", URLDecoder.decode(encodedRequest, "UTF-8"));
        request.setParameter("RelayState", relayState);
        return request;
    }

    protected MockHttpServletRequest buildSloPostRequest(final String relayState,
            final Resource postEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(postEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("POST", SP_SLO_POST_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setParameter("SAMLRequest", encodedRequest);
        request.setParameter("RelayState", relayState);
        return request;
    }

    protected MockHttpServletRequest buildSloRedirectResponse(final String relayState,
            final Resource redirectEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(redirectEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("GET", SP_SLO_REDIRECT_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setQueryString("?SAMLResponse=" + encodedRequest + "&RelayState=" + relayState);
        request.setParameter("SAMLResponse", URLDecoder.decode(encodedRequest, "UTF-8"));
        request.setParameter("RelayState", relayState);
        return request;
    }

    protected MockHttpServletRequest buildSloPostResponse(final String relayState,
            final Resource postEncodedResource) throws IOException, UnsupportedEncodingException {
        final String encodedRequest = SamlTestResourcesHelper.readFile(postEncodedResource);
        final MockHttpServletRequest request = new MockHttpServletRequest("POST", SP_SLO_POST_URI_ENDPOINT);
        request.setServerName(SP_AUTHN_SERVER_NAME_ENDPOINT);
        request.setParameter("SAMLResponse", encodedRequest);
        request.setParameter("RelayState", relayState);
        return request;
    }
}