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.
*/