com.redblackit.war.X509HttpClientTest.java Source code

Java tutorial

Introduction

Here is the source code for com.redblackit.war.X509HttpClientTest.java

Source

/*
 * Copyright 2002-2011 the original author or authors, or Red-Black IT Ltd, as appropriate.
 *
 * 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 com.redblackit.war;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLPeerUnverifiedException;

import junit.framework.Assert;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author djnorth
 * 
 *         Test using X509HttpClientFactory bean, and also plain
 *         DefaultHttpCLient for non-client auth.
 * 
 *         The system property clientAuthMandatory can be used to allow
 *         successful tests with servers such as GlassFish that do not allow
 *         optional client authentication ("want").
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class X509HttpClientTest {

    private Logger logger = Logger.getLogger("web.client");

    /**
     * X509 Http Clients
     */
    @Autowired
    @Qualifier("httpClientGoodCert")
    private HttpClient httpClientGoodCert;

    @Autowired
    @Qualifier("httpClientGoodCertNotUser")
    private HttpClient httpClientGoodCertNotUser;

    @Autowired
    @Qualifier("httpClientBadCert")
    private HttpClient httpClientBadCert;

    /**
     * Commonly used attributes from testProperties and messages
     */

    @Value("#{'https://' + testProperties.serverHost + ':' + ( systemProperties['httpsPort.override'] ?: testProperties.httpsPort ) + '/' + testProperties.appPath}")
    private String baseHttpsUrl;
    @Value("#{messages['login.title']}")
    private String loginTitle;
    @Value("#{messages['welcome.title']}")
    private String welcomeTitle;
    @Value("#{systemProperties['clientAuthMandatory'] ?: false}")
    private boolean clientAuthMandatory;

    /**
     * Make connection with good certificate client and verify response is home
     * page
     */
    @Test
    public void testX509ConnectHttpsGoodCertificate() throws Exception {
        validateResponseToRequest(httpClientGoodCert, baseHttpsUrl, welcomeTitle);
    }

    /**
     * Make connection with good certificate client which is not a user in
     * Spring security and verify response is login page
     */
    @Test
    public void testX509ConnectHttpsGoodCertificateNotUser() throws Exception {
        validateResponseToRequest(httpClientGoodCertNotUser, baseHttpsUrl, loginTitle);
    }

    /**
     * Make connection with bad certificate client and verify response is login
     * page, or failure, depending on the web server
     */
    @Test
    public void testX509ConnectHttpsBadCertificate() throws Exception {
        if (clientAuthMandatory) {
            validateRequestFails(httpClientBadCert, baseHttpsUrl);
        } else {
            validateResponseToRequest(httpClientBadCert, baseHttpsUrl, loginTitle);
        }
    }

    /**
     * Do request and validate response
     * 
     * @param httpClientToTest
     * @param url
     * @param expectedTitle
     */
    private void validateResponseToRequest(HttpClient httpClientToTest, String url, String expectedTitle)
            throws Exception {
        HttpGet request = new HttpGet(url);
        HttpResponse response = httpClientToTest.execute(request);

        logger.info("request:" + request);

        StatusLine status = response.getStatusLine();
        Assert.assertEquals("Status code:" + status, HttpStatus.SC_OK, status.getStatusCode());
        logger.info(status);

        BasicResponseHandler responseHandler = new BasicResponseHandler();
        String responseBody = responseHandler.handleResponse(response).trim();
        final int xmlstart = responseBody.indexOf("<?xml");
        if (xmlstart > 0) {
            responseBody = responseBody.substring(xmlstart);
        }
        logger.debug("responseBody*>>");
        logger.debug(responseBody);
        logger.debug("responseBody*<<");

        Pattern titlePattern = Pattern.compile("(<title>)([^<]+)(</title>)");
        Matcher matcher = titlePattern.matcher(responseBody);
        Assert.assertTrue("title element found", matcher.find());

        String title = matcher.group(2);
        Assert.assertEquals("title", expectedTitle, title);
    }

    /**
     * Validate request fails (for bad certificates when server only supports
     * clientAuthMandatory e.g. GlassFish
     * 
     * @param httpClientToTest
     * @param url
     */
    private void validateRequestFails(HttpClient httpClientToTest, String url) throws Exception {

        HttpGet request = new HttpGet(url);
        logger.info("request:" + request);
        try {
            HttpResponse response = httpClientToTest.execute(request);

            StatusLine status = response.getStatusLine();
            logger.error(status);

            BasicResponseHandler responseHandler = new BasicResponseHandler();
            String responseBody = responseHandler.handleResponse(response).trim();
            final int xmlstart = responseBody.indexOf("<?xml");
            if (xmlstart > 0) {
                responseBody = responseBody.substring(xmlstart);
            }
            logger.error("responseBody*>>");
            logger.error(responseBody);
            logger.error("responseBody*<<");

            Assert.fail("expected exception for bad certifiate:but got response");
        } catch (SSLPeerUnverifiedException pue) {
            logger.debug("expected exception", pue);
        }

    }

}