You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2013/07/18 17:50:22 UTC

svn commit: r1504503 - in /chemistry/opencmis/trunk: chemistry-opencmis-android/chemistry-opencmis-android-client/ chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/

Author: fmui
Date: Thu Jul 18 15:50:22 2013
New Revision: 1504503

URL: http://svn.apache.org/r1504503
Log:
CMIS-692: added LTPA AuthenticationProvider

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java   (with props)
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java

Modified: chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml?rev=1504503&r1=1504502&r2=1504503&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml Thu Jul 18 15:50:22 2013
@@ -85,6 +85,7 @@
 									<fileset dir="${client-bindings}/${sourcefiles}">
 										<include name="**/*.java" />
 										<exclude name="**/spi/StandardAuthenticationProvider.*" />
+										<exclude name="**/spi/LTPAWSSecurityAuthenticationProvider.*" />
 										<exclude name="**/spi/local/**" />
 										<exclude name="**/spi/http/DefaultHttpInvoker.*" />
 										<exclude name="**/spi/webservices/**" />

Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java?rev=1504503&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java Thu Jul 18 15:50:22 2013
@@ -0,0 +1,154 @@
+/*
+ * 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.chemistry.opencmis.client.bindings.spi;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.Set;
+import java.util.TimeZone;
+
+import javax.security.auth.Subject;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Base64;
+import org.apache.chemistry.opencmis.commons.impl.ClassLoaderUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class LTPAWSSecurityAuthenticationProvider extends StandardAuthenticationProvider {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(LTPAWSSecurityAuthenticationProvider.class);
+
+    @Override
+    public Element getSOAPHeaders(Object portObject) {
+
+        String securityToken = getSecurityToken();
+
+        // Exit if no security token found
+        if (securityToken == null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("securityToken is null");
+            }
+            return null;
+        }
+
+        // Set time
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+        long created = System.currentTimeMillis();
+        long expires = created + 24 * 60 * 60 * 1000; // 24 hours
+
+        // Create the SOAP WSSecurity header
+        try {
+            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+
+            Element wsseSecurityElement = document.createElementNS(WSSE_NAMESPACE, "Security");
+
+            Element wsuTimestampElement = document.createElementNS(WSU_NAMESPACE, "Timestamp");
+            wsseSecurityElement.appendChild(wsuTimestampElement);
+
+            Element tsCreatedElement = document.createElementNS(WSU_NAMESPACE, "Created");
+            tsCreatedElement.appendChild(document.createTextNode(sdf.format(created)));
+            wsuTimestampElement.appendChild(tsCreatedElement);
+
+            Element tsExpiresElement = document.createElementNS(WSU_NAMESPACE, "Expires");
+            tsExpiresElement.appendChild(document.createTextNode(sdf.format(expires)));
+            wsuTimestampElement.appendChild(tsExpiresElement);
+
+            // Add the BinarySecurityToken (contains the LTPAv2 token)
+            Element wsseBinarySecurityTokenElement = document.createElementNS(WSSE_NAMESPACE, "BinarySecurityToken");
+            wsseBinarySecurityTokenElement.setAttribute("xmlns:wsu", WSU_NAMESPACE);
+            wsseBinarySecurityTokenElement.setAttribute("xmlns:wsst",
+                    "http://www.ibm.com/websphere/appserver/tokentype");
+            wsseBinarySecurityTokenElement.setAttribute("wsu:Id", "ltpa_20");
+            wsseBinarySecurityTokenElement.setAttribute("ValueType", "wsst:LTPAv2");
+            wsseBinarySecurityTokenElement.appendChild(document.createTextNode(securityToken));
+
+            // Append BinarySecurityToken to Security section
+            wsseSecurityElement.appendChild(wsseBinarySecurityTokenElement);
+
+            return wsseSecurityElement;
+        } catch (ParserConfigurationException e) {
+            // shouldn't happen...
+            throw new CmisRuntimeException("Could not build SOAP header: " + e.getMessage(), e);
+        }
+    }
+
+    private String getSecurityToken() {
+        try {
+            Class<?> wsSubjectClass = ClassLoaderUtil.loadClass("com.ibm.websphere.security.auth.WSSubject");
+            Class<?> wsCredentialClass = ClassLoaderUtil.loadClass("com.ibm.websphere.security.cred.WSCredential");
+
+            // Get current security subject
+            Method m = wsSubjectClass.getMethod("getRunAsSubject", new Class[0]);
+            Subject securitySubject = (Subject) m.invoke(null, new Object[0]);
+            if (securitySubject != null) {
+                // Get all security credentials from the security subject
+                Set<?> securityCredentials = securitySubject.getPublicCredentials(wsCredentialClass);
+
+                // Get the first credential
+                Object securityCredential = securityCredentials.iterator().next();
+                String user = invokeSecurityCredentialMethod(wsCredentialClass, securityCredential, "getSecurityName");
+
+                if (user.equalsIgnoreCase("UNAUTHENTICATED")) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("User = UNAUTHENTICATED");
+                    }
+                    return null;
+                }
+
+                byte[] token = invokeSecurityCredentialMethod(wsCredentialClass, securityCredential,
+                        "getCredentialToken");
+                if (token == null) {
+                    return null;
+                }
+
+                return Base64.encodeBytes(token);
+            }
+        } catch (Exception e) {
+            throw new CmisRuntimeException("Could not build SOAP header: " + e.getMessage(), e);
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T invokeSecurityCredentialMethod(Class<?> credentialClass, Object securityCredential, String methodName)
+            throws NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
+        Method m = credentialClass.getMethod(methodName, new Class[0]);
+        return (T) m.invoke(securityCredential, new Object[0]);
+    }
+
+    @Override
+    protected boolean getSendBasicAuth() {
+        return false;
+    }
+
+    @Override
+    protected boolean getSendUsernameToken() {
+        return false;
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/LTPAWSSecurityAuthenticationProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java?rev=1504503&r1=1504502&r2=1504503&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java Thu Jul 18 15:50:22 2013
@@ -29,6 +29,7 @@ import javax.xml.parsers.ParserConfigura
 
 import org.apache.chemistry.opencmis.client.bindings.spi.cookies.CmisCookieManager;
 import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
 import org.apache.chemistry.opencmis.commons.impl.Base64;
 import org.apache.chemistry.opencmis.commons.impl.DateTimeHelper;
 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
@@ -45,8 +46,8 @@ public class StandardAuthenticationProvi
 
     private static final long serialVersionUID = 1L;
 
-    private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
-    private static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+    protected static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
+    protected static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
 
     private boolean sendBasicAuth;
     private boolean sendUsernameToken;
@@ -57,14 +58,14 @@ public class StandardAuthenticationProvi
     public void setSession(BindingSession session) {
         super.setSession(session);
 
-        sendBasicAuth = isTrue(SessionParameter.AUTH_HTTP_BASIC);
-        sendUsernameToken = isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN);
+        sendBasicAuth = getSendBasicAuth();
+        sendUsernameToken = getSendUsernameToken();
 
-        if (isTrue(SessionParameter.COOKIES)) {
+        if (getHandleCookies()) {
             cookieManager = new CmisCookieManager();
         }
 
-        // authentication
+        // basic authentication
         if (sendBasicAuth) {
             // get user and password
             String user = getUser();
@@ -74,39 +75,19 @@ public class StandardAuthenticationProvi
             if (user != null) {
                 fixedHeaders.put("Authorization", createBasicAuthHeaderValue(user, password));
             }
+        }
 
+        // proxy authentication
+        if (getProxyUser() != null) {
             // get proxy user and password
             String proxyUser = getProxyUser();
             String proxyPassword = getProxyPassword();
 
-            // if no proxy user is set, don't set basic auth header
-            if (proxyUser != null) {
-                fixedHeaders.put("Proxy-Authorization", createBasicAuthHeaderValue(proxyUser, proxyPassword));
-            }
+            fixedHeaders.put("Proxy-Authorization", createBasicAuthHeaderValue(proxyUser, proxyPassword));
         }
 
         // other headers
-        int x = 0;
-        Object headerParam;
-        while ((headerParam = getSession().get(SessionParameter.HEADER + "." + x)) != null) {
-            String header = headerParam.toString();
-            int colon = header.indexOf(':');
-            if (colon > -1) {
-                String key = header.substring(0, colon).trim();
-                if (key.length() > 0) {
-                    String value = header.substring(colon + 1).trim();
-                    List<String> values = fixedHeaders.get(key);
-                    if (values == null) {
-                        fixedHeaders.put(key, Collections.singletonList(value));
-                    } else {
-                        List<String> newValues = new ArrayList<String>(values);
-                        newValues.add(value);
-                        fixedHeaders.put(key, newValues);
-                    }
-                }
-            }
-            x++;
-        }
+        addSessionParameterHeadersToFixedHeaders();
     }
 
     @Override
@@ -192,10 +173,8 @@ public class StandardAuthenticationProvi
             return wsseSecurityElement;
         } catch (ParserConfigurationException e) {
             // shouldn't happen...
-            e.printStackTrace();
+            throw new CmisRuntimeException("Could not build SOAP header: " + e.getMessage(), e);
         }
-
-        return null;
     }
 
     /**
@@ -207,6 +186,35 @@ public class StandardAuthenticationProvi
     }
 
     /**
+     * Adds the {@link SessionParameter.HEADER} to the fixed headers. This
+     * method should only be called from the {@link #setSession(BindingSession)}
+     * method to avoid threading issues.
+     */
+    protected void addSessionParameterHeadersToFixedHeaders() {
+        int x = 0;
+        Object headerParam;
+        while ((headerParam = getSession().get(SessionParameter.HEADER + "." + x)) != null) {
+            String header = headerParam.toString();
+            int colon = header.indexOf(':');
+            if (colon > -1) {
+                String key = header.substring(0, colon).trim();
+                if (key.length() > 0) {
+                    String value = header.substring(colon + 1).trim();
+                    List<String> values = fixedHeaders.get(key);
+                    if (values == null) {
+                        fixedHeaders.put(key, Collections.singletonList(value));
+                    } else {
+                        List<String> newValues = new ArrayList<String>(values);
+                        newValues.add(value);
+                        fixedHeaders.put(key, newValues);
+                    }
+                }
+            }
+            x++;
+        }
+    }
+
+    /**
      * Creates a basic authentication header value from a username and a
      * password.
      */
@@ -225,6 +233,28 @@ public class StandardAuthenticationProvi
     }
 
     /**
+     * Returns if a HTTP Basic Authentication header should be sent. (All
+     * bindings.)
+     */
+    protected boolean getSendBasicAuth() {
+        return isTrue(SessionParameter.AUTH_HTTP_BASIC);
+    }
+
+    /**
+     * Returns if a UsernameToken should be sent. (Web Services binding only.)
+     */
+    protected boolean getSendUsernameToken() {
+        return isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN);
+    }
+
+    /**
+     * Returns if the authentication provider should handle cookies.
+     */
+    protected boolean getHandleCookies() {
+        return isTrue(SessionParameter.COOKIES);
+    }
+
+    /**
      * Returns <code>true</code> if the given parameter exists in the session
      * and is set to true, <code>false</code> otherwise.
      */