[picketlink-commits] Picketlink SVN: r1563 - in product/trunk/picketlink-core/src/main/java/org/picketlink: identity/federation/core/util and 2 other directories.

picketlink-commits at lists.jboss.org picketlink-commits at lists.jboss.org
Wed Jul 4 10:43:51 EDT 2012


Author: pskopek at redhat.com
Date: 2012-07-04 10:43:50 -0400 (Wed, 04 Jul 2012)
New Revision: 1563

Added:
   product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenValidation.java
   product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/MapBasedTokenHandler.java
Modified:
   product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/ErrorCodes.java
   product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/util/SOAPUtil.java
   product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java
   product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/jaas/JBWSTokenIssuingLoginModule.java
Log:
backport of [PRODMGT-153] Adding ability to use customer's own login module and
supply binary security token in JAAS sharedState Map and use in new MapBasedTokenHandler to send it to STS.


Modified: product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/ErrorCodes.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/ErrorCodes.java	2012-06-12 14:15:37 UTC (rev 1562)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/ErrorCodes.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -191,4 +191,6 @@
    String WRITER_UNSUPPORTED_ATTRIB_VALUE = "PL00084: Writer: Unsupported Attribute Value:";
 
    String WRONG_TYPE = "PL00095: Wrong type:";
+   
+   String SOAP_MESSAGE_DUMP_ERROR = "PL00104: Error while dumping SOAP message:";
 }
\ No newline at end of file

Modified: product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/util/SOAPUtil.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/util/SOAPUtil.java	2012-06-12 14:15:37 UTC (rev 1562)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/identity/federation/core/util/SOAPUtil.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -21,6 +21,7 @@
  */
 package org.picketlink.identity.federation.core.util;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
@@ -33,6 +34,7 @@
 import javax.xml.soap.SOAPMessage;
 import javax.xml.transform.Source;
 
+import org.picketlink.identity.federation.core.ErrorCodes;
 import org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil;
 import org.w3c.dom.Document;
 
@@ -116,4 +118,20 @@
          throw new RuntimeException(e);
       }
    }
+   
+   /**
+    * Utility method to dump soapMessage to String.
+    * Used for logging purpose. Use only with TRACE level, please. 
+    * @param soapMessage
+    * @return String representation of soapMessage
+    */
+   public static String soapMessageAsString(SOAPMessage soapMessage) {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      try {
+         soapMessage.writeTo(baos);
+      } catch (Exception almostIgnored) {
+         return ErrorCodes.SOAP_MESSAGE_DUMP_ERROR + almostIgnored;
+      }
+      return baos.toString();
+   }   
 }
\ No newline at end of file

Modified: product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java	2012-06-12 14:15:37 UTC (rev 1562)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenHandler.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -39,6 +39,7 @@
 import javax.xml.ws.handler.soap.SOAPMessageContext;
 
 import org.picketlink.identity.federation.core.ErrorCodes;
+import org.picketlink.identity.federation.core.util.SOAPUtil;
 import org.picketlink.identity.federation.core.util.StringUtil;
 import org.picketlink.trust.jbossws.Constants;
 import org.picketlink.trust.jbossws.Util;
@@ -93,7 +94,7 @@
     * 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");
+           "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
    
    /**
     * Attribute value for the ValueType attribute
@@ -259,15 +260,7 @@
       }
       if( trace)
       {
-         log.trace("SOAP Message=");
-         try
-         {
-            sm.writeTo(System.out);
-         }
-         catch (Exception ignore)
-         {    
-            log.trace("Exception tracing out SOAP Message", ignore);
-         }
+         log.trace("SOAP Message=" + SOAPUtil.soapMessageAsString(sm));
       }
       return true; 
    } 

Added: product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenValidation.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenValidation.java	                        (rev 0)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/BinaryTokenValidation.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -0,0 +1,33 @@
+/*
+ * 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 javax.xml.ws.handler.MessageContext;
+
+/**
+ * Interface for token validation to be supplied to @MapBasedTokenHandler and @BinaryTokenHandler.
+ * @author pskopek
+ *
+ */
+public interface BinaryTokenValidation {
+   public boolean validateBinaryToken(Object token, MessageContext msgContext);
+}

Added: product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/MapBasedTokenHandler.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/MapBasedTokenHandler.java	                        (rev 0)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/handler/MapBasedTokenHandler.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -0,0 +1,317 @@
+/*
+ * 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.Map;
+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.jboss.logging.Logger;
+import org.picketlink.identity.federation.core.ErrorCodes;
+import org.picketlink.identity.federation.core.util.SOAPUtil;
+import org.picketlink.trust.jbossws.Constants;
+import org.picketlink.trust.jbossws.Util;
+
+/**
+ * <p>
+ * Handler that looks for a binary token data that exists in jaasOptionsMap supplied in constructor.
+ * </p>
+ * <p>
+ * <b>Configuration:</b>
+ * <p>
+ * <i>System Properties:</i>
+ * <ul>
+ * <li>map.token.key: key which will be used to fetch binary token from the jaasOptionsMap. Default value is ClientID</li>
+ * <li>map.token.validation.class.key: validation class for binary token inside handleInbound method</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>
+ * </ul>
+ * <i>Setters:</i>
+ * <p>
+ * Please see the see also section.
+ * </p>
+ * 
+ * @see #setEncodingType(String)
+ * @see #setValueType(String)
+ * @see #setValueTypeNamespace(String)
+ * @see #setValueTypePrefix(String) </p> </p>
+ * @author Anil.Saldhana at redhat.com
+ * @author pskopek at redhat.com
+ * @since Jun 11, 2012
+ */
+public class MapBasedTokenHandler extends AbstractPicketLinkTrustHandler {
+
+    public static final String SYS_PROP_TOKEN_KEY = "map.token.key";
+    public static final String DEFAULT_TOKEN_KEY = "ClientID";
+
+    
+    /**
+     * The JAAS shared options map key name for binary token to be stored in.
+     */
+    public final String tokenOptionKey = SecurityActions.getSystemProperty(
+            SYS_PROP_TOKEN_KEY, "ClientID");
+
+    /**
+     * Key in the JAAS options map to find class name to validate token in
+     * inbound message handle method.
+     */
+    public final String validationTokenClassKey = SecurityActions
+            .getSystemProperty("map.token.validation.class.key",
+                    "tokenValidationClass");
+
+    /**
+     * 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);
+
+    private SOAPFactory factory = null;
+
+    /**
+     * Shared options from calling login module (@see
+     * 
+     * @JBWSTokenIssuingLoginModule).
+     */
+    private Map<String, ?> jaasLoginModuleOptions = null;
+
+    public MapBasedTokenHandler(Map<String, ?> jaasOptionsMap) {
+        jaasLoginModuleOptions = jaasOptionsMap;
+    }
+
+    /**
+     * <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;
+    }
+
+    @Override
+    protected boolean handleInbound(MessageContext msgContext) {
+        if (trace) {
+            log.trace("Handling Inbound Message");
+        }
+
+        String tokenValidation = (String) jaasLoginModuleOptions
+                .get(validationTokenClassKey);
+        if (tokenValidation == null) {
+            return true;
+        }
+
+        BinaryTokenValidation validation = null;
+        try {
+            ClassLoader cl = SecurityActions.getClassLoader(getClass());
+            validation = (BinaryTokenValidation) cl.loadClass(tokenValidation)
+                    .newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(ErrorCodes.CLASS_NOT_LOADED
+                    + "Class not loaded:" + tokenValidation, e);
+        }
+        String token = getToken(msgContext);
+        if (trace) {
+            log.trace("Validating token=" + token);
+        }
+
+        return validation.validateBinaryToken(token, msgContext);
+    }
+
+    @Override
+    protected boolean handleOutbound(MessageContext msgContext) {
+        if (trace) {
+            log.trace("Handling Outbound Message");
+        }
+
+        String token = (String) jaasLoginModuleOptions.get(tokenOptionKey);
+        if (token == null)
+            throw new RuntimeException(ErrorCodes.INJECTED_VALUE_MISSING
+                    + tokenOptionKey
+                    + " has to be set by calling LoginMoule in option map.");
+
+        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 binary token", e);
+        }
+        if (trace) {
+            log.trace("SOAP Message=" + SOAPUtil.soapMessageAsString(sm));
+        }
+        return true;
+    }
+
+    /**
+     * 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;
+    }
+
+    private String getToken(MessageContext msgContext) {
+
+        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");
+            }
+            return Util.findElementByWsuId(header, "BinarySecurityToken")
+                    .getTextContent();
+
+        } catch (SOAPException e) {
+            log.error("Unable to create binary token", e);
+            return null;
+        }
+    }
+
+}
\ No newline at end of file

Modified: product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/jaas/JBWSTokenIssuingLoginModule.java
===================================================================
--- product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/jaas/JBWSTokenIssuingLoginModule.java	2012-06-12 14:15:37 UTC (rev 1562)
+++ product/trunk/picketlink-core/src/main/java/org/picketlink/trust/jbossws/jaas/JBWSTokenIssuingLoginModule.java	2012-07-04 14:43:50 UTC (rev 1563)
@@ -22,6 +22,7 @@
 package org.picketlink.trust.jbossws.jaas;
 
 import java.security.Principal;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -44,6 +45,7 @@
 import org.picketlink.identity.federation.core.wstrust.auth.STSIssuingLoginModule;
 import org.picketlink.trust.jbossws.PicketLinkDispatch;
 import org.picketlink.trust.jbossws.handler.BinaryTokenHandler;
+import org.picketlink.trust.jbossws.handler.MapBasedTokenHandler;
 import org.picketlink.trust.jbossws.handler.SAML2Handler;
 
 /**
@@ -74,10 +76,24 @@
    }
 
    @Override
-   protected STSClient createWSTrustClient(STSClientConfig config)
-   { 
-      return new JBWSTokenClient(config,options);
-   }  
+   protected STSClient createWSTrustClient(STSClientConfig config) {
+
+      String binaryTokenKey = (String) options
+            .get(MapBasedTokenHandler.SYS_PROP_TOKEN_KEY);
+      if (binaryTokenKey == null) {
+         binaryTokenKey = SecurityActions.getSystemProperty(
+               MapBasedTokenHandler.SYS_PROP_TOKEN_KEY,
+               MapBasedTokenHandler.DEFAULT_TOKEN_KEY);
+      }
+      Object binaryToken = sharedState.get(binaryTokenKey);
+
+      Map<String, ? super Object> STSClientOptions = new HashMap<String, Object>(options);
+      if (binaryToken != null) {
+         STSClientOptions.put(binaryTokenKey, binaryToken);
+      }
+
+      return new JBWSTokenClient(config, STSClientOptions);
+   }
    
    @SuppressWarnings("unchecked")
    @Override
@@ -125,7 +141,7 @@
       }
       
       @SuppressWarnings("rawtypes")
-      public JBWSTokenClient(STSClientConfig config, Map<String,?> options)
+      public JBWSTokenClient(STSClientConfig config, Map<String, ? super Object> options)
       {
          super(config); 
          
@@ -168,6 +184,10 @@
                   SAML2Handler samlHandler = new SAML2Handler();
                   handlers.add(samlHandler);
                } 
+               else if (token.equalsIgnoreCase("map")) {
+                  MapBasedTokenHandler mapBasedHandler = new MapBasedTokenHandler(options);
+                  handlers.add(mapBasedHandler);
+               }   
                else
                {
                   ClassLoader cl = SecurityActions.getClassLoader(getClass());



More information about the picketlink-commits mailing list