/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.cxf.transport.http; import java.io.OutputStream; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.cxf.Bus; import org.apache.cxf.bus.extension.ExtensionManagerBus; import org.apache.cxf.common.util.Base64Utility; import org.apache.cxf.configuration.security.AuthorizationPolicy; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; import org.apache.cxf.service.model.EndpointInfo; import org.apache.cxf.transport.http.auth.HttpAuthSupplier; import org.apache.cxf.ws.addressing.EndpointReferenceType; import org.apache.cxf.ws.addressing.EndpointReferenceUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class HTTPConduitTest extends Assert { @Before public void setUp() throws Exception { } @After public void tearDown() { } /** * Generates a new message. */ private Message getNewMessage() { Message message = new MessageImpl(); Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); List<String> contentTypes = new ArrayList<>(); contentTypes.add("text/xml"); contentTypes.add("charset=utf8"); headers.put("content-type", contentTypes); message.put(Message.PROTOCOL_HEADERS, headers); return message; } private final class TestAuthSupplier implements HttpAuthSupplier { public String getAuthorization(AuthorizationPolicy authPolicy, URI currentURI, Message message, String fullHeader) { return "myauth"; } public boolean requiresRequestCaching() { return false; } } /** * This test verfies that the "getTarget() call returns the correct * EndpointReferenceType for the given endpoint address. */ @Test public void testGetTarget() throws Exception { Bus bus = new ExtensionManagerBus(); EndpointInfo ei = new EndpointInfo(); ei.setAddress("http://nowhere.com/bar/foo"); HTTPConduit conduit = new URLConnectionHTTPConduit(bus, ei, null); conduit.finalizeConfig(); EndpointReferenceType target = EndpointReferenceUtils.getEndpointReference( "http://nowhere.com/bar/foo"); // Test call EndpointReferenceType ref = conduit.getTarget(); assertNotNull("unexpected null target", ref); assertEquals("unexpected target", EndpointReferenceUtils.getAddress(ref), EndpointReferenceUtils.getAddress(target)); assertEquals("unexpected address", conduit.getAddress(), "http://nowhere.com/bar/foo"); assertEquals("unexpected on-demand URL", conduit.getURI().getPath(), "/bar/foo"); } /** * Verfies one of the tenents of our interface -- the Conduit sets up * an OutputStream on the message after a "prepare". */ @Test public void testConduitOutputStream() throws Exception { Bus bus = new ExtensionManagerBus(); EndpointInfo ei = new EndpointInfo(); ei.setAddress("http://nowhere.com/bar/foo"); HTTPConduit conduit = new URLConnectionHTTPConduit(bus, ei, null); conduit.finalizeConfig(); Message message = getNewMessage(); // Test call conduit.prepare(message); assertNotNull("Conduit should always set output stream.", message.getContent(OutputStream.class)); } @Test public void testAuthPolicyFromEndpointInfo() throws Exception { Bus bus = new ExtensionManagerBus(); EndpointInfo ei = new EndpointInfo(); AuthorizationPolicy ap = new AuthorizationPolicy(); ap.setPassword("password"); ap.setUserName("testUser"); ei.addExtensor(ap); ei.setAddress("http://nowhere.com/bar/foo"); HTTPConduit conduit = new URLConnectionHTTPConduit(bus, ei, null); conduit.finalizeConfig(); Message message = getNewMessage(); // Test call conduit.prepare(message); Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS)); assertNotNull("Authorization Header should exist", headers.get("Authorization")); assertEquals("Unexpected Authorization Token", "Basic " + Base64Utility.encode("testUser:password".getBytes()), headers.get("Authorization").get(0)); } /** * This test verifies the precedence of Authorization Information. * Setting authorization information on the Message takes precedence * over a Basic Auth Supplier with preemptive UserPass, and that * followed by setting it directly on the Conduit. */ @Test public void testAuthPolicyPrecedence() throws Exception { Bus bus = new ExtensionManagerBus(); EndpointInfo ei = new EndpointInfo(); ei.setAddress("http://nowhere.com/bar/foo"); HTTPConduit conduit = new URLConnectionHTTPConduit(bus, ei, null); conduit.finalizeConfig(); conduit.getAuthorization().setUserName("Satan"); conduit.getAuthorization().setPassword("hell"); Message message = getNewMessage(); // Test call conduit.prepare(message); Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS)); assertNotNull("Authorization Header should exist", headers.get("Authorization")); assertEquals("Unexpected Authorization Token", "Basic " + Base64Utility.encode("Satan:hell".getBytes()), headers.get("Authorization").get(0)); // Setting a Basic Auth User Pass should override conduit.setAuthSupplier(new TestAuthSupplier()); message = getNewMessage(); // Test Call conduit.prepare(message); headers = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS)); List<String> authorization = headers.get("Authorization"); assertNotNull("Authorization Token must be set", authorization); assertEquals("Wrong Authorization Token", "myauth", authorization.get(0)); conduit.setAuthSupplier(null); // Setting authorization policy on the message should override // conduit setting AuthorizationPolicy authPolicy = new AuthorizationPolicy(); authPolicy.setUserName("Hello"); authPolicy.setPassword("world"); authPolicy.setAuthorizationType("Basic"); message = getNewMessage(); message.put(AuthorizationPolicy.class, authPolicy); conduit.prepare(message); headers = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS)); assertEquals("Unexpected Authorization Token", "Basic " + Base64Utility.encode("Hello:world".getBytes()), headers.get("Authorization").get(0)); } }