You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2018/03/22 15:00:30 UTC

[cxf] branch master updated: CXF-7687 - AuthorizationPolicy: AuthorizationType="Bearer" has no effect

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new 203c8a2  CXF-7687 - AuthorizationPolicy: AuthorizationType="Bearer" has no effect
203c8a2 is described below

commit 203c8a2731bdd44ce102e983d8b97f63cfa283f5
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Thu Mar 22 14:59:55 2018 +0000

    CXF-7687 - AuthorizationPolicy: AuthorizationType="Bearer" has no effect
---
 .../org/apache/cxf/transport/http/HTTPConduit.java | 15 +++--
 .../transport/http/auth/CustomAuthSupplier.java    | 45 +++++++++++++++
 .../systest/jaxrs/security/saml/JAXRSSamlTest.java | 67 ++++++++++++++++++++++
 .../jaxrs/security/saml/SamlCallbackHandler.java   | 15 ++++-
 4 files changed, 134 insertions(+), 8 deletions(-)

diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
index fda7b8f..1ce0b84 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
@@ -75,6 +75,7 @@ import org.apache.cxf.transport.AbstractConduit;
 import org.apache.cxf.transport.Assertor;
 import org.apache.cxf.transport.Conduit;
 import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.transport.http.auth.CustomAuthSupplier;
 import org.apache.cxf.transport.http.auth.DefaultBasicAuthSupplier;
 import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
 import org.apache.cxf.transport.http.auth.HttpAuthHeader;
@@ -157,10 +158,10 @@ public abstract class HTTPConduit
      */
     public static final String KEY_HTTP_CONNECTION = "http.connection";
     public static final String KEY_HTTP_CONNECTION_ADDRESS = "http.connection.address";
-    
+
     public static final String SET_HTTP_RESPONSE_MESSAGE = "org.apache.cxf.transport.http.set.response.message";
     public static final String HTTP_RESPONSE_MESSAGE = "http.responseMessage";
-    
+
     public static final String PROCESS_FAULT_ON_HTTP_400 = "org.apache.cxf.transport.process_fault_on_http_400";
     public static final String NO_IO_EXCEPTIONS = "org.apache.cxf.transport.no_io_exceptions";
     /**
@@ -515,11 +516,11 @@ public abstract class HTTPConduit
         int chunkThreshold = 0;
         final AuthorizationPolicy effectiveAuthPolicy = getEffectiveAuthPolicy(message);
         if (this.authSupplier == null) {
-            this.authSupplier = createAuthSupplier(effectiveAuthPolicy.getAuthorizationType());
+            this.authSupplier = createAuthSupplier(effectiveAuthPolicy);
         }
 
         if (this.proxyAuthSupplier == null) {
-            this.proxyAuthSupplier = createAuthSupplier(proxyAuthorizationPolicy.getAuthorizationType());
+            this.proxyAuthSupplier = createAuthSupplier(proxyAuthorizationPolicy);
         }
 
         if (this.authSupplier.requiresRequestCaching()) {
@@ -601,11 +602,15 @@ public abstract class HTTPConduit
                                                        boolean isChunking,
                                                        int chunkThreshold) throws IOException;
 
-    private HttpAuthSupplier createAuthSupplier(String authType) {
+    private HttpAuthSupplier createAuthSupplier(AuthorizationPolicy authzPolicy) {
+        String authType = authzPolicy.getAuthorizationType();
         if (HttpAuthHeader.AUTH_TYPE_NEGOTIATE.equals(authType)) {
             return new SpnegoAuthSupplier();
         } else if (HttpAuthHeader.AUTH_TYPE_DIGEST.equals(authType)) {
             return new DigestAuthSupplier();
+        } else if (authType != null && !HttpAuthHeader.AUTH_TYPE_BASIC.equals(authType)
+            && authzPolicy.getAuthorization() != null) {
+            return new CustomAuthSupplier();
         } else {
             return new DefaultBasicAuthSupplier();
         }
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/CustomAuthSupplier.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/CustomAuthSupplier.java
new file mode 100644
index 0000000..1066234
--- /dev/null
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/CustomAuthSupplier.java
@@ -0,0 +1,45 @@
+/**
+ * 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.auth;
+
+import java.net.URI;
+
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+
+/**
+ * Use the AuthorizationPolicy type + value to create the authorization header.
+ */
+public final class CustomAuthSupplier implements HttpAuthSupplier {
+
+    public boolean requiresRequestCaching() {
+        return false;
+    }
+
+    public String getAuthorization(AuthorizationPolicy  authPolicy,
+                                   URI currentURI,
+                                   Message message,
+                                   String fullHeader) {
+        if (authPolicy.getAuthorizationType() != null && authPolicy.getAuthorization() != null) {
+            return authPolicy.getAuthorizationType() + " " + authPolicy.getAuthorization();
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
index 8df6d45..14c777b 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/JAXRSSamlTest.java
@@ -19,7 +19,9 @@
 
 package org.apache.cxf.systest.jaxrs.security.saml;
 
+import java.io.StringWriter;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -30,14 +32,22 @@ import javax.ws.rs.core.Form;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
 import org.apache.cxf.Bus;
 import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.provider.FormEncodingProvider;
 import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
 import org.apache.cxf.rs.security.saml.SamlEnvelopedOutInterceptor;
 import org.apache.cxf.rs.security.saml.SamlFormOutInterceptor;
 import org.apache.cxf.rs.security.saml.SamlHeaderOutInterceptor;
@@ -45,8 +55,13 @@ import org.apache.cxf.rs.security.xml.XmlSigOutInterceptor;
 import org.apache.cxf.rt.security.SecurityConstants;
 import org.apache.cxf.systest.jaxrs.security.Book;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
 import org.apache.wss4j.common.WSS4JConstants;
+import org.apache.wss4j.common.saml.SAMLCallback;
+import org.apache.wss4j.common.saml.SAMLUtil;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.DOM2Writer;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -61,6 +76,49 @@ public class JAXRSSamlTest extends AbstractBusClientServerTestBase {
     }
 
     @Test
+    public void testSAMLTokenHeaderUsingAuthorizationPolicy() throws Exception {
+        String address = "https://localhost:" + PORT + "/samlheader/bookstore/books/123";
+
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(address);
+
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAXRSSamlTest.class.getResource("client.xml");
+        Bus springBus = bf.createBus(busFile.toString());
+        bean.setBus(springBus);
+
+        // Create SAML Token
+        SAMLCallback samlCallback = new SAMLCallback();
+        SAMLUtil.doSAMLCallback(new SamlCallbackHandler(), samlCallback);
+        SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+        Document doc = DOMUtils.createDocument();
+        Element token = assertion.toDOM(doc);
+
+        WebClient wc =  bean.createWebClient();
+
+        HTTPConduit http = (HTTPConduit) WebClient.getConfig(wc).getConduit();
+        AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
+        String encodedToken = encodeToken(DOM2Writer.nodeToString(token));
+        authorizationPolicy.setAuthorization(encodedToken);
+        authorizationPolicy.setAuthorizationType("SAML");
+        http.setAuthorization(authorizationPolicy);
+
+        try {
+            Book book = wc.get(Book.class);
+            assertEquals(123L, book.getId());
+        } catch (WebApplicationException ex) {
+            fail(ex.getMessage());
+        } catch (ProcessingException ex) {
+            if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+                fail(ex.getCause().getMessage());
+            } else {
+                fail(ex.getMessage());
+            }
+        }
+
+    }
+
+    @Test
     public void testGetBookSAMLTokenAsHeader() throws Exception {
         String address = "https://localhost:" + PORT + "/samlheader/bookstore/books/123";
 
@@ -271,4 +329,13 @@ public class JAXRSSamlTest extends AbstractBusClientServerTestBase {
         }
         return bean.createWebClient();
     }
+
+    private String encodeToken(String assertion) throws Base64Exception {
+        byte[] tokenBytes = assertion.getBytes(StandardCharsets.UTF_8);
+
+        tokenBytes = new DeflateEncoderDecoder().deflateToken(tokenBytes);
+        StringWriter writer = new StringWriter();
+        Base64Utility.encode(tokenBytes, 0, tokenBytes.length, writer);
+        return writer.toString();
+    }
 }
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlCallbackHandler.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlCallbackHandler.java
index 4d5bdfd..e8eff0a 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlCallbackHandler.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlCallbackHandler.java
@@ -88,7 +88,10 @@ public class SamlCallbackHandler implements CallbackHandler {
                 }
                 callback.setIssuer("https://idp.example.org/SAML2");
 
-                String subjectName = (String)m.getContextualProperty("saml.subject.name");
+                String subjectName = null;
+                if (m != null) {
+                    subjectName = (String)m.getContextualProperty("saml.subject.name");
+                }
                 if (subjectName == null) {
                     subjectName = "uid=sts-client,o=mock-sts.com";
                 }
@@ -149,7 +152,10 @@ public class SamlCallbackHandler implements CallbackHandler {
                 AttributeStatementBean attrBean = new AttributeStatementBean();
                 attrBean.setSubject(subjectBean);
 
-                List<String> roles = CastUtils.cast((List<?>)m.getContextualProperty("saml.roles"));
+                List<String> roles = null;
+                if (m != null) {
+                    roles = CastUtils.cast((List<?>)m.getContextualProperty("saml.roles"));
+                }
                 if (roles == null) {
                     roles = Collections.singletonList("user");
                 }
@@ -161,7 +167,10 @@ public class SamlCallbackHandler implements CallbackHandler {
                 roleClaim.setAttributeValues(new ArrayList<>(roles));
                 claims.add(roleClaim);
 
-                List<String> authMethods = CastUtils.cast((List<?>)m.getContextualProperty("saml.auth"));
+                List<String> authMethods = null;
+                if (m != null) {
+                    authMethods = CastUtils.cast((List<?>)m.getContextualProperty("saml.auth"));
+                }
                 if (authMethods == null) {
                     authMethods = Collections.singletonList("password");
                 }

-- 
To stop receiving notification emails like this one, please contact
coheigea@apache.org.