From 5251b1be8d891c3b810efbf05c5511e1ab648864 Mon Sep 17 00:00:00 2001 From: Zibran Khan Date: Tue, 27 Oct 2026 06:36:12 +0530 Subject: [PATCH] filter local policy assertions from ListingAgent ?policy responses --- .../axis2/transport/http/ListingAgent.java | 41 +----- .../http/PolicyListingFilterTest.java | 125 ++++++++++++++++++ 2 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 modules/transport/http/src/test/java/org/apache/axis2/transport/http/PolicyListingFilterTest.java diff --git a/modules/transport/http/src/main/java/org/apache/axis2/transport/http/ListingAgent.java b/modules/transport/http/src/main/java/org/apache/axis2/transport/http/ListingAgent.java index 6bb8e6e8f4..ea8a50f8b6 100644 --- a/modules/transport/http/src/main/java/org/apache/axis2/transport/http/ListingAgent.java +++ b/modules/transport/http/src/main/java/org/apache/axis2/transport/http/ListingAgent.java @@ -36,10 +36,6 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -203,6 +199,9 @@ private void handlePolicyRequest(HttpServletRequest req, HttpServletResponse res, String serviceName, AxisService axisService) throws IOException, ServletException { + // Every policy below is written through this serializer, as the WSDL + // generators do, so the assertions modules declare local (RampartConfig + // and its keystore settings, for one) are never published. ExternalPolicySerializer serializer = new ExternalPolicySerializer(); serializer.setAssertionsToFilter(configContext .getAxisConfiguration().getLocalPolicyAssertions()); @@ -216,23 +215,10 @@ private void handlePolicyRequest(HttpServletRequest req, Policy targetPolicy = findPolicy(idParam, axisService); if (targetPolicy != null) { - XMLStreamWriter writer; - try { - OutputStream out = res.getOutputStream(); - writer = XMLOutputFactory.newInstance() - .createXMLStreamWriter(out); - res.setContentType("application/wspolicy+xml"); - targetPolicy.serialize(writer); - writer.flush(); - - } catch (XMLStreamException e) { - throw new ServletException( - "Error occured when serializing the Policy", - e); - - } catch (FactoryConfigurationError e) { + serializer.serialize(targetPolicy, res.getOutputStream()); + } catch (RuntimeException e) { throw new ServletException( "Error occured when serializing the Policy", e); @@ -248,23 +234,10 @@ private void handlePolicyRequest(HttpServletRequest req, Policy effecPolicy = policyInclude.getEffectivePolicy(); if (effecPolicy != null) { - XMLStreamWriter writer; - try { - OutputStream out = res.getOutputStream(); - writer = XMLOutputFactory.newInstance() - .createXMLStreamWriter(out); - res.setContentType("application/wspolicy+xml"); - effecPolicy.serialize(writer); - writer.flush(); - - } catch (XMLStreamException e) { - throw new ServletException( - "Error occured when serializing the Policy", - e); - - } catch (FactoryConfigurationError e) { + serializer.serialize(effecPolicy, res.getOutputStream()); + } catch (RuntimeException e) { throw new ServletException( "Error occured when serializing the Policy", e); diff --git a/modules/transport/http/src/test/java/org/apache/axis2/transport/http/PolicyListingFilterTest.java b/modules/transport/http/src/test/java/org/apache/axis2/transport/http/PolicyListingFilterTest.java new file mode 100644 index 0000000000..dc7b02be51 --- /dev/null +++ b/modules/transport/http/src/test/java/org/apache/axis2/transport/http/PolicyListingFilterTest.java @@ -0,0 +1,125 @@ +/* + * 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.axis2.transport.http; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; + +import javax.xml.namespace.QName; + +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import junit.framework.TestCase; + +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.ConfigurationContextFactory; +import org.apache.axis2.description.AxisService; +import org.apache.neethi.Policy; +import org.apache.neethi.PolicyEngine; + +/** + * A module lists the policy assertions that are local to the server in the + * {@code local-policy-assertions} element of its module.xml (Rampart does so for + * RampartConfig, which carries the user, callback class and keystore settings). + * The WSDL generators drop them when they embed a policy, and the {@code ?policy} + * route has to drop them as well. + */ +public class PolicyListingFilterTest extends TestCase { + + private static final String RAMPART_NS = "http://ws.apache.org/rampart/policy"; + + private static final String POLICY = + "" + + "" + + "" + + "" + + "service" + + "" + + "storepass" + + "" + + ""; + + private ConfigurationContext configContext; + + @Override + protected void setUp() throws Exception { + configContext = ConfigurationContextFactory.createEmptyConfigurationContext(); + configContext.getAxisConfiguration().addLocalPolicyAssertion( + new QName(RAMPART_NS, "RampartConfig")); + + AxisService service = new AxisService("Secured"); + Policy policy = PolicyEngine.getPolicy( + new ByteArrayInputStream(POLICY.getBytes(StandardCharsets.UTF_8))); + service.getPolicySubject().attachPolicy(policy); + configContext.getAxisConfiguration().addService(service); + } + + private String policyListing(String id) throws Exception { + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURL()) + .thenReturn(new StringBuffer("http://localhost:8080/axis2/services/Secured")); + when(req.getQueryString()).thenReturn(id == null ? "policy" : "policy&id=" + id); + when(req.getParameter("id")).thenReturn(id); + final ByteArrayOutputStream body = new ByteArrayOutputStream(); + HttpServletResponse res = mock(HttpServletResponse.class); + when(res.getOutputStream()).thenReturn(new ServletOutputStream() { + @Override + public void write(int b) { + body.write(b); + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + } + }); + new ListingAgent(configContext).processListService(req, res); + return new String(body.toByteArray(), StandardCharsets.UTF_8); + } + + private void assertLocalAssertionWithheld(String listing) { + assertTrue("the published assertion should still be listed: " + listing, + listing.contains("TransportBinding")); + assertFalse("a local assertion was published: " + listing, + listing.contains("RampartConfig")); + assertFalse("the keystore password was published: " + listing, + listing.contains("storepass")); + } + + public void testEffectivePolicyWithholdsLocalAssertions() throws Exception { + assertLocalAssertionWithheld(policyListing(null)); + } + + public void testPolicyByIdWithholdsLocalAssertions() throws Exception { + assertLocalAssertionWithheld(policyListing("SecPolicy")); + } +}