[jboss-cvs] Picketlink SVN: r864 - in trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws: handler and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Apr 6 12:14:24 EDT 2011


Author: anil.saldhana at jboss.com
Date: 2011-04-06 12:14:24 -0400 (Wed, 06 Apr 2011)
New Revision: 864

Added:
   trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java
Modified:
   trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/Constants.java
   trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/SecurityActions.java
Log:
PLFED-162: a binary token handler to pick from http header or http cookie

Modified: trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/Constants.java
===================================================================
--- trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/Constants.java	2011-04-05 17:22:13 UTC (rev 863)
+++ trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/Constants.java	2011-04-06 16:14:24 UTC (rev 864)
@@ -27,14 +27,23 @@
 
 /**
  * @author Jason T. Greene
+ * @author Anil Saldhana
  */
 public class Constants
 {
    public static final String WSS_SOAP_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0";
+   
+   public static final String WSSE_LOCAL = "Security";
 
    public static final String WSSE_PREFIX = "wsse";
 
    public static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
+   
+   public static final String WSSE_BINARY_SECURITY_TOKEN = "BinarySecurityToken";
+   
+   public static final String WSSE_ENCODING_TYPE = "EncodingType";
+   
+   public static final String WSSE_VALUE_TYPE = "ValueType";
 
    public static final String WSU_PREFIX = "wsu";
 

Added: trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java
===================================================================
--- trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java	                        (rev 0)
+++ trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java	2011-04-06 16:14:24 UTC (rev 864)
@@ -0,0 +1,377 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketlink.trust.jbossws.handler;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFactory;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+import org.apache.log4j.Logger;
+import org.jboss.wsf.common.handler.GenericSOAPHandler;
+import org.picketlink.trust.jbossws.Constants;
+import org.picketlink.trust.jbossws.Util;
+
+/**
+ * <p>
+ * Handler that looks for a binary data that exists
+ * in the HTTP payload either as a header or a cookie
+ * based on configuration.
+ * </p>
+ * <p>
+ * <b>Configuration:</b>
+ * <p>
+ * <i>System Properties:</i>
+ * <ul>
+ *   <li>binary.http.header: http header name</li>
+ *   <li>binary.http.cookie: http cookie name</li>
+ *   <li>binary.http.encodingType: attribute value of the EncodingType attribute</li>
+ *   <li>binary.http.valueType: attribute value of the ValueType attribute</li>
+ *   <li>binary.http.valueType.namespace: namespace for the ValueType attribute</li>
+ *   <li>binary.http.valueType.prefix: namespace for the ValueType attribute</li>
+ *   <li>binary.http.cleanToken: true or false dependending on whether the binary token has to be cleaned</li>
+ * </ul>
+ * <i>Setters:</i>
+ * <p> Please see the see also section. </p>
+ * 
+ * @see #setHttpHeaderName(String)
+ * @see #setHttpCookieName(String)
+ * @see #setEncodingType(String)
+ * @see #setValueType(String)
+ * @see #setValueTypeNamespace(String)
+ * @see #setValueTypePrefix(String)
+ * @see #setCleanToken(boolean)
+ * </p>
+ * </p>
+ * @author Anil.Saldhana at redhat.com
+ * @since Apr 5, 2011
+ */
+ at SuppressWarnings("rawtypes")
+public class BinaryTokenHandler extends GenericSOAPHandler
+{
+   protected static Logger log = Logger.getLogger(BinaryTokenHandler.class);
+   protected boolean trace = log.isTraceEnabled();
+   
+   private static Set<QName> headers;
+
+   /**
+    * The HTTP header name that this token looks for. Either this or the httpCookieName should be set.
+    */
+   private String httpHeaderName = SecurityActions.getSystemProperty("binary.http.header", null);
+   
+   /**
+    * The HTTP cookie name that this token looks for. Either this or the httpHeaderName should be set.
+    */
+   private String httpCookieName = SecurityActions.getSystemProperty("binary.http.cookie", null);
+    
+   /**
+    * Attribute value for the EncodingType attribute
+    */
+   private String encodingType = SecurityActions.getSystemProperty("binary.http.encodingType", 
+           "http://docs.oasis-open.org/wss/2004/01/ oasis-200401-wss-soap-message-security-1.0#Base64Binary");
+   
+   /**
+    * Attribute value for the ValueType attribute
+    */
+   private String valueType = SecurityActions.getSystemProperty("binary.http.valueType", null);
+   
+   /**
+    * Namespace for the ValueType. Can be null. If null, then a separate namespace is not added.
+    */
+   private String valueTypeNamespace = SecurityActions.getSystemProperty("binary.http.valueType.namespace", null);
+   
+   /**
+    * Prefix for the ValueType. Can be null. 
+    */
+   private String valueTypePrefix = SecurityActions.getSystemProperty("binary.http.valueType.prefix", null);
+   
+   /**
+    * Some binary tokens need to be cleaned. This handler just cleans upto the first blank space and discards before that.
+    */
+   private boolean cleanToken = Boolean.parseBoolean(SecurityActions.getSystemProperty("binary.http.cleanToken", "false"));
+   
+   private SOAPFactory factory = null;
+
+   static
+   {
+      HashSet<QName> set = new HashSet<QName>();
+      set.add(Constants.WSSE_HEADER_QNAME);
+      headers = Collections.unmodifiableSet(set);
+   } 
+   
+   /**
+    * <p> Set the EncodingType value.</p>
+    * <p> Alternatively, set the system property "binary.http.encodingType"</p>
+    * 
+    * @param binaryEncodingType
+    */
+   public void setEncodingType(String binaryEncodingType)
+   {
+      this.encodingType = binaryEncodingType;
+   }
+
+   /**
+    * <p> Set the Value type</p>
+    * <p> Alternatively, set the system property "binary.http.valueType"</p>
+    * 
+    * @param binaryValueType
+    */
+   public void setValueType(String binaryValueType)
+   {
+      this.valueType = binaryValueType;
+   }
+
+   /**
+    * <p> Set the ValueType Namespace </p>
+    * <p> Alternatively, set the system property "binary.http.valueType.namespace"</p>
+    * 
+    * @param binaryValueNamespace
+    */
+   public void setValueTypeNamespace(String binaryValueNamespace)
+   {
+      this.valueTypeNamespace = binaryValueNamespace;
+   }
+
+   /**
+    * <p> Set the Value Type Prefix </p>
+    * <p> Alternatively, set the system property "binary.http.valueType.prefix" </p>
+    * 
+    * @param binaryValuePrefix
+    */
+   public void setValueTypePrefix(String binaryValuePrefix)
+   {
+      this.valueTypePrefix = binaryValuePrefix;
+   }
+
+   public Set<QName> getHeaders()
+   {
+      //return a collection with just the wsse:Security header to pass the MustUnderstand check on it
+      return headers;
+   }
+
+   /**
+    * <p>
+    * Set the Http Header Name
+    * </p>
+    * <p>
+    * Alternatively, set the system property: "binary.http.header"
+    * </p>
+    * 
+    * @param http
+    */
+   public void setHttpHeaderName(String http)
+   {
+      httpHeaderName = http;
+   }
+
+   /**
+    * <p>
+    * Set the Http Cookie Name
+    * </p>
+    * <p>
+    * Alternatively, set the system property: ""binary.http.cookie"
+    * </p>
+    * 
+    * @param http
+    */
+   public void setHttpCookieName(String http)
+   {
+      httpCookieName = http;
+   }
+   
+   /**
+    * <p>
+    * Should we not clean the extracted binary token.
+    * </p>
+    * <p>
+    * Alternatively, set the system property: "binary.http.cleanToken"
+    * </p>
+    * 
+    * @param clean
+    */
+   public void setCleanToken( boolean clean)
+   {
+      this.cleanToken = clean;
+   }
+   
+   @Override
+   protected boolean handleOutbound(MessageContext msgContext)
+   {
+      if( httpHeaderName == null && httpCookieName == null )
+         throw new RuntimeException("Either httpHeaderName or httpCookieName should be set" );
+      
+      HttpServletRequest servletRequest = getHttpRequest(msgContext);
+      if( servletRequest == null )
+         throw new IllegalStateException("Unable to proceed as Http request is null"); 
+       
+      String token = getTokenValue(servletRequest);
+      if(token==null)
+         throw new IllegalStateException("Null Token");
+      SOAPElement security = null;
+      try
+      {
+         security = create(token);
+      }
+      catch (SOAPException e)
+      {  
+         log.error("Unable to create binary token", e);
+      }
+      if( security == null)
+      {
+         log.warn("Was not able to create security token. Just sending message without binary token");
+         return true;
+      }
+      SOAPMessage sm = ((SOAPMessageContext)msgContext).getMessage();
+      SOAPEnvelope envelope;
+      try
+      {
+         envelope = sm.getSOAPPart().getEnvelope();
+         SOAPHeader header = (SOAPHeader)Util.
+         findElement(envelope, new QName(envelope.getNamespaceURI(), "Header"));
+         if (header == null)
+         {
+            header = (SOAPHeader)envelope.getOwnerDocument().createElementNS(
+                  envelope.getNamespaceURI(), envelope.getPrefix() + ":Header");
+            envelope.insertBefore(header, envelope.getFirstChild());
+         }
+         header.addChildElement(security);
+      }
+      catch (SOAPException e)
+      {  
+         log.error("Unable to create WSSE Binary Header::",e);
+      }
+      return true; 
+   } 
+   
+   /**
+    * Get the {@link HttpServletRequest} from the {@link MessageContext}
+    * @param msgContext
+    * @return
+    */
+   private HttpServletRequest getHttpRequest(MessageContext msgContext)
+   {
+      return (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
+   }
+   
+   /**
+    * Given the {@link HttpServletRequest}, look for the http header or
+    * the cookie depending on the configuration
+    * @param http
+    * @return
+    */
+   private String getTokenValue(HttpServletRequest http)
+   {
+      if( httpHeaderName!= null && !httpHeaderName.isEmpty())
+      {
+         String header = http.getHeader(httpHeaderName);
+         if( header != null)
+            return clean(header);
+      } 
+      if( httpCookieName != null && !httpCookieName.isEmpty())
+      {
+         Cookie[] cookies = http.getCookies();
+         if( cookies != null )
+         {
+            for(Cookie cookie: cookies)
+            {
+               if(cookie.getName().equals(httpCookieName))
+               {
+                  return clean(cookie.getValue());
+               }
+            }
+         }
+      }
+      return null;
+   }
+   
+   /**
+    * Given a binary token, create a {@link SOAPElement}
+    * @param token
+    * @return
+    * @throws SOAPException
+    */
+   private SOAPElement create(String token) throws SOAPException
+   {
+      if(factory == null)
+         factory = SOAPFactory.newInstance();
+      SOAPElement security = factory.createElement(Constants.WSSE_LOCAL, Constants.WSSE_PREFIX, Constants.WSSE_NS); 
+
+      if (valueTypeNamespace != null)
+      {
+         security.addNamespaceDeclaration(valueTypePrefix, valueTypeNamespace);
+      } 
+
+      SOAPElement binarySecurityToken = factory.
+      createElement(Constants.WSSE_BINARY_SECURITY_TOKEN, Constants.WSSE_PREFIX, Constants.WSSE_NS);
+      binarySecurityToken.addTextNode(token);
+      if( valueType != null && !valueType.isEmpty())
+      {
+         binarySecurityToken.setAttribute(Constants.WSSE_VALUE_TYPE, valueType);
+      }
+      if (encodingType != null)
+      {
+         binarySecurityToken.setAttribute(Constants.WSSE_ENCODING_TYPE, encodingType);
+      }
+
+      security.addChildElement(binarySecurityToken);
+      return security; 
+   }
+   
+   /**
+    * Some 3rd party systems send in the binary token in the format Discardable<space>ValidToken
+    * @param value
+    * @return
+    */
+   private String clean(String value)
+   {
+      if( trace)
+      {
+         log.trace("Cleaning:"+value);
+      }
+      int i= -1;
+      
+      if( cleanToken)
+      {
+         value = value.trim();
+         while((i = value.indexOf(' ')) != -1)
+         {
+             value = value.substring(i + 1);
+         }         
+      }
+      if(trace)
+      {
+         log.trace("Cleaned:"+value);
+      }
+      return value;
+   }
+}
\ No newline at end of file

Modified: trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/SecurityActions.java
===================================================================
--- trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/SecurityActions.java	2011-04-05 17:22:13 UTC (rev 863)
+++ trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/SecurityActions.java	2011-04-06 16:14:24 UTC (rev 864)
@@ -88,4 +88,21 @@
          }
       });
    }
+   
+   /**
+    * Get a system property
+    * @param key the property name
+    * @param defaultValue default value in absence of property
+    * @return
+    */
+   static String getSystemProperty( final String key, final String defaultValue)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<String>()
+      { 
+         public String run()
+         {
+            return System.getProperty(key, defaultValue);
+         }
+      });
+   }
 }
\ No newline at end of file



More information about the jboss-cvs-commits mailing list