cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1221366 [1/2] - in /cxf/trunk: rt/ws/security/src/main/java/org/apache/cxf/ws/security/ rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/ rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/ rt/ws/secu...
Date Tue, 20 Dec 2011 17:41:59 GMT
Author: coheigea
Date: Tue Dec 20 17:41:59 2011
New Revision: 1221366

URL: http://svn.apache.org/viewvc?rev=1221366&view=rev
Log:
[CXF-3635] - WS-Trust SPNego (WCF message level spnego)

Added:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/NegotiationUtils.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSInvoker.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenOutInterceptor.java
      - copied, changed from r1221333, cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoTokenInterceptorProvider.java
Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/WSSecurityPolicyLoader.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/SpnegoContextToken.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
    cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/client/client.xml
    cxf/trunk/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/spnego/server/server.xml

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1221366&r1=1221365&r2=1221366&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java Tue Dec 20 17:41:59 2011
@@ -113,6 +113,16 @@ public final class SecurityConstants {
     public static final String KERBEROS_CLIENT = "ws-security.kerberos.client";
     
     /**
+     * The JAAS Context name to use for Kerberos. This is currently only supported for SPNEGO.
+     */
+    public static final String KERBEROS_JAAS_CONTEXT_NAME = "ws-security.kerberos.jaas.context";
+    
+    /**
+     * The Kerberos Service Provider Name (spn) to use. This is currently only supported for SPNEGO.
+     */
+    public static final String KERBEROS_SPN = "ws-security.kerberos.spn";
+    
+    /**
      * Set this to "false" to not cache a SecurityToken per proxy object in the 
      * IssuedTokenInterceptorProvider. This should be done if a token is being retrieved
      * from an STS in an intermediary. The default value is "true".
@@ -133,7 +143,8 @@ public final class SecurityConstants {
             SAML1_TOKEN_VALIDATOR, SAML2_TOKEN_VALIDATOR, TIMESTAMP_TOKEN_VALIDATOR,
             SIGNATURE_TOKEN_VALIDATOR, IS_BSP_COMPLIANT, TIMESTAMP_FUTURE_TTL,
             BST_TOKEN_VALIDATOR, SAML_CALLBACK_HANDLER, STS_TOKEN_ON_BEHALF_OF,
-            KERBEROS_CLIENT, SCT_TOKEN_VALIDATOR, CACHE_ISSUED_TOKEN_IN_ENDPOINT
+            KERBEROS_CLIENT, SCT_TOKEN_VALIDATOR, CACHE_ISSUED_TOKEN_IN_ENDPOINT,
+            KERBEROS_JAAS_CONTEXT_NAME, KERBEROS_SPN
         }));
         ALL_PROPERTIES = Collections.unmodifiableSet(s);
     }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/WSSecurityPolicyLoader.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/WSSecurityPolicyLoader.java?rev=1221366&r1=1221365&r2=1221366&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/WSSecurityPolicyLoader.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/WSSecurityPolicyLoader.java Tue Dec 20 17:41:59 2011
@@ -56,6 +56,7 @@ import org.apache.cxf.ws.security.policy
 import org.apache.cxf.ws.security.policy.builders.SecurityContextTokenBuilder;
 import org.apache.cxf.ws.security.policy.builders.SignedElementsBuilder;
 import org.apache.cxf.ws.security.policy.builders.SignedPartsBuilder;
+import org.apache.cxf.ws.security.policy.builders.SpnegoContextTokenBuilder;
 import org.apache.cxf.ws.security.policy.builders.SupportingTokens12Builder;
 import org.apache.cxf.ws.security.policy.builders.SupportingTokensBuilder;
 import org.apache.cxf.ws.security.policy.builders.SymmetricBindingBuilder;
@@ -72,6 +73,7 @@ import org.apache.cxf.ws.security.policy
 import org.apache.cxf.ws.security.policy.interceptors.KerberosTokenInterceptorProvider;
 import org.apache.cxf.ws.security.policy.interceptors.SamlTokenInterceptorProvider;
 import org.apache.cxf.ws.security.policy.interceptors.SecureConversationTokenInterceptorProvider;
+import org.apache.cxf.ws.security.policy.interceptors.SpnegoTokenInterceptorProvider;
 import org.apache.cxf.ws.security.policy.interceptors.UsernameTokenInterceptorProvider;
 import org.apache.cxf.ws.security.policy.interceptors.WSSecurityInterceptorProvider;
 import org.apache.cxf.ws.security.policy.interceptors.WSSecurityPolicyInterceptorProvider;
@@ -121,6 +123,7 @@ public final class WSSecurityPolicyLoade
         reg.registerBuilder(new SecurityContextTokenBuilder());
         reg.registerBuilder(new SignedElementsBuilder());
         reg.registerBuilder(new SignedPartsBuilder());
+        reg.registerBuilder(new SpnegoContextTokenBuilder(pbuild));
         reg.registerBuilder(new SupportingTokens12Builder(pbuild));
         reg.registerBuilder(new SupportingTokensBuilder(pbuild));
         reg.registerBuilder(new SymmetricBindingBuilder(pbuild));
@@ -184,6 +187,7 @@ public final class WSSecurityPolicyLoade
         reg.register(new UsernameTokenInterceptorProvider(bus));
         reg.register(new SamlTokenInterceptorProvider());
         reg.register(new SecureConversationTokenInterceptorProvider());
+        reg.register(new SpnegoTokenInterceptorProvider());
     }
 
 }

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/NegotiationUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/NegotiationUtils.java?rev=1221366&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/NegotiationUtils.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/NegotiationUtils.java Tue Dec 20 17:41:59 2011
@@ -0,0 +1,285 @@
+/**
+ * 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.ws.security.policy.interceptors;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.ws.addressing.MAPAggregator;
+import org.apache.cxf.ws.addressing.policy.MetadataConstants;
+import org.apache.cxf.ws.policy.AssertionInfo;
+import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.policy.EndpointPolicy;
+import org.apache.cxf.ws.policy.PolicyEngine;
+import org.apache.cxf.ws.policy.builder.primitive.PrimitiveAssertion;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.policy.SP11Constants;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.model.AlgorithmSuite;
+import org.apache.cxf.ws.security.policy.model.Binding;
+import org.apache.cxf.ws.security.policy.model.Trust10;
+import org.apache.cxf.ws.security.policy.model.Trust13;
+import org.apache.cxf.ws.security.tokenstore.MemoryTokenStore;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.tokenstore.TokenStore;
+import org.apache.cxf.ws.security.trust.STSUtils;
+import org.apache.neethi.Assertion;
+import org.apache.neethi.Policy;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.ConversationException;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.token.SecurityContextToken;
+
+/**
+ * This is a collection of utility methods for use in negotiation exchanges such as WS-SecureConversation 
+ * and WS-Trust for SPNEGO.
+ */
+final class NegotiationUtils {
+    
+    private NegotiationUtils() {
+        // complete
+    }
+
+    static Trust10 getTrust10(AssertionInfoMap aim) {
+        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRUST_10);
+        if (ais == null || ais.isEmpty()) {
+            ais = aim.get(SP11Constants.TRUST_10);
+        }
+        if (ais == null || ais.isEmpty()) {
+            return null;
+        }
+        return (Trust10)ais.iterator().next().getAssertion();
+    }
+    
+    static Trust13 getTrust13(AssertionInfoMap aim) {
+        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRUST_13);
+        if (ais == null || ais.isEmpty()) {
+            return null;
+        }
+        return (Trust13)ais.iterator().next().getAssertion();
+    }
+    
+    static TokenStore getTokenStore(Message message) {
+        EndpointInfo info = message.getExchange().get(Endpoint.class).getEndpointInfo();
+        synchronized (info) {
+            TokenStore tokenStore = (TokenStore)message.getContextualProperty(TokenStore.class.getName());
+            if (tokenStore == null) {
+                tokenStore = (TokenStore)info.getProperty(TokenStore.class.getName());
+            }
+            if (tokenStore == null) {
+                tokenStore = new MemoryTokenStore();
+                info.setProperty(TokenStore.class.getName(), tokenStore);
+            }
+            return tokenStore;
+        }
+    }
+    
+    static Assertion getAddressingPolicy(AssertionInfoMap aim, boolean optional) {
+        Collection<AssertionInfo> lst = aim.get(MetadataConstants.USING_ADDRESSING_2004_QNAME);
+        Assertion assertion = null;
+        if (null != lst && !lst.isEmpty()) {
+            assertion = lst.iterator().next().getAssertion();
+        }
+        if (assertion == null) {
+            lst = aim.get(MetadataConstants.USING_ADDRESSING_2005_QNAME);
+            if (null != lst && !lst.isEmpty()) {
+                assertion = lst.iterator().next().getAssertion();
+            }
+        }
+        if (assertion == null) {
+            lst = aim.get(MetadataConstants.USING_ADDRESSING_2006_QNAME);
+            if (null != lst && !lst.isEmpty()) {
+                assertion = lst.iterator().next().getAssertion();
+            }
+        }
+        if (assertion == null) {
+            return new PrimitiveAssertion(MetadataConstants.USING_ADDRESSING_2006_QNAME,
+                                          optional);
+        } else if (optional) {
+            return new PrimitiveAssertion(assertion.getName(),
+                                          optional);            
+        }
+        return assertion;
+    }
+
+    static AlgorithmSuite getAlgorithmSuite(AssertionInfoMap aim) {
+        Binding transport = null;
+        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRANSPORT_BINDING);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                transport = (Binding)ai.getAssertion();
+            }                    
+        } else {
+            ais = aim.get(SP12Constants.ASYMMETRIC_BINDING);
+            if (ais != null) {
+                for (AssertionInfo ai : ais) {
+                    transport = (Binding)ai.getAssertion();
+                }                    
+            } else {
+                ais = aim.get(SP12Constants.SYMMETRIC_BINDING);
+                if (ais != null) {
+                    for (AssertionInfo ai : ais) {
+                        transport = (Binding)ai.getAssertion();
+                    }                    
+                }
+            }
+        }
+        if (transport != null) {
+            return transport.getAlgorithmSuite();
+        }
+        return null;
+    }
+    
+    static int getWSCVersion(String tokenTypeValue) throws ConversationException {
+        if (tokenTypeValue == null) {
+            return ConversationConstants.DEFAULT_VERSION;
+        }
+
+        if (tokenTypeValue.startsWith(ConversationConstants.WSC_NS_05_02)) {
+            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_02);
+        } else if (tokenTypeValue.startsWith(ConversationConstants.WSC_NS_05_12)) {
+            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_12);
+        } else {
+            throw new ConversationException("unsupportedSecConvVersion");
+        }
+    }
+    
+    static void recalcEffectivePolicy(
+        SoapMessage message, 
+        String namespace, 
+        Policy policy,
+        Invoker invoker
+    ) {
+        Exchange ex = message.getExchange();
+        Bus bus = ex.getBus();
+        PolicyEngine pe = bus.getExtension(PolicyEngine.class);
+        if (null == pe) {
+            return;
+        }
+        Destination destination = ex.getDestination();
+        try {
+            Endpoint endpoint = message.getExchange().getEndpoint();
+
+            TokenStore store = (TokenStore)message.getContextualProperty(TokenStore.class.getName());
+            if (store == null) {
+                store = new MemoryTokenStore();
+                endpoint.getEndpointInfo().setProperty(TokenStore.class.getName(), store);
+            }
+            endpoint = STSUtils.createSTSEndpoint(bus, 
+                    namespace,
+                    endpoint.getEndpointInfo().getTransportId(),
+                    destination.getAddress().getAddress().getValue(),
+                    message.getVersion().getBindingId(), 
+                    policy,
+                    null);
+            endpoint.getEndpointInfo().setProperty(TokenStore.class.getName(), store);
+            message.getExchange().put(TokenStore.class.getName(), store);
+
+            EndpointPolicy ep = pe.getServerEndpointPolicy(endpoint.getEndpointInfo(), destination);
+            List<Interceptor<? extends Message>> interceptors = ep.getInterceptors();
+            for (Interceptor<? extends Message> i : interceptors) {
+                message.getInterceptorChain().add(i);
+            }
+
+            Collection<Assertion> assertions = ep.getVocabulary();
+            if (null != assertions) {
+                message.put(AssertionInfoMap.class, new AssertionInfoMap(assertions));
+            }
+            endpoint.getService().setInvoker(invoker);
+            ex.put(Endpoint.class, endpoint);
+            ex.put(Service.class, endpoint.getService());
+            ex.put(org.apache.cxf.binding.Binding.class, endpoint.getBinding());
+            ex.remove(BindingOperationInfo.class);
+            message.put(MAPAggregator.ACTION_VERIFIED, Boolean.TRUE);
+        } catch (Exception exc) {
+            throw new Fault(exc);
+        }
+    }
+
+    /**
+     * Return true on successfully parsing a SecurityContextToken result
+     */
+    static boolean parseSCTResult(SoapMessage message) {
+        List<WSHandlerResult> results = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
+        if (results == null) {
+            return false;
+        }
+        
+        for (WSHandlerResult rResult : results) {
+            List<WSSecurityEngineResult> wsSecEngineResults = rResult.getResults();
+
+            for (WSSecurityEngineResult wser : wsSecEngineResults) {
+                Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+                if (actInt.intValue() == WSConstants.SCT) {
+                    SecurityContextToken tok = 
+                        (SecurityContextToken)wser.get(WSSecurityEngineResult.TAG_SECURITY_CONTEXT_TOKEN);
+                    message.getExchange().put(SecurityConstants.TOKEN_ID, tok.getIdentifier());
+                    
+                    byte[] secret = (byte[])wser.get(WSSecurityEngineResult.TAG_SECRET);
+                    if (secret != null) {
+                        SecurityToken token = new SecurityToken(tok.getIdentifier());
+                        token.setToken(tok.getElement());
+                        token.setSecret(secret);
+                        token.setTokenType(tok.getTokenType());
+                        message.getExchange().put(SecurityConstants.TOKEN, token);
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    static CallbackHandler getCallbackHandler(Object o, Class<?> clazz) {
+        CallbackHandler handler = null;
+        if (o instanceof CallbackHandler) {
+            handler = (CallbackHandler)o;
+        } else if (o instanceof String) {
+            try {
+                handler = 
+                    (CallbackHandler)ClassLoaderUtils.loadClass((String)o, clazz).newInstance();
+            } catch (Exception e) {
+                handler = null;
+            }
+        }
+        return handler;
+    }
+    
+}

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSInvoker.java?rev=1221366&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSInvoker.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSInvoker.java Tue Dec 20 17:41:59 2011
@@ -0,0 +1,257 @@
+/**
+ * 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.ws.security.policy.interceptors;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
+import org.apache.cxf.ws.addressing.AttributedURIType;
+import org.apache.cxf.ws.addressing.JAXWSAConstants;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.tokenstore.TokenStore;
+import org.apache.cxf.ws.security.trust.STSUtils;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.conversation.ConversationException;
+import org.apache.ws.security.conversation.dkalgo.P_SHA1;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.XmlSchemaDateFormat;
+
+/**
+ * An abstract Invoker used by the Spnego and SecureConversationInInterceptors.
+ */
+abstract class STSInvoker implements Invoker {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(STSInvoker.class);
+    
+    public Object invoke(Exchange exchange, Object o) {
+        AddressingProperties inProps = (AddressingProperties)exchange.getInMessage()
+                .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
+        if (inProps != null) {
+            AddressingProperties props = new AddressingPropertiesImpl(inProps.getNamespaceURI());
+            AttributedURIType action = new AttributedURIType();
+            action.setValue(inProps.getAction().getValue().replace("/RST/", "/RSTR/"));
+            props.setAction(action);
+            exchange.getOutMessage().put(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND, props);
+        }
+
+        MessageContentsList lst = (MessageContentsList)o;
+        DOMSource src = (DOMSource)lst.get(0);
+        Node nd = src.getNode();
+        Element requestEl = null;
+        if (nd instanceof Document) {
+            requestEl = ((Document)nd).getDocumentElement();
+        } else {
+            requestEl = (Element)nd;
+        }
+        String namespace = requestEl.getNamespaceURI();
+        String prefix = requestEl.getPrefix();
+        SecurityToken cancelToken = null;
+        if ("RequestSecurityToken".equals(requestEl.getLocalName())) {
+            try {
+                String requestType = null;
+                Element binaryExchange = null;
+                String tokenType = null;
+                Element el = DOMUtils.getFirstElement(requestEl);
+                while (el != null) {
+                    String localName = el.getLocalName();
+                    if (namespace.equals(el.getNamespaceURI())) {
+                        if ("RequestType".equals(localName)) {
+                            requestType = el.getTextContent();
+                        } else if ("CancelTarget".equals(localName)) {
+                            cancelToken = findCancelToken(exchange, el);
+                        } else if ("BinaryExchange".equals(localName)) {
+                            binaryExchange = el;
+                        } else if ("TokenType".equals(localName)) {
+                            tokenType = DOMUtils.getContent(el);
+                        } 
+                    }
+
+                    el = DOMUtils.getNextElement(el);
+                }
+                if (requestType == null) {
+                    requestType = "/Issue";
+                }
+                if (requestType.endsWith("/Issue") 
+                    && !STSUtils.getTokenTypeSCT(namespace).equals(tokenType)) {
+                    throw new Exception("Unknown token type: " + tokenType);
+                }
+                
+                W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+                writer.setNsRepairing(true);
+
+                if (requestType.endsWith("/Issue")) { 
+                    doIssue(requestEl, exchange, binaryExchange, writer, prefix, namespace);
+                } else if (requestType.endsWith("/Cancel")) {
+                    doCancel(exchange, cancelToken, writer, prefix, namespace);
+                } //else if (requestType.endsWith("/Renew")) {
+                //REVISIT - implement
+                //}
+
+                return new MessageContentsList(new DOMSource(writer.getDocument()));
+            } catch (RuntimeException ex) {
+                throw ex;
+            } catch (Exception ex) {
+                throw new Fault(ex);
+            }
+        } else {
+            throw new Fault("Unknown SecureConversation element: " + requestEl.getLocalName(), LOG);
+        }
+    }
+    
+    abstract void doIssue(
+        Element requestEl,
+        Exchange exchange,
+        Element binaryExchange,
+        W3CDOMStreamWriter writer,
+        String prefix, 
+        String namespace
+    ) throws Exception;
+
+    private void doCancel(
+        Exchange exchange, 
+        SecurityToken cancelToken, 
+        W3CDOMStreamWriter writer,
+        String prefix, 
+        String namespace
+    ) throws Exception {
+        if (STSUtils.WST_NS_05_12.equals(namespace)) {
+            writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection", namespace);
+        }
+        writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
+        
+        TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                .getProperty(TokenStore.class.getName());
+        cancelToken.setState(SecurityToken.State.CANCELLED);
+        store.update(cancelToken);
+        writer.writeEmptyElement(prefix, "RequestedTokenCancelled", namespace);
+        exchange.put(SecurityConstants.TOKEN, cancelToken);
+        
+        writer.writeEndElement();
+        if (STSUtils.WST_NS_05_12.equals(namespace)) {
+            writer.writeEndElement();
+        }
+    }
+
+    private SecurityToken findCancelToken(Exchange exchange, Element el) throws WSSecurityException {
+        SecurityTokenReference ref = new SecurityTokenReference(DOMUtils.getFirstElement(el));
+        String uri = ref.getReference().getURI();
+        TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                .getProperty(TokenStore.class.getName());
+        return store.getToken(uri);
+    }
+    
+    byte[] writeProofToken(String prefix, 
+        String namespace,
+        W3CDOMStreamWriter writer,
+        byte[] clientEntropy,
+        int keySize
+    ) throws NoSuchAlgorithmException, WSSecurityException, ConversationException, XMLStreamException {
+        byte secret[] = null; 
+        writer.writeStartElement(prefix, "RequestedProofToken", namespace);
+        if (clientEntropy == null) {
+            secret = WSSecurityUtil.generateNonce(keySize / 8);
+
+            writer.writeStartElement(prefix, "BinarySecret", namespace);
+            writer.writeAttribute("Type", namespace + "/Nonce");
+            writer.writeCharacters(Base64.encode(secret));
+            writer.writeEndElement();
+        } else {
+            byte entropy[] = WSSecurityUtil.generateNonce(keySize / 8);
+            P_SHA1 psha1 = new P_SHA1();
+            secret = psha1.createKey(clientEntropy, entropy, 0, keySize / 8);
+
+            writer.writeStartElement(prefix, "ComputedKey", namespace);
+            writer.writeCharacters(namespace + "/CK/PSHA1");            
+            writer.writeEndElement();
+            writer.writeEndElement();
+
+            writer.writeStartElement(prefix, "Entropy", namespace);
+            writer.writeStartElement(prefix, "BinarySecret", namespace);
+            writer.writeAttribute("Type", namespace + "/Nonce");
+            writer.writeCharacters(Base64.encode(entropy));
+            writer.writeEndElement();
+
+        }
+        writer.writeEndElement();
+        return secret;
+    }
+    
+    Element writeSecurityTokenReference(
+        W3CDOMStreamWriter writer,
+        String id,
+        String refValueType
+    ) {
+        Reference ref = new Reference(writer.getDocument());
+        ref.setURI(id);
+        if (refValueType != null) {
+            ref.setValueType(refValueType);
+        }
+        SecurityTokenReference str = new SecurityTokenReference(writer.getDocument());
+        str.setReference(ref);
+
+        writer.getCurrentNode().appendChild(str.getElement());
+        return str.getElement();
+    }
+    
+    void writeLifetime(
+        W3CDOMStreamWriter writer,
+        Date created,
+        Date expires,
+        String prefix,
+        String namespace
+    ) throws Exception {
+        XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+        writer.writeStartElement(prefix, "Lifetime", namespace);
+        writer.writeNamespace("wsu", WSConstants.WSU_NS);
+        writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
+        writer.writeCharacters(fmt.format(created.getTime()));
+        writer.writeEndElement();
+        
+        writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
+        writer.writeCharacters(fmt.format(expires.getTime()));
+        writer.writeEndElement();
+        writer.writeEndElement();
+    }
+
+}
+

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationInInterceptor.java?rev=1221366&r1=1221365&r2=1221366&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationInInterceptor.java Tue Dec 20 17:41:59 2011
@@ -21,44 +21,26 @@ package org.apache.cxf.ws.security.polic
 
 import java.util.Collection;
 import java.util.Date;
-import java.util.List;
 import java.util.logging.Logger;
 
-import javax.xml.transform.dom.DOMSource;
-
-import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
-import org.apache.cxf.Bus;
 import org.apache.cxf.binding.soap.SoapBindingConstants;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.endpoint.Endpoint;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageContentsList;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.service.Service;
-import org.apache.cxf.service.invoker.Invoker;
-import org.apache.cxf.service.model.BindingOperationInfo;
 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
-import org.apache.cxf.transport.Destination;
 import org.apache.cxf.ws.addressing.AddressingProperties;
-import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
-import org.apache.cxf.ws.addressing.AttributedURIType;
 import org.apache.cxf.ws.addressing.JAXWSAConstants;
-import org.apache.cxf.ws.addressing.MAPAggregator;
 import org.apache.cxf.ws.policy.AssertionInfo;
 import org.apache.cxf.ws.policy.AssertionInfoMap;
-import org.apache.cxf.ws.policy.EndpointPolicy;
 import org.apache.cxf.ws.policy.PolicyBuilder;
-import org.apache.cxf.ws.policy.PolicyEngine;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.policy.SP12Constants;
 import org.apache.cxf.ws.security.policy.model.Binding;
@@ -69,7 +51,6 @@ import org.apache.cxf.ws.security.policy
 import org.apache.cxf.ws.security.policy.model.SymmetricBinding;
 import org.apache.cxf.ws.security.policy.model.Trust10;
 import org.apache.cxf.ws.security.policy.model.Trust13;
-import org.apache.cxf.ws.security.tokenstore.MemoryTokenStore;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.tokenstore.TokenStore;
 import org.apache.cxf.ws.security.trust.STSClient;
@@ -79,15 +60,8 @@ import org.apache.neethi.All;
 import org.apache.neethi.Assertion;
 import org.apache.neethi.ExactlyOne;
 import org.apache.neethi.Policy;
-import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSSecurityEngineResult;
-import org.apache.ws.security.WSSecurityException;
-import org.apache.ws.security.handler.WSHandlerConstants;
-import org.apache.ws.security.handler.WSHandlerResult;
 import org.apache.ws.security.message.token.SecurityContextToken;
-import org.apache.ws.security.message.token.SecurityTokenReference;
 import org.apache.ws.security.util.Base64;
-import org.apache.ws.security.util.XmlSchemaDateFormat;
 
 class SecureConversationInInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
     static final Logger LOG = LogUtils.getL7dLogger(SecureConversationInInterceptor.class);
@@ -111,6 +85,7 @@ class SecureConversationInInterceptor ex
         }
         return null;
     }
+    
     public void handleMessage(SoapMessage message) throws Fault {
         AssertionInfoMap aim = message.get(AssertionInfoMap.class);
         // extract Assertion information
@@ -157,8 +132,7 @@ class SecureConversationInInterceptor ex
                     ExactlyOne ea = new ExactlyOne();
                     p.addPolicyComponent(ea);
                     All all = new All();
-                    Assertion ass = SecureConversationTokenInterceptorProvider
-                        .getAddressingPolicy(aim, false);
+                    Assertion ass = NegotiationUtils.getAddressingPolicy(aim, false);
                     all.addPolicyComponent(ass);
                     ea.addPolicyComponent(all);
                     PolicyBuilder pbuilder = message.getExchange().getBus()
@@ -194,8 +168,7 @@ class SecureConversationInInterceptor ex
                     ExactlyOne ea = new ExactlyOne();
                     p.addPolicyComponent(ea);
                     All all = new All();
-                    Assertion ass = SecureConversationTokenInterceptorProvider
-                        .getAddressingPolicy(aim, false);
+                    Assertion ass = NegotiationUtils.getAddressingPolicy(aim, false);
                     all.addPolicyComponent(ass);
                     ea.addPolicyComponent(all);
                     pol = p.merge(pol);
@@ -207,60 +180,13 @@ class SecureConversationInInterceptor ex
                 if (s.startsWith(STSUtils.WST_NS_05_02)) {
                     ns = STSUtils.WST_NS_05_02;
                 }
-                recalcEffectivePolicy(message, ns, pol);
+                NegotiationUtils.recalcEffectivePolicy(message, ns, pol, new SecureConversationSTSInvoker());
             } else {
                 message.getInterceptorChain().add(SecureConversationTokenFinderInterceptor.INSTANCE);
             }
         }
     }
-    private void recalcEffectivePolicy(SoapMessage message, 
-                                       String namespace,
-                                       Policy policy) {
-        Exchange ex = message.getExchange();
-        Bus bus = ex.getBus();
-        PolicyEngine pe = bus.getExtension(PolicyEngine.class);
-        if (null == pe) {
-            return;
-        }
-        Destination destination = ex.getDestination();
-        try {
-            Endpoint endpoint = message.getExchange().getEndpoint();
-            
-            TokenStore store = (TokenStore)message.getContextualProperty(TokenStore.class.getName());
-            if (store == null) {
-                store = new MemoryTokenStore();
-                endpoint.getEndpointInfo().setProperty(TokenStore.class.getName(), store);
-            }
-            endpoint = STSUtils.createSTSEndpoint(bus, 
-                                                  namespace,
-                                                  endpoint.getEndpointInfo().getTransportId(),
-                                                  destination.getAddress().getAddress().getValue(),
-                                                  message.getVersion().getBindingId(), 
-                                                  policy,
-                                                  null);
-            endpoint.getEndpointInfo().setProperty(TokenStore.class.getName(), store);
-            message.getExchange().put(TokenStore.class.getName(), store);
-        
-            EndpointPolicy ep = pe.getServerEndpointPolicy(endpoint.getEndpointInfo(), destination);
-            List<Interceptor<? extends Message>> interceptors = ep.getInterceptors();
-            for (Interceptor<? extends Message> i : interceptors) {
-                message.getInterceptorChain().add(i);
-            }
-            
-            Collection<Assertion> assertions = ep.getVocabulary();
-            if (null != assertions) {
-                message.put(AssertionInfoMap.class, new AssertionInfoMap(assertions));
-            }
-            endpoint.getService().setInvoker(new STSInvoker());
-            ex.put(Endpoint.class, endpoint);
-            ex.put(Service.class, endpoint.getService());
-            ex.put(org.apache.cxf.binding.Binding.class, endpoint.getBinding());
-            ex.remove(BindingOperationInfo.class);
-            message.put(MAPAggregator.ACTION_VERIFIED, Boolean.TRUE);
-        } catch (Exception exc) {
-            throw new Fault(exc);
-        }
-    }
+
     private void unmapSecurityProps(Message message) {
         Exchange ex = message.getExchange();
         for (String s : SecurityConstants.ALL_PROPERTIES) {
@@ -271,95 +197,24 @@ class SecureConversationInInterceptor ex
         }
     }
 
-    public class STSInvoker implements Invoker {
+    public class SecureConversationSTSInvoker extends STSInvoker {
 
-        public Object invoke(Exchange exchange, Object o) {
-            AddressingProperties inProps = (AddressingProperties)exchange.getInMessage()
-                .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
-            if (inProps != null) {
-                AddressingProperties props = new AddressingPropertiesImpl(inProps.getNamespaceURI());
-                AttributedURIType action = new AttributedURIType();
-                action.setValue(inProps.getAction().getValue().replace("/RST/", "/RSTR/"));
-                props.setAction(action);
-                exchange.getOutMessage().put(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND,
-                                             props);
+        void doIssue(
+            Element requestEl,
+            Exchange exchange,
+            Element binaryExchange,
+            W3CDOMStreamWriter writer,
+            String prefix, 
+            String namespace
+        ) throws Exception {
+            if (STSUtils.WST_NS_05_12.equals(namespace)) {
+                writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection", namespace);
             }
+            writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
             
-            MessageContentsList lst = (MessageContentsList)o;
-            DOMSource src = (DOMSource)lst.get(0);
-            Node nd = src.getNode();
-            Element requestEl = null;
-            if (nd instanceof Document) {
-                requestEl = ((Document)nd).getDocumentElement();
-            } else {
-                requestEl = (Element)nd;
-            }
-            String namespace = requestEl.getNamespaceURI();
-            String prefix = requestEl.getPrefix();
-            SecurityToken cancelToken = null;
-            if ("RequestSecurityToken".equals(requestEl.getLocalName())) {
-                try {
-                    W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
-                    writer.setNsRepairing(true);
-                    if (STSUtils.WST_NS_05_12.equals(namespace)) {
-                        writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection",
-                                                 namespace);
-                    }
-                    writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
-                    
-                    String requestType = null;
-                    Element el = DOMUtils.getFirstElement(requestEl);
-                    while (el != null) {
-                        String localName = el.getLocalName();
-                        if (namespace.equals(el.getNamespaceURI())) {
-                            if ("RequestType".equals(localName)) {
-                                requestType = el.getTextContent();
-                            } else if ("CancelTarget".equals(localName)) {
-                                cancelToken = findCancelToken(exchange, el);
-                            }
-                        }
-                        
-                        el = DOMUtils.getNextElement(el);
-                    }
-                    if (requestType == null) {
-                        requestType = "/Issue";
-                    }
-                    
-                    if (requestType.endsWith("/Issue")) { 
-                        doIssue(requestEl, exchange, writer, prefix, namespace);
-                    } else if (requestType.endsWith("/Cancel")) {
-                        TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
-                            .getProperty(TokenStore.class.getName());
-                        cancelToken.setState(SecurityToken.State.CANCELLED);
-                        store.update(cancelToken);
-                        writer.writeEmptyElement(prefix, "RequestedTokenCancelled", namespace);
-                        exchange.put(SecurityConstants.TOKEN, cancelToken);
-                    } //else if (requestType.endsWith("/Renew")) {
-                        //REVISIT - implement
-                    //}
-                    writer.writeEndElement();
-                    if (STSUtils.WST_NS_05_12.equals(namespace)) {
-                        writer.writeEndElement();
-                    }
-                    return new MessageContentsList(new DOMSource(writer.getDocument()));
-                } catch (RuntimeException ex) {
-                    throw ex;
-                } catch (Exception ex) {
-                    throw new Fault(ex);
-                }
-            } else {
-                throw new Fault("Unknown SecureConversation element: " + requestEl.getLocalName(),
-                                LOG);
-            }
-        }
-
-        private void doIssue(Element requestEl,
-                             Exchange exchange, W3CDOMStreamWriter writer,
-                             String prefix, String namespace) 
-            throws Exception {
             byte clientEntropy[] = null;
             int keySize = 256;
-            long ttl = 300000;
+            long ttl = 300000L;
             String tokenType = null;
             Element el = DOMUtils.getFirstElement(requestEl);
             while (el != null) {
@@ -380,10 +235,14 @@ class SecureConversationInInterceptor ex
                 el = DOMUtils.getNextElement(el);
             }
             
+            // Check received KeySize
+            if (keySize < 128 || keySize > 512) {
+                keySize = 256;
+            }
+            
             writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
             SecurityContextToken sct =
-                new SecurityContextToken(SecureConversationTokenInterceptorProvider
-                                              .getWSCVersion(tokenType), writer.getDocument());
+                new SecurityContextToken(NegotiationUtils.getWSCVersion(tokenType), writer.getDocument());
             
             Date created = new Date();
             Date expires = new Date();
@@ -391,53 +250,35 @@ class SecureConversationInInterceptor ex
             
             SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
             token.setToken(sct.getElement());
-            token.setTokenType(WSConstants.WSC_SCT);
+            token.setTokenType(sct.getTokenType());
             
             writer.getCurrentNode().appendChild(sct.getElement());
             writer.writeEndElement();        
             
             writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
-            token.setAttachedReference(SecureConversationTokenInterceptorProvider
-                                           .writeSecurityTokenReference(writer,
-                                                                   "#" + sct.getID(), 
-                                                                   tokenType));
+            token.setAttachedReference(
+                writeSecurityTokenReference(writer, "#" + sct.getID(), tokenType)
+            );
             writer.writeEndElement();
             
             writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
-            token.setUnattachedReference(SecureConversationTokenInterceptorProvider
-                                             .writeSecurityTokenReference(writer,
-                                                                     sct.getIdentifier(),
-                                                                     tokenType));
-            writer.writeEndElement();
-            
-            XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
-            writer.writeStartElement(prefix, "Lifetime", namespace);
-            writer.writeNamespace("wsu", WSConstants.WSU_NS);
-            writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
-            writer.writeCharacters(fmt.format(created.getTime()));
+            token.setUnattachedReference(
+                writeSecurityTokenReference(writer, sct.getIdentifier(), tokenType)
+            );
             writer.writeEndElement();
             
-            writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
-            writer.writeCharacters(fmt.format(expires.getTime()));
-            writer.writeEndElement();
-            writer.writeEndElement();
+            writeLifetime(writer, created, expires, prefix, namespace);
 
-            byte[] secret = SecureConversationTokenInterceptorProvider.writeProofToken(prefix, 
-                                            namespace,
-                                            writer,
-                                            clientEntropy, 
-                                            keySize);
+            byte[] secret = writeProofToken(prefix, namespace, writer, clientEntropy, keySize);
+            
             token.setSecret(secret);
             ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
                     .getProperty(TokenStore.class.getName())).add(token);
-        }
-
-        private SecurityToken findCancelToken(Exchange exchange, Element el) throws WSSecurityException {
-            SecurityTokenReference ref = new SecurityTokenReference(DOMUtils.getFirstElement(el));
-            String uri = ref.getReference().getURI();
-            TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
-                    .getProperty(TokenStore.class.getName());
-            return store.getToken(uri);
+            
+            writer.writeEndElement();
+            if (STSUtils.WST_NS_05_12.equals(namespace)) {
+                writer.writeEndElement();
+            }
         }
 
     }
@@ -455,34 +296,8 @@ class SecureConversationInInterceptor ex
         }
 
         public void handleMessage(SoapMessage message) throws Fault {
-            //Find the SC token
-            boolean found = false;
-            List<WSHandlerResult> results = 
-                CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
-            if (results != null) {
-                for (WSHandlerResult rResult : results) {
-                    List<WSSecurityEngineResult> wsSecEngineResults = rResult.getResults();
-    
-                    for (WSSecurityEngineResult wser : wsSecEngineResults) {
-                        Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
-                        if (actInt.intValue() == WSConstants.SCT) {
-                            SecurityContextToken tok
-                                = (SecurityContextToken)wser
-                                    .get(WSSecurityEngineResult.TAG_SECURITY_CONTEXT_TOKEN);
-                            message.getExchange().put(SecurityConstants.TOKEN_ID, tok.getIdentifier());
-                            byte[] secret = (byte[])wser.get(WSSecurityEngineResult.TAG_SECRET);
-                            if (secret != null) {
-                                SecurityToken token = new SecurityToken(tok.getIdentifier());
-                                token.setToken(tok.getElement());
-                                token.setSecret(secret);
-                                token.setTokenType(WSConstants.WSC_SCT);
-                                message.getExchange().put(SecurityConstants.TOKEN, token);
-                            }
-                            found = true;
-                        }
-                    }
-                }
-            }
+            boolean foundSCT = NegotiationUtils.parseSCTResult(message);
+
             AssertionInfoMap aim = message.get(AssertionInfoMap.class);
             // extract Assertion information
             if (aim != null) {
@@ -491,7 +306,7 @@ class SecureConversationInInterceptor ex
                     return;
                 }
                 for (AssertionInfo inf : ais) {
-                    if (found) {
+                    if (foundSCT) {
                         inf.setAsserted(true);
                     } else {
                         inf.setNotAsserted("No SecureConversation token found in message.");
@@ -534,8 +349,7 @@ class SecureConversationInInterceptor ex
             if (tok == null) {
                 String tokId = (String)m2.getContextualProperty(SecurityConstants.TOKEN_ID);
                 if (tokId != null) {
-                    tok = SecureConversationTokenInterceptorProvider
-                        .getTokenStore(m2).getToken(tokId);
+                    tok = NegotiationUtils.getTokenStore(m2).getToken(tokId);
                 }
             }
 
@@ -558,8 +372,7 @@ class SecureConversationInInterceptor ex
                     }
                     
                     client.cancelSecurityToken(tok);
-                    SecureConversationTokenInterceptorProvider
-                        .getTokenStore(m2).remove(tok);
+                    NegotiationUtils.getTokenStore(m2).remove(tok);
                 } catch (RuntimeException e) {
                     throw e;
                 } catch (Exception e) {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java?rev=1221366&r1=1221365&r2=1221366&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationOutInterceptor.java Tue Dec 20 17:41:59 2011
@@ -61,7 +61,7 @@ class SecureConversationOutInterceptor e
                 if (tok == null) {
                     String tokId = (String)message.getContextualProperty(SecurityConstants.TOKEN_ID);
                     if (tokId != null) {
-                        tok = SecureConversationTokenInterceptorProvider
+                        tok = NegotiationUtils
                             .getTokenStore(message).getToken(tokId);
                     }
                 }
@@ -78,7 +78,7 @@ class SecureConversationOutInterceptor e
                                                                   tok.getId());
                     message.getExchange().put(SecurityConstants.TOKEN_ID, 
                                               tok.getId());
-                    SecureConversationTokenInterceptorProvider.getTokenStore(message).add(tok);
+                    NegotiationUtils.getTokenStore(message).add(tok);
                     
                 }
             } else {
@@ -157,7 +157,11 @@ class SecureConversationOutInterceptor e
                     client.setAddressingNamespace(maps.getNamespaceURI());
                 }
                 tok = client.requestSecurityToken(s);
-                tok.setTokenType(WSConstants.WSC_SCT);
+                String tokenType = tok.getTokenType();
+                tok.setTokenType(tokenType);
+                if (tokenType == null || "".equals(tokenType)) {
+                    tok.setTokenType(WSConstants.WSC_SCT);
+                }
                 return tok;
             } catch (RuntimeException e) {
                 throw e;

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java?rev=1221366&r1=1221365&r2=1221366&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java Tue Dec 20 17:41:59 2011
@@ -19,55 +19,28 @@
 
 package org.apache.cxf.ws.security.policy.interceptors;
 
-import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Map;
 import java.util.logging.Logger;
 
-import javax.xml.stream.XMLStreamException;
-
-import org.w3c.dom.Element;
-
-
 import org.apache.cxf.binding.soap.Soap11;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.service.model.EndpointInfo;
-import org.apache.cxf.staxutils.W3CDOMStreamWriter;
-import org.apache.cxf.ws.addressing.policy.MetadataConstants;
 import org.apache.cxf.ws.policy.AbstractPolicyInterceptorProvider;
-import org.apache.cxf.ws.policy.AssertionInfo;
 import org.apache.cxf.ws.policy.AssertionInfoMap;
 import org.apache.cxf.ws.policy.PolicyBuilder;
-import org.apache.cxf.ws.policy.builder.primitive.PrimitiveAssertion;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.policy.SP11Constants;
 import org.apache.cxf.ws.security.policy.SP12Constants;
 import org.apache.cxf.ws.security.policy.SPConstants.SupportTokenType;
 import org.apache.cxf.ws.security.policy.model.AlgorithmSuite;
-import org.apache.cxf.ws.security.policy.model.Binding;
 import org.apache.cxf.ws.security.policy.model.SecureConversationToken;
 import org.apache.cxf.ws.security.policy.model.SupportingToken;
-import org.apache.cxf.ws.security.policy.model.Trust10;
-import org.apache.cxf.ws.security.policy.model.Trust13;
-import org.apache.cxf.ws.security.tokenstore.MemoryTokenStore;
-import org.apache.cxf.ws.security.tokenstore.TokenStore;
 import org.apache.cxf.ws.security.trust.STSClient;
 import org.apache.neethi.All;
-import org.apache.neethi.Assertion;
 import org.apache.neethi.ExactlyOne;
 import org.apache.neethi.Policy;
-import org.apache.ws.security.WSSecurityException;
-import org.apache.ws.security.conversation.ConversationConstants;
-import org.apache.ws.security.conversation.ConversationException;
-import org.apache.ws.security.conversation.dkalgo.P_SHA1;
-import org.apache.ws.security.message.token.Reference;
-import org.apache.ws.security.message.token.SecurityTokenReference;
-import org.apache.ws.security.util.Base64;
-import org.apache.ws.security.util.WSSecurityUtil;
 
 /**
  * 
@@ -85,81 +58,19 @@ public class SecureConversationTokenInte
         this.getInFaultInterceptors().add(new SecureConversationInInterceptor());
     }
     
-    static final Trust10 getTrust10(AssertionInfoMap aim) {
-        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRUST_10);
-        if (ais == null || ais.isEmpty()) {
-            ais = aim.get(SP11Constants.TRUST_10);
-        }
-        if (ais == null || ais.isEmpty()) {
-            return null;
-        }
-        return (Trust10)ais.iterator().next().getAssertion();
-    }
-    
-    static final Trust13 getTrust13(AssertionInfoMap aim) {
-        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRUST_13);
-        if (ais == null || ais.isEmpty()) {
-            return null;
-        }
-        return (Trust13)ais.iterator().next().getAssertion();
-    }
-    
-    static final TokenStore getTokenStore(Message message) {
-        EndpointInfo info = message.getExchange().get(Endpoint.class).getEndpointInfo();
-        synchronized (info) {
-            TokenStore tokenStore = (TokenStore)message.getContextualProperty(TokenStore.class.getName());
-            if (tokenStore == null) {
-                tokenStore = (TokenStore)info.getProperty(TokenStore.class.getName());
-            }
-            if (tokenStore == null) {
-                tokenStore = new MemoryTokenStore();
-                info.setProperty(TokenStore.class.getName(), tokenStore);
-            }
-            return tokenStore;
-        }
-    }
-    
-    static Assertion getAddressingPolicy(AssertionInfoMap aim, boolean optional) {
-        Collection<AssertionInfo> lst = aim.get(MetadataConstants.USING_ADDRESSING_2004_QNAME);
-        Assertion assertion = null;
-        if (null != lst && !lst.isEmpty()) {
-            assertion = lst.iterator().next().getAssertion();
-        }
-        if (assertion == null) {
-            lst = aim.get(MetadataConstants.USING_ADDRESSING_2005_QNAME);
-            if (null != lst && !lst.isEmpty()) {
-                assertion = lst.iterator().next().getAssertion();
-            }
-        }
-        if (assertion == null) {
-            lst = aim.get(MetadataConstants.USING_ADDRESSING_2006_QNAME);
-            if (null != lst && !lst.isEmpty()) {
-                assertion = lst.iterator().next().getAssertion();
-            }
-        }
-        if (assertion == null) {
-            return new PrimitiveAssertion(MetadataConstants.USING_ADDRESSING_2006_QNAME,
-                                          optional);
-        } else if (optional) {
-            return new PrimitiveAssertion(assertion.getName(),
-                                          optional);            
-        }
-        return assertion;
-    }
-
     static String setupClient(STSClient client,
                             SoapMessage message,
                             AssertionInfoMap aim,
                             SecureConversationToken itok,
                             boolean endorse) {
-        client.setTrust(getTrust10(aim));
-        client.setTrust(getTrust13(aim));
+        client.setTrust(NegotiationUtils.getTrust10(aim));
+        client.setTrust(NegotiationUtils.getTrust13(aim));
         Policy pol = itok.getBootstrapPolicy();
         Policy p = new Policy();
         ExactlyOne ea = new ExactlyOne();
         p.addPolicyComponent(ea);
         All all = new All();
-        all.addPolicyComponent(getAddressingPolicy(aim, false));
+        all.addPolicyComponent(NegotiationUtils.getAddressingPolicy(aim, false));
         ea.addPolicyComponent(all);
         
         if (endorse) {
@@ -178,7 +89,7 @@ public class SecureConversationTokenInte
         String s = message
             .getContextualProperty(Message.ENDPOINT_ADDRESS).toString();
         client.setLocation(s);
-        AlgorithmSuite suite = getAlgorithmSuite(aim);
+        AlgorithmSuite suite = NegotiationUtils.getAlgorithmSuite(aim);
         if (suite != null) {
             client.setAlgorithmSuite(suite);
             int x = suite.getMaximumSymmetricKeyLength();
@@ -191,34 +102,6 @@ public class SecureConversationTokenInte
         return s;
     }
     
-    private static AlgorithmSuite getAlgorithmSuite(AssertionInfoMap aim) {
-        Binding transport = null;
-        Collection<AssertionInfo> ais = aim.get(SP12Constants.TRANSPORT_BINDING);
-        if (ais != null) {
-            for (AssertionInfo ai : ais) {
-                transport = (Binding)ai.getAssertion();
-            }                    
-        } else {
-            ais = aim.get(SP12Constants.ASYMMETRIC_BINDING);
-            if (ais != null) {
-                for (AssertionInfo ai : ais) {
-                    transport = (Binding)ai.getAssertion();
-                }                    
-            } else {
-                ais = aim.get(SP12Constants.SYMMETRIC_BINDING);
-                if (ais != null) {
-                    for (AssertionInfo ai : ais) {
-                        transport = (Binding)ai.getAssertion();
-                    }                    
-                }
-            }
-        }
-        if (transport != null) {
-            return transport.getAlgorithmSuite();
-        }
-        return null;
-    }
-    
     private static void mapSecurityProps(Message message, Map<String, Object> ctx) {
         for (String s : SecurityConstants.ALL_PROPERTIES) {
             Object v = message.getContextualProperty(s + ".sct");
@@ -228,75 +111,4 @@ public class SecureConversationTokenInte
         }
     }
     
-    static byte[] writeProofToken(String prefix, 
-                                          String namespace,
-                                          W3CDOMStreamWriter writer,
-                                          byte[] clientEntropy,
-                                          int keySize) 
-        throws NoSuchAlgorithmException, WSSecurityException, ConversationException, XMLStreamException {
-        byte secret[] = null; 
-        writer.writeStartElement(prefix, "RequestedProofToken", namespace);
-        if (clientEntropy == null) {
-            secret = WSSecurityUtil.generateNonce(keySize / 8);
-            
-            writer.writeStartElement(prefix, "BinarySecret", namespace);
-            writer.writeAttribute("Type", namespace + "/Nonce");
-            writer.writeCharacters(Base64.encode(secret));
-            writer.writeEndElement();
-        } else {
-            byte entropy[] = WSSecurityUtil.generateNonce(keySize / 8);
-            P_SHA1 psha1 = new P_SHA1();
-            secret = psha1.createKey(clientEntropy,
-                                     entropy,
-                                     0,
-                                     keySize / 8);
-
-            writer.writeStartElement(prefix, "ComputedKey", namespace);
-            writer.writeCharacters(namespace + "/CK/PSHA1");            
-            writer.writeEndElement();
-            writer.writeEndElement();
-
-            writer.writeStartElement(prefix, "Entropy", namespace);
-            writer.writeStartElement(prefix, "BinarySecret", namespace);
-            writer.writeAttribute("Type", namespace + "/Nonce");
-            writer.writeCharacters(Base64.encode(entropy));
-            writer.writeEndElement();
-            
-        }
-        writer.writeEndElement();
-        return secret;
-    }
-    
-    static Element writeSecurityTokenReference(W3CDOMStreamWriter writer,
-                                                    String id,
-                                                    String refValueType) {
-
-        Reference ref = new Reference(writer.getDocument());
-        ref.setURI(id);
-        if (refValueType != null) {
-            ref.setValueType(refValueType);
-        }
-        SecurityTokenReference str = new SecurityTokenReference(writer.getDocument());
-        str.setReference(ref);
-
-        writer.getCurrentNode().appendChild(str.getElement());
-        return str.getElement();
-    }
-
-    
-    static int getWSCVersion(String tokenTypeValue) throws ConversationException {
-
-        if (tokenTypeValue == null) {
-            return ConversationConstants.DEFAULT_VERSION;
-        }
-
-        if (tokenTypeValue.startsWith(ConversationConstants.WSC_NS_05_02)) {
-            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_02);
-        } else if (tokenTypeValue.startsWith(ConversationConstants.WSC_NS_05_12)) {
-            return ConversationConstants.getWSTVersion(ConversationConstants.WSC_NS_05_12);
-        } else {
-            throw new ConversationException("unsupportedSecConvVersion");
-        }
-    }
-
 }

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenInInterceptor.java?rev=1221366&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenInInterceptor.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SpnegoContextTokenInInterceptor.java Tue Dec 20 17:41:59 2011
@@ -0,0 +1,368 @@
+/**
+ * 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.ws.security.policy.interceptors;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.soap.SoapBindingConstants;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.JAXWSAConstants;
+import org.apache.cxf.ws.policy.AssertionInfo;
+import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.tokenstore.TokenStore;
+import org.apache.cxf.ws.security.trust.STSUtils;
+import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
+import org.apache.neethi.All;
+import org.apache.neethi.Assertion;
+import org.apache.neethi.ExactlyOne;
+import org.apache.neethi.Policy;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.SecurityContextToken;
+import org.apache.ws.security.spnego.SpnegoTokenContext;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.WSSecurityUtil;
+
+class SpnegoContextTokenInInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
+    static final Logger LOG = LogUtils.getL7dLogger(SpnegoContextTokenInInterceptor.class);
+    
+    public SpnegoContextTokenInInterceptor() {
+        super(Phase.PRE_PROTOCOL);
+    }
+    
+    public void handleMessage(SoapMessage message) throws Fault {
+        AssertionInfoMap aim = message.get(AssertionInfoMap.class);
+        // extract Assertion information
+        if (aim != null) {
+            Collection<AssertionInfo> ais = aim.get(SP12Constants.SPNEGO_CONTEXT_TOKEN);
+            if (ais == null || ais.isEmpty()) {
+                return;
+            }
+            if (isRequestor(message)) {
+                //client side should be checked on the way out
+                for (AssertionInfo ai : ais) {
+                    ai.setAsserted(true);
+                }      
+                return;
+            }
+            String s = (String)message.get(SoapBindingConstants.SOAP_ACTION);
+            AddressingProperties inProps = (AddressingProperties)message
+                .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
+            if (inProps != null && s == null) {
+                //MS/WCF doesn't put a soap action out for this, must check the headers
+                s = inProps.getAction().getValue();
+            }
+
+            if (s != null 
+                && s.contains("/RST/Issue")
+                && (s.startsWith(STSUtils.WST_NS_05_02)
+                    || s.startsWith(STSUtils.WST_NS_05_12))) {
+
+                Policy p = new Policy();
+                ExactlyOne ea = new ExactlyOne();
+                p.addPolicyComponent(ea);
+                All all = new All();
+                Assertion ass = NegotiationUtils.getAddressingPolicy(aim, false);
+                all.addPolicyComponent(ass);
+                ea.addPolicyComponent(all);
+                
+                //setup endpoint and forward to it.
+                unmapSecurityProps(message);
+                String ns = STSUtils.WST_NS_05_12;
+                if (s.startsWith(STSUtils.WST_NS_05_02)) {
+                    ns = STSUtils.WST_NS_05_02;
+                }
+                NegotiationUtils.recalcEffectivePolicy(message, ns, p, new SpnegoSTSInvoker());
+            } else {
+                message.getInterceptorChain().add(SpnegoContextTokenFinderInterceptor.INSTANCE);
+            }
+        }
+    }
+    
+    private void unmapSecurityProps(Message message) {
+        Exchange ex = message.getExchange();
+        for (String s : SecurityConstants.ALL_PROPERTIES) {
+            Object v = message.getContextualProperty(s);
+            if (v != null) {
+                ex.put(s, v);
+            }
+        }
+    }
+
+    public class SpnegoSTSInvoker extends STSInvoker {
+
+        void doIssue(
+            Element requestEl,
+            Exchange exchange, 
+            Element binaryExchange,
+            W3CDOMStreamWriter writer,
+            String prefix, 
+            String namespace
+        ) throws Exception {
+            
+            SpnegoTokenContext spnegoToken = 
+                handleBinaryExchange(binaryExchange, exchange.getInMessage(), namespace);
+            
+            writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection", namespace);
+            writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
+            
+            String context = requestEl.getAttributeNS(null, "Context");
+            if (context != null && !"".equals(context)) {
+                writer.writeAttribute("Context", context);
+            }
+            
+            // Find TokenType and KeySize
+            int keySize = 256;
+            String tokenType = null;
+            Element el = DOMUtils.getFirstElement(requestEl);
+            while (el != null) {
+                String localName = el.getLocalName();
+                if (namespace.equals(el.getNamespaceURI())) {
+                    if ("KeySize".equals(localName)) {
+                        keySize = Integer.parseInt(el.getTextContent());
+                    } else if ("TokenType".equals(localName)) {
+                        tokenType = el.getTextContent();
+                    }
+                }
+                
+                el = DOMUtils.getNextElement(el);
+            }
+            
+            // Check received KeySize
+            if (keySize < 128 || keySize > 512) {
+                keySize = 256;
+            }
+            
+            // TokenType
+            writer.writeStartElement(prefix, "TokenType", namespace);
+            writer.writeCharacters(tokenType);
+            writer.writeEndElement();
+            
+            writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
+            
+            // SecurityContextToken
+            SecurityContextToken sct =
+                new SecurityContextToken(
+                    NegotiationUtils.getWSCVersion(tokenType), writer.getDocument()
+                );
+            
+            // Lifetime
+            Date created = new Date();
+            Date expires = new Date();
+            expires.setTime(created.getTime() + 300000L);
+            
+            SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
+            token.setToken(sct.getElement());
+            token.setTokenType(sct.getTokenType());
+            
+            writer.getCurrentNode().appendChild(sct.getElement());
+            writer.writeEndElement();        
+            
+            // References
+            writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
+            token.setAttachedReference(
+                writeSecurityTokenReference(writer, "#" + sct.getID(), tokenType)
+            );
+            writer.writeEndElement();
+            
+            writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
+            token.setUnattachedReference(
+                writeSecurityTokenReference(writer, sct.getIdentifier(), tokenType)
+            );
+            writer.writeEndElement();
+            
+            writeLifetime(writer, created, expires, prefix, namespace);
+            
+            // KeySize
+            writer.writeStartElement(prefix, "KeySize", namespace);
+            writer.writeCharacters("" + keySize);
+            writer.writeEndElement();
+            
+            byte[] secret = WSSecurityUtil.generateNonce(keySize / 8);
+            byte[] key = spnegoToken.wrapKey(secret);
+            
+            writeProofToken(writer, prefix, namespace, key);
+
+            writer.writeEndElement();
+            
+            /*
+            // Second RequestSecurityTokenResponse containing the Authenticator
+            // TODO
+            writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
+            if (context != null && !"".equals(context)) {
+                writer.writeAttribute("Context", context);
+            }
+            writeAuthenticator(writer, prefix, namespace, secret);
+            writer.writeEndElement();
+            */
+            
+            writer.writeEndElement();
+            
+            spnegoToken.clear();
+            
+            token.setSecret(secret);
+            ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+                    .getProperty(TokenStore.class.getName())).add(token);
+        }
+        
+        private SpnegoTokenContext handleBinaryExchange(
+            Element binaryExchange,
+            Message message,
+            String namespace
+        ) throws Exception {
+            if (binaryExchange == null) {
+                throw new Exception("No BinaryExchange element received");
+            }
+            String encoding = binaryExchange.getAttributeNS(null, "EncodingType");
+            if (!BinarySecurity.BASE64_ENCODING.equals(encoding)) {
+                throw new Exception("Unknown encoding type: " + encoding);
+            }
+
+            String valueType = binaryExchange.getAttributeNS(null, "ValueType");
+            if (!(namespace + "/spnego").equals(valueType)) {
+                throw new Exception("Unknown value type: " + valueType);
+            }
+
+            String content = DOMUtils.getContent(binaryExchange);
+            byte[] decodedContent = Base64.decode(content);
+            
+            String jaasContext = 
+                (String)message.getContextualProperty(SecurityConstants.KERBEROS_JAAS_CONTEXT_NAME);
+            String kerberosSpn = 
+                (String)message.getContextualProperty(SecurityConstants.KERBEROS_SPN);
+            CallbackHandler callbackHandler = 
+                NegotiationUtils.getCallbackHandler(
+                    message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER), this.getClass()
+                );
+
+            SpnegoTokenContext spnegoToken = new SpnegoTokenContext();
+            spnegoToken.validateServiceTicket(
+                jaasContext, callbackHandler, kerberosSpn, decodedContent
+            );
+            return spnegoToken;
+        }
+        
+        private void writeProofToken(
+            W3CDOMStreamWriter writer,
+            String prefix, 
+            String namespace,
+            byte[] key
+        ) throws Exception {
+            // RequestedProofToken
+            writer.writeStartElement(prefix, "RequestedProofToken", namespace);
+            
+            // EncryptedKey
+            writer.writeStartElement(WSConstants.ENC_PREFIX, "EncryptedKey", WSConstants.ENC_NS);
+            writer.writeStartElement(WSConstants.ENC_PREFIX, "EncryptionMethod", WSConstants.ENC_NS);
+            writer.writeAttribute("Algorithm", namespace + "/spnego#GSS_Wrap");
+            writer.writeEndElement();
+            writer.writeStartElement(WSConstants.ENC_PREFIX, "CipherData", WSConstants.ENC_NS);
+            writer.writeStartElement(WSConstants.ENC_PREFIX, "CipherValue", WSConstants.ENC_NS);
+
+            writer.writeCharacters(Base64.encode(key));
+            
+            writer.writeEndElement();
+            writer.writeEndElement();
+            writer.writeEndElement();
+            
+            writer.writeEndElement();
+        }
+        
+        /*
+        private void writeAuthenticator(
+            W3CDOMStreamWriter writer,
+            String prefix, 
+            String namespace,
+            byte[] secret
+        ) throws Exception {
+            // Authenticator
+            writer.writeStartElement(prefix, "Authenticator", namespace);
+            
+            // CombinedHash
+            writer.writeStartElement(prefix, "CombinedHash", namespace);
+            
+            P_SHA1 psha1 = new P_SHA1();
+            byte[] seed = "AUTH-HASH".getBytes();
+            byte[] digest = psha1.createKey(secret, seed, 0, 32);
+            writer.writeCharacters(Base64.encode(digest));
+            
+            writer.writeEndElement();
+            
+            writer.writeEndElement();
+        }
+        */
+
+    }
+    
+    
+    static final class SpnegoContextTokenFinderInterceptor 
+        extends AbstractPhaseInterceptor<SoapMessage> {
+        
+        static final SpnegoContextTokenFinderInterceptor INSTANCE 
+            = new SpnegoContextTokenFinderInterceptor();
+        
+        private SpnegoContextTokenFinderInterceptor() {
+            super(Phase.PRE_PROTOCOL);
+            addAfter(WSS4JInInterceptor.class.getName());
+        }
+
+        public void handleMessage(SoapMessage message) throws Fault {
+            boolean foundSCT = NegotiationUtils.parseSCTResult(message);
+            
+            AssertionInfoMap aim = message.get(AssertionInfoMap.class);
+            // extract Assertion information
+            if (aim != null) {
+                Collection<AssertionInfo> ais = aim.get(SP12Constants.SPNEGO_CONTEXT_TOKEN);
+                if (ais == null || ais.isEmpty()) {
+                    return;
+                }
+                for (AssertionInfo inf : ais) {
+                    if (foundSCT) {
+                        inf.setAsserted(true);
+                    } else {
+                        inf.setNotAsserted("No SecurityContextToken token found in message.");
+                    }
+                }
+            }
+        }
+    }
+    
+
+    
+}
\ No newline at end of file



Mime
View raw message