cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1146045 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/
Date Wed, 13 Jul 2011 14:07:19 GMT
Author: sergeyb
Date: Wed Jul 13 14:07:18 2011
New Revision: 1146045

URL: http://svn.apache.org/viewvc?rev=1146045&view=rev
Log:
[CXF-3588] Some refactoring of plain SAML interceptors

Added:
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
  (with props)
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
  (with props)
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
  (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderInHandler.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderOutInterceptor.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java?rev=1146045&r1=1146044&r2=1146045&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
Wed Jul 13 14:07:18 2011
@@ -62,6 +62,12 @@ public class FormEncodingProvider implem
     private String attachmentDir;
     private String attachmentThreshold;
 
+    private boolean expectEncoded;
+    
+    public void setExpectedEncoded(boolean expect) {
+        this.expectEncoded = expect;
+    }
+    
     public void setAttachmentDirectory(String dir) {
         attachmentDir = dir;
     }
@@ -94,8 +100,7 @@ public class FormEncodingProvider implem
             }
             
             MultivaluedMap<String, String> params = createMap(clazz);
-            populateMap(params, is, mt,
-                        AnnotationUtils.getAnnotation(annotations, Encoded.class) == null);
+            populateMap(params, is, mt, !keepEncoded(annotations));
             validateMap(params);
             
             persistParamsOnMessage(params);
@@ -108,6 +113,11 @@ public class FormEncodingProvider implem
         }
     }
 
+    protected boolean keepEncoded(Annotation[] anns) {
+        return AnnotationUtils.getAnnotation(anns, Encoded.class) != null 
+               || expectEncoded;
+    }
+    
     protected void persistParamsOnMessage(MultivaluedMap<String, String> params) {
         Message message = PhaseInterceptorChain.getCurrentMessage();
         if (message != null) {
@@ -180,7 +190,7 @@ public class FormEncodingProvider implem
         
         MultivaluedMap<String, String> map = 
             (MultivaluedMap<String, String>)(obj instanceof Form ? ((Form)obj).getData()
: obj);
-        boolean encoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null;
+        boolean encoded = keepEncoded(anns);
         
         String encoding = HttpUtils.getSetEncoding(mt, headers, "UTF-8");
         

Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java?rev=1146045&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
(added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
Wed Jul 13 14:07:18 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.systest.jaxrs.security.saml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.zip.DataFormatException;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.message.Message;
+
+public abstract class AbstractSamlBase64InHandler extends AbstractSamlInHandler {
+
+    private boolean useDeflateEncoding = true;
+    
+    public void setUseDeflateEncoding(boolean deflate) {
+        useDeflateEncoding = deflate;
+    }
+    public boolean useDeflateEncoding() {
+        return useDeflateEncoding;
+    }
+    
+    protected void handleToken(Message message, String assertion) {
+        // the assumption here is that saml:Assertion is directly available, however, it

+        // may be contained inside saml:Response or saml:ArtifactResponse/saml:Response
+        if (assertion == null) {
+            throwFault("SAML assertion is not available", null);
+        }
+        
+        try {
+            byte[] deflatedToken = Base64Utility.decode(assertion);
+            InputStream is = useDeflateEncoding() 
+                ? new DeflateEncoderDecoder().inflateToken(deflatedToken)
+                : new ByteArrayInputStream(deflatedToken); 
+            validateToken(message, is); 
+        } catch (Base64Exception ex) {
+            throwFault("Base64 decoding has failed", ex);
+        } catch (DataFormatException ex) {
+            throwFault("Encoded assertion can not be inflated", ex);
+        }         
+    }
+}

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlBase64InHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java?rev=1146045&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
(added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
Wed Jul 13 14:07:18 2011
@@ -0,0 +1,68 @@
+/**
+ * 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.systest.jaxrs.security.saml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+public class DeflateEncoderDecoder {
+    public InputStream inflateToken(byte[] deflatedToken) 
+        throws DataFormatException {
+        Inflater inflater = new Inflater();
+        inflater.setInput(deflatedToken);
+        
+        byte[] input = new byte[deflatedToken.length * 2];
+        
+        int inflatedLen = 0;
+        int inputLen = 0;
+        byte[] inflatedToken = input;
+        while (!inflater.finished()) {
+            inputLen = inflater.inflate(input);
+            if (!inflater.finished()) {
+                inflatedToken = new byte[input.length + inflatedLen];
+                System.arraycopy(input, 0, inflatedToken, inflatedLen, inputLen);
+                inflatedLen += inputLen;
+            }
+        }
+        InputStream is = new ByteArrayInputStream(input, 0, inputLen);
+        if (inflatedToken != input) {
+            is = new SequenceInputStream(new ByteArrayInputStream(inflatedToken, 0, inflatedLen),
+                                         is);
+        }
+        return is;
+    }
+    
+    public byte[] deflateToken(byte[] tokenBytes) {
+        Deflater compresser = new Deflater();
+        
+        compresser.setInput(tokenBytes);
+        compresser.finish();
+        
+        byte[] output = new byte[tokenBytes.length];
+        
+        int compressedDataLength = compresser.deflate(output);
+        byte[] result = new byte[compressedDataLength];
+        System.arraycopy(output, 0, result, 0, compressedDataLength);
+        return result;
+    }
+}

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/DeflateEncoderDecoder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java?rev=1146045&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
(added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
Wed Jul 13 14:07:18 2011
@@ -0,0 +1,92 @@
+/**
+ * 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.systest.jaxrs.security.saml;
+
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.net.URI;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.ext.form.Form;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.UriInfoImpl;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.provider.FormEncodingProvider;
+import org.apache.cxf.message.Message;
+
+public class SamlFormInHandler extends AbstractSamlBase64InHandler {
+
+    private static final String SAML_ELEMENT = "SAMLToken";
+    private static final String SAML_RELAY_STATE = "RelayState";
+   
+    private FormEncodingProvider provider = new FormEncodingProvider();
+    
+    public SamlFormInHandler() {
+        provider.setExpectedEncoded(true);
+    }
+    
+    public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
+        
+        Form form = readFormData(message);    
+        String assertion = form.getData().getFirst(SAML_ELEMENT);
+        
+        handleToken(message, assertion);         
+
+        // redirect if needed
+        String samlRequestURI = form.getData().getFirst(SAML_RELAY_STATE);
+        if (samlRequestURI != null) {
+            // RelayState may actually represent a reference to a transient local state
+            // containing the actual REQUEST URI client was using before being redirected

+            // back to IDP - at the moment assume it's URI
+            UriInfoImpl ui = new UriInfoImpl(message); 
+            if (!samlRequestURI.startsWith(ui.getBaseUri().toString())) {
+                return Response.status(302).location(URI.create(samlRequestURI)).build();
+            }
+        }
+        // restore input stream
+        CachedOutputStream os = new CachedOutputStream(); 
+        form.getData().remove(SAML_ELEMENT);
+        form.getData().remove(SAML_RELAY_STATE);
+        try {
+            provider.writeTo(form, Form.class, Form.class, new Annotation[]{}, 
+                MediaType.APPLICATION_FORM_URLENCODED_TYPE, new MetadataMap<String, Object>(),
os);
+            message.setContent(InputStream.class, os.getInputStream());
+        } catch (Exception ex) {
+            throwFault(ex.getMessage(), ex);
+        }
+        return null;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Form readFormData(Message message) {
+        try {
+            return (Form)provider.readFrom((Class)Form.class, Form.class, 
+                              new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE,

+                              new MetadataMap<String, String>(), 
+                              message.getContent(InputStream.class));
+        } catch (Exception ex) {
+            throwFault("Error reading the form", ex);    
+        }
+        return null;
+    }
+}

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlFormInHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderInHandler.java?rev=1146045&r1=1146044&r2=1146045&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderInHandler.java
(original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderInHandler.java
Wed Jul 13 14:07:18 2011
@@ -19,23 +19,16 @@
 
 package org.apache.cxf.systest.jaxrs.security.saml;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
 import java.util.List;
-import java.util.zip.DataFormatException;
-import java.util.zip.Inflater;
 
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 
-import org.apache.cxf.common.util.Base64Exception;
-import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.message.Message;
 
-public class SamlHeaderInHandler extends AbstractSamlInHandler {
+public class SamlHeaderInHandler extends AbstractSamlBase64InHandler {
 
     private static final String SAML_AUTH = "SAML";
     
@@ -54,41 +47,10 @@ public class SamlHeaderInHandler extends
             throwFault("Authorization header is malformed", null);
         }
         
-        try {
-            validateToken(message, decodeAndInflateToken(parts[1])); 
-        } catch (Base64Exception ex) {
-            throwFault("Base64 decoding has failed", ex);
-        } catch (DataFormatException ex) {
-            throwFault("Encoded assertion can not be inflated", ex);
-        }         
+        handleToken(message, parts[1]);         
         return null;
     }
 
     
-    private InputStream decodeAndInflateToken(String encodedToken) 
-        throws DataFormatException, Base64Exception {
-        byte[] deflatedToken = Base64Utility.decode(encodedToken);
-        Inflater inflater = new Inflater();
-        inflater.setInput(deflatedToken);
-        
-        byte[] input = new byte[deflatedToken.length * 2];
-        
-        int inflatedLen = 0;
-        int inputLen = 0;
-        byte[] inflatedToken = input;
-        while (!inflater.finished()) {
-            inputLen = inflater.inflate(input);
-            if (!inflater.finished()) {
-                inflatedToken = new byte[input.length + inflatedLen];
-                System.arraycopy(input, 0, inflatedToken, inflatedLen, inputLen);
-                inflatedLen += inputLen;
-            }
-        }
-        InputStream is = new ByteArrayInputStream(input, 0, inputLen);
-        if (inflatedToken != input) {
-            is = new SequenceInputStream(new ByteArrayInputStream(inflatedToken, 0, inflatedLen),
-                                         is);
-        }
-        return is;
-    }
+    
 }

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderOutInterceptor.java?rev=1146045&r1=1146044&r2=1146045&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderOutInterceptor.java
(original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/SamlHeaderOutInterceptor.java
Wed Jul 13 14:07:18 2011
@@ -26,7 +26,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
-import java.util.zip.Deflater;
 
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.Base64Exception;
@@ -40,13 +39,20 @@ public class SamlHeaderOutInterceptor ex
     private static final Logger LOG = 
         LogUtils.getL7dLogger(SamlHeaderOutInterceptor.class);
     
+    private boolean useDeflateEncoding = true;
+    
     public SamlHeaderOutInterceptor() {
     } 
 
+    public void setUseDeflateEncoding(boolean deflate) {
+        useDeflateEncoding = deflate;
+    }
+    
     public void handleMessage(Message message) throws Fault {
-        AssertionWrapper assertion = createAssertion(message);
+        AssertionWrapper assertionWrapper = createAssertion(message);
         try {
-            String encodedToken = deflateAndEncodeToken(assertion.assertionToString());
+            
+            String encodedToken = encodeToken(assertionWrapper.assertionToString());
             
             Map<String, List<String>> headers = 
                 CastUtils.cast((Map)message.get(Message.PROTOCOL_HEADERS));
@@ -68,25 +74,18 @@ public class SamlHeaderOutInterceptor ex
         
     }
         
-    
-    private String deflateAndEncodeToken(String token) throws Base64Exception {
-        Deflater compresser = new Deflater();
+    private String encodeToken(String assertion) throws Base64Exception {
         byte[] tokenBytes = null;
         try {
-            tokenBytes = token.getBytes("UTF-8");
-            compresser.setInput(tokenBytes);
+            tokenBytes = assertion.getBytes("UTF-8");
         } catch (UnsupportedEncodingException ex) {
             // won't happen
         }
-        compresser.finish();
-        
-        byte[] output = new byte[tokenBytes.length];
-        
-        int compressedDataLength = compresser.deflate(output);
-        
+        if (useDeflateEncoding) {
+            tokenBytes = new DeflateEncoderDecoder().deflateToken(tokenBytes);
+        }
         StringWriter writer = new StringWriter();
-        Base64Utility.encode(output, 0, compressedDataLength, writer);
+        Base64Utility.encode(tokenBytes, 0, tokenBytes.length, writer);
         return writer.toString();
     }
-    
 }



Mime
View raw message