You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2016/02/16 14:54:37 UTC

[1/3] cxf git commit: Refactor how WSS4J creates the CXF SecurityContext to make it pluggable

Repository: cxf
Updated Branches:
  refs/heads/master 7d1890510 -> d68286f71


Refactor how WSS4J creates the CXF SecurityContext to make it pluggable


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a9db299a
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a9db299a
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a9db299a

Branch: refs/heads/master
Commit: a9db299a4715fd054adceca1abddf5fbf08a5b20
Parents: 7d18905
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Feb 16 11:50:16 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Feb 16 11:58:32 2016 +0000

----------------------------------------------------------------------
 .../cxf/ws/security/SecurityConstants.java      |  10 +-
 ...tUsernameTokenAuthenticatingInterceptor.java |  31 ++-
 .../DefaultWSS4JSecurityContextCreator.java     | 205 +++++++++++++++++++
 .../ws/security/wss4j/WSS4JInInterceptor.java   | 160 +--------------
 .../wss4j/WSS4JSecurityContextCreator.java      |  34 +++
 5 files changed, 281 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a9db299a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
index f9ebaba..f431a14 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
@@ -276,6 +276,14 @@ public final class SecurityConstants extends org.apache.cxf.rt.security.Security
      */
     public static final String DELEGATED_CREDENTIAL = "ws-security.delegated.credential";
     
+    /**
+     * A WSS4JSecurityContextCreator implementation that is used to create a CXF SecurityContext
+     * from the set of WSS4J processing results. The default implementation is the
+     * DefaultWSS4JSecurityContextCreator. This configuration tag allows the user to plug in
+     * a custom way of setting up the CXF SecurityContext.
+     */
+    public static final String SECURITY_CONTEXT_CREATOR = "ws-security.security.context.creator";
+    
     //
     // Validator implementations for validating received security tokens
     //
@@ -397,7 +405,7 @@ public final class SecurityConstants extends org.apache.cxf.rt.security.Security
             CACHE_IDENTIFIER, DELEGATED_CREDENTIAL, KERBEROS_USE_CREDENTIAL_DELEGATION, 
             KERBEROS_IS_USERNAME_IN_SERVICENAME_FORM, KERBEROS_REQUEST_CREDENTIAL_DELEGATION, 
             POLICY_VALIDATOR_MAP, STORE_BYTES_IN_ATTACHMENT, USE_ATTACHMENT_ENCRYPTION_CONTENT_ONLY_TRANSFORM,
-            SYMMETRIC_SIGNATURE_ALGORITHM
+            SYMMETRIC_SIGNATURE_ALGORITHM, SECURITY_CONTEXT_CREATOR
         }));
         for (String commonProperty : COMMON_PROPERTIES) {
             s.add(commonProperty);

http://git-wip-us.apache.org/repos/asf/cxf/blob/a9db299a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
index 5bec27f..3b3fa01 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
@@ -25,6 +25,10 @@ import java.util.logging.Logger;
 
 import javax.security.auth.Subject;
 import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.stream.XMLStreamException;
+
+import org.w3c.dom.Element;
 
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.common.logging.LogUtils;
@@ -39,6 +43,7 @@ import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSecurityEngine;
 import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.handler.WSHandlerResult;
 import org.apache.wss4j.dom.validate.UsernameTokenValidator;
 import org.apache.wss4j.dom.validate.Validator;
 
@@ -102,12 +107,15 @@ public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS
     }
     
     @Override
-    protected SecurityContext createSecurityContext(final Principal p) {
-        Message msg = PhaseInterceptorChain.getCurrentMessage();
-        if (msg == null) {
-            throw new IllegalStateException("Current message is not available");
-        }
-        return doCreateSecurityContext(p, msg.get(Subject.class));
+    protected void doResults(
+                             SoapMessage msg, 
+                             String actor,
+                             Element soapHeader,
+                             Element soapBody,
+                             WSHandlerResult wsResult, 
+                             boolean utWithCallbacks
+    ) throws SOAPException, XMLStreamException, WSSecurityException {
+        new UsernameTokenSecurityContextCreator().createSecurityContext(msg, wsResult);
     }
     
     /**
@@ -233,4 +241,15 @@ public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS
         
     }
     
+    private static class UsernameTokenSecurityContextCreator extends DefaultWSS4JSecurityContextCreator {
+        
+        @Override
+        protected SecurityContext createSecurityContext(final Principal p) {
+            Message msg = PhaseInterceptorChain.getCurrentMessage();
+            if (msg == null) {
+                throw new IllegalStateException("Current message is not available");
+            }
+            return new DefaultSecurityContext(p, msg.get(Subject.class));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a9db299a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
new file mode 100644
index 0000000..8069a95
--- /dev/null
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
@@ -0,0 +1,205 @@
+/**
+ * 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.wss4j;
+
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.security.DefaultSecurityContext;
+import org.apache.cxf.interceptor.security.RolePrefixSecurityContextImpl;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.rt.security.claims.ClaimCollection;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
+import org.apache.cxf.rt.security.saml.utils.SAMLUtils;
+import org.apache.cxf.rt.security.utils.SecurityUtils;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
+import org.apache.wss4j.dom.handler.WSHandlerConstants;
+import org.apache.wss4j.dom.handler.WSHandlerResult;
+import org.apache.wss4j.dom.message.token.KerberosSecurity;
+
+/**
+ * The default implementation to create a SecurityContext from a set of WSS4J processing results.
+ */
+public class DefaultWSS4JSecurityContextCreator implements WSS4JSecurityContextCreator {
+    
+    private static final List<Integer> DEFAULT_SECURITY_PRIORITIES = new ArrayList<>();
+    static {
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.ST_SIGNED);
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.ST_UNSIGNED);
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.UT);
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.BST);
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.SIGN);
+        DEFAULT_SECURITY_PRIORITIES.add(WSConstants.UT_NOPASSWORD);
+    }
+
+    private List<Integer> securityPriorities = new ArrayList<>(DEFAULT_SECURITY_PRIORITIES);
+    
+    /**
+     * Create a SecurityContext and store it on the SoapMessage parameter
+     */
+    public void createSecurityContext(SoapMessage msg, WSHandlerResult handlerResult) {
+        /*
+         * All ok up to this point. Now construct and setup the security result
+         * structure. The service may fetch this and check it.
+         */
+        List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
+        if (results == null) {
+            results = new LinkedList<>();
+            msg.put(WSHandlerConstants.RECV_RESULTS, results);
+        }
+        results.add(0, handlerResult);
+        
+        String allowUnsigned = 
+            (String)SecurityUtils.getSecurityPropertyValue(
+                SecurityConstants.ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, msg
+            );
+        boolean allowUnsignedSamlPrincipals = Boolean.parseBoolean(allowUnsigned);
+        boolean useJAASSubject = true; 
+        String useJAASSubjectStr = 
+            (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SC_FROM_JAAS_SUBJECT, msg);
+        if (useJAASSubjectStr != null) {
+            useJAASSubject = Boolean.parseBoolean(useJAASSubjectStr);
+        }
+        
+        // Now go through the results in a certain order to set up a security context. Highest priority is first.
+        Map<Integer, List<WSSecurityEngineResult>> actionResults = handlerResult.getActionResults();
+        for (Integer resultPriority : securityPriorities) {
+            if (resultPriority == WSConstants.ST_UNSIGNED && !allowUnsignedSamlPrincipals) {
+                continue;
+            }
+            
+            List<WSSecurityEngineResult> foundResults = actionResults.get(resultPriority);
+            if (foundResults != null && !foundResults.isEmpty()) {
+                for (WSSecurityEngineResult result : foundResults) {
+                    final Object binarySecurity = result.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+                    PublicKey publickey = 
+                        (PublicKey)result.get(WSSecurityEngineResult.TAG_PUBLIC_KEY);
+                    X509Certificate cert = 
+                        (X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+                    
+                    if ((resultPriority == WSConstants.BST && !(binarySecurity instanceof KerberosSecurity))
+                        || (resultPriority == WSConstants.SIGN && publickey == null && cert == null)) {
+                        continue;
+                    }
+                    SecurityContext context = createSecurityContext(msg, useJAASSubject, result);
+                    if (context != null) {
+                        msg.put(SecurityContext.class, context);
+                        return;
+                    }
+                }
+            }
+        }
+    }
+    
+    protected SecurityContext createSecurityContext(
+        SoapMessage msg, boolean useJAASSubject, WSSecurityEngineResult wsResult
+    ) {
+        final Principal p = (Principal)wsResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+        final Subject subject = (Subject)wsResult.get(WSSecurityEngineResult.TAG_SUBJECT);
+        
+        if (subject != null && !(p instanceof KerberosPrincipal) && useJAASSubject) {
+            String roleClassifier = 
+                (String)msg.getContextualProperty(SecurityConstants.SUBJECT_ROLE_CLASSIFIER);
+            if (roleClassifier != null && !"".equals(roleClassifier)) {
+                String roleClassifierType = 
+                    (String)msg.getContextualProperty(SecurityConstants.SUBJECT_ROLE_CLASSIFIER_TYPE);
+                if (roleClassifierType == null || "".equals(roleClassifierType)) {
+                    roleClassifierType = "prefix";
+                }
+                return new RolePrefixSecurityContextImpl(subject, roleClassifier, roleClassifierType);
+            } else {
+                return new DefaultSecurityContext(p, subject);
+            }
+        } else if (p != null) {
+            boolean utWithCallbacks = 
+                MessageUtils.getContextualBoolean(msg, SecurityConstants.VALIDATE_TOKEN, true);
+            if (!utWithCallbacks) {
+                WSS4JTokenConverter.convertToken(msg, p);
+            }
+            Object receivedAssertion = wsResult.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN);
+            if (receivedAssertion == null) {
+                receivedAssertion = wsResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+            }
+            if (wsResult.get(WSSecurityEngineResult.TAG_DELEGATION_CREDENTIAL) != null) {
+                msg.put(SecurityConstants.DELEGATED_CREDENTIAL, 
+                        wsResult.get(WSSecurityEngineResult.TAG_DELEGATION_CREDENTIAL));
+            }
+            
+            if (receivedAssertion instanceof SamlAssertionWrapper) {
+                String roleAttributeName = (String)SecurityUtils.getSecurityPropertyValue(
+                        SecurityConstants.SAML_ROLE_ATTRIBUTENAME, msg);
+                if (roleAttributeName == null || roleAttributeName.length() == 0) {
+                    roleAttributeName = WSS4JInInterceptor.SAML_ROLE_ATTRIBUTENAME_DEFAULT;
+                }
+                
+                ClaimCollection claims = 
+                    SAMLUtils.getClaims((SamlAssertionWrapper)receivedAssertion);
+                Set<Principal> roles = 
+                    SAMLUtils.parseRolesFromClaims(claims, roleAttributeName, null);
+                
+                SAMLSecurityContext context = 
+                    new SAMLSecurityContext(p, roles, claims);
+                context.setIssuer(SAMLUtils.getIssuer(receivedAssertion));
+                context.setAssertionElement(SAMLUtils.getAssertionElement(receivedAssertion));
+                return context;
+            } else {
+                return createSecurityContext(p);
+            }
+        }
+        
+        return null;
+    }
+    
+    protected SecurityContext createSecurityContext(final Principal p) {
+        return new SecurityContext() {
+
+            public Principal getUserPrincipal() {
+                return p;
+            }
+
+            public boolean isUserInRole(String arg0) {
+                return false;
+            }
+        };
+    }
+    
+    public List<Integer> getSecurityPriorities() {
+        return securityPriorities;
+    }
+
+    public void setSecurityPriorities(List<Integer> securityPriorities) {
+        this.securityPriorities = securityPriorities;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a9db299a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
index 20b70a5..020b4ca 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
@@ -18,23 +18,16 @@
  */
 package org.apache.cxf.ws.security.wss4j;
 
-import java.security.Principal;
 import java.security.Provider;
-import java.security.PublicKey;
 import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPException;
 import javax.xml.soap.SOAPMessage;
@@ -45,6 +38,7 @@ import javax.xml.transform.dom.DOMSource;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
+
 import org.apache.cxf.binding.soap.SoapFault;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.binding.soap.SoapVersion;
@@ -55,15 +49,9 @@ import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.interceptor.security.DefaultSecurityContext;
-import org.apache.cxf.interceptor.security.RolePrefixSecurityContextImpl;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.rt.security.claims.ClaimCollection;
-import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
-import org.apache.cxf.rt.security.saml.utils.SAMLUtils;
 import org.apache.cxf.rt.security.utils.SecurityUtils;
-import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.security.transport.TLSSessionInfo;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.ws.security.SecurityConstants;
@@ -73,7 +61,6 @@ import org.apache.wss4j.common.cache.ReplayCache;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.ThreadLocalSecurityProvider;
 import org.apache.wss4j.common.ext.WSSecurityException;
-import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSConfig;
 import org.apache.wss4j.dom.engine.WSSecurityEngine;
@@ -81,7 +68,6 @@ import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.handler.WSHandlerConstants;
 import org.apache.wss4j.dom.handler.WSHandlerResult;
-import org.apache.wss4j.dom.message.token.KerberosSecurity;
 import org.apache.wss4j.dom.processor.Processor;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.wss4j.dom.validate.NoOpValidator;
@@ -496,134 +482,17 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
         WSHandlerResult wsResult, 
         boolean utWithCallbacks
     ) throws SOAPException, XMLStreamException, WSSecurityException {
-        /*
-         * All ok up to this point. Now construct and setup the security result
-         * structure. The service may fetch this and check it.
-         */
-        List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
-        if (results == null) {
-            results = new LinkedList<>();
-            msg.put(WSHandlerConstants.RECV_RESULTS, results);
-        }
-        results.add(0, wsResult);
-        
-        String allowUnsigned = 
-            (String)SecurityUtils.getSecurityPropertyValue(
-                SecurityConstants.ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, msg
-            );
-        boolean allowUnsignedSamlPrincipals = Boolean.parseBoolean(allowUnsigned);
-        boolean useJAASSubject = true; 
-        String useJAASSubjectStr = 
-            (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SC_FROM_JAAS_SUBJECT, msg);
-        if (useJAASSubjectStr != null) {
-            useJAASSubject = Boolean.parseBoolean(useJAASSubjectStr);
-        }
-        
-        // Now go through the results in a certain order to set up a security context. Highest priority is first.
-        
-        List<Integer> resultPriorities = new ArrayList<>();
-        resultPriorities.add(WSConstants.ST_SIGNED);
-        resultPriorities.add(WSConstants.ST_UNSIGNED);
-        resultPriorities.add(WSConstants.UT);
-        resultPriorities.add(WSConstants.BST);
-        resultPriorities.add(WSConstants.SIGN);
-        resultPriorities.add(WSConstants.UT_NOPASSWORD);
         
-        Map<Integer, List<WSSecurityEngineResult>> actionResults = wsResult.getActionResults();
-        for (Integer resultPriority : resultPriorities) {
-            if (resultPriority == WSConstants.ST_UNSIGNED && !allowUnsignedSamlPrincipals) {
-                continue;
-            }
-            
-            List<WSSecurityEngineResult> foundResults = actionResults.get(resultPriority);
-            if (foundResults != null && !foundResults.isEmpty()) {
-                for (WSSecurityEngineResult result : foundResults) {
-                    final Object binarySecurity = result.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
-                    PublicKey publickey = 
-                        (PublicKey)result.get(WSSecurityEngineResult.TAG_PUBLIC_KEY);
-                    X509Certificate cert = 
-                        (X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
-                    
-                    if ((resultPriority == WSConstants.BST && !(binarySecurity instanceof KerberosSecurity))
-                        || (resultPriority == WSConstants.SIGN && publickey == null && cert == null)) {
-                        continue;
-                    }
-                    SecurityContext context = 
-                        createSecurityContext(msg, useJAASSubject, result, utWithCallbacks);
-                    if (context != null) {
-                        msg.put(SecurityContext.class, context);
-                        return;
-                    }
-                }
-            }
+        WSS4JSecurityContextCreator contextCreator = 
+            (WSS4JSecurityContextCreator)SecurityUtils.getSecurityPropertyValue(
+                SecurityConstants.SECURITY_CONTEXT_CREATOR, msg);
+        if (contextCreator != null) {
+            contextCreator.createSecurityContext(msg, wsResult);
+        } else {
+            new DefaultWSS4JSecurityContextCreator().createSecurityContext(msg, wsResult);
         }
     }
     
-    private SecurityContext createSecurityContext(
-        SoapMessage msg, boolean useJAASSubject,
-        WSSecurityEngineResult wsResult, boolean utWithCallbacks
-    ) {
-        final Principal p = (Principal)wsResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
-        final Subject subject = (Subject)wsResult.get(WSSecurityEngineResult.TAG_SUBJECT);
-        
-        return createSecurityContext(msg, subject, p, useJAASSubject, wsResult, utWithCallbacks);
-    }
-    
-    protected SecurityContext createSecurityContext(
-        SoapMessage msg, Subject subject, Principal p, boolean useJAASSubject,
-        WSSecurityEngineResult wsResult, boolean utWithCallbacks
-    ) {
-        if (subject != null && !(p instanceof KerberosPrincipal) && useJAASSubject) {
-            String roleClassifier = 
-                (String)msg.getContextualProperty(SecurityConstants.SUBJECT_ROLE_CLASSIFIER);
-            if (roleClassifier != null && !"".equals(roleClassifier)) {
-                String roleClassifierType = 
-                    (String)msg.getContextualProperty(SecurityConstants.SUBJECT_ROLE_CLASSIFIER_TYPE);
-                if (roleClassifierType == null || "".equals(roleClassifierType)) {
-                    roleClassifierType = "prefix";
-                }
-                return new RolePrefixSecurityContextImpl(subject, roleClassifier, roleClassifierType);
-            } else {
-                return new DefaultSecurityContext(p, subject);
-            }
-        } else if (p != null) {
-            if (!utWithCallbacks) {
-                WSS4JTokenConverter.convertToken(msg, p);
-            }
-            Object receivedAssertion = wsResult.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN);
-            if (receivedAssertion == null) {
-                receivedAssertion = wsResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
-            }
-            if (wsResult.get(WSSecurityEngineResult.TAG_DELEGATION_CREDENTIAL) != null) {
-                msg.put(SecurityConstants.DELEGATED_CREDENTIAL, 
-                        wsResult.get(WSSecurityEngineResult.TAG_DELEGATION_CREDENTIAL));
-            }
-            
-            if (receivedAssertion instanceof SamlAssertionWrapper) {
-                String roleAttributeName = (String)SecurityUtils.getSecurityPropertyValue(
-                        SecurityConstants.SAML_ROLE_ATTRIBUTENAME, msg);
-                if (roleAttributeName == null || roleAttributeName.length() == 0) {
-                    roleAttributeName = SAML_ROLE_ATTRIBUTENAME_DEFAULT;
-                }
-                
-                ClaimCollection claims = 
-                    SAMLUtils.getClaims((SamlAssertionWrapper)receivedAssertion);
-                Set<Principal> roles = 
-                    SAMLUtils.parseRolesFromClaims(claims, roleAttributeName, null);
-                
-                SAMLSecurityContext context = 
-                    new SAMLSecurityContext(p, roles, claims);
-                context.setIssuer(SAMLUtils.getIssuer(receivedAssertion));
-                context.setAssertionElement(SAMLUtils.getAssertionElement(receivedAssertion));
-                return context;
-            } else {
-                return createSecurityContext(p);
-            }
-        }
-        
-        return null;
-    }
-
     protected void advanceBody(
         SoapMessage msg, Node body
     ) throws SOAPException, XMLStreamException, WSSecurityException {
@@ -638,19 +507,6 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
         msg.setContent(XMLStreamReader.class, reader);
     }
     
-    protected SecurityContext createSecurityContext(final Principal p) {
-        return new SecurityContext() {
-
-            public Principal getUserPrincipal() {
-                return p;
-            }
-
-            public boolean isUserInRole(String arg0) {
-                return false;
-            }
-        };
-    }
-    
     private String getAction(SoapMessage msg, SoapVersion version) {
         String action = (String)getOption(WSHandlerConstants.ACTION);
         if (action == null) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/a9db299a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JSecurityContextCreator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JSecurityContextCreator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JSecurityContextCreator.java
new file mode 100644
index 0000000..a9f56e1
--- /dev/null
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JSecurityContextCreator.java
@@ -0,0 +1,34 @@
+/**
+ * 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.wss4j;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.wss4j.dom.handler.WSHandlerResult;
+
+/**
+ * A pluggable way to create a CXF SecurityContext Object from a set of WSS4J processing results
+ */
+public interface WSS4JSecurityContextCreator {
+    
+    /**
+     * Create a SecurityContext and store it on the SoapMessage parameter
+     */
+    void createSecurityContext(SoapMessage msg, WSHandlerResult handlerResult);
+    
+}


[2/3] cxf git commit: Minor change

Posted by co...@apache.org.
Minor change


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/864d3f30
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/864d3f30
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/864d3f30

Branch: refs/heads/master
Commit: 864d3f3070eeea5d717caef381cd91f310195b30
Parents: a9db299
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Feb 16 11:58:37 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Feb 16 11:58:37 2016 +0000

----------------------------------------------------------------------
 .../cxf/ws/security/wss4j/WSS4JInInterceptor.java   | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/864d3f30/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
index 020b4ca..d996711 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
@@ -294,13 +294,13 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
                     doResults(msg, actor, 
                               SAAJUtils.getHeader(doc),
                               SAAJUtils.getBody(doc),
-                              wsResult);
+                              wsResult, utWithCallbacks);
                 } else {
                     checkActions(msg, reqData, wsResult.getResults(), actions, SAAJUtils.getBody(doc));
                     doResults(msg, actor,
                               SAAJUtils.getHeader(doc),
                               SAAJUtils.getBody(doc),
-                              wsResult);
+                              wsResult, utWithCallbacks);
                 }
             }
             advanceBody(msg, SAAJUtils.getBody(doc));
@@ -469,17 +469,7 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
         String actor, 
         Element soapHeader,
         Element soapBody,
-        WSHandlerResult wsResult
-    ) throws SOAPException, XMLStreamException, WSSecurityException {
-        doResults(msg, actor, soapHeader, soapBody, wsResult, false);
-    }
-
-    protected void doResults(
-        SoapMessage msg, 
-        String actor,
-        Element soapHeader,
-        Element soapBody,
-        WSHandlerResult wsResult, 
+        WSHandlerResult wsResult,
         boolean utWithCallbacks
     ) throws SOAPException, XMLStreamException, WSSecurityException {
         


[3/3] cxf git commit: Adding a custom WSS4JSecurityContextCreator for an STS system test

Posted by co...@apache.org.
Adding a custom WSS4JSecurityContextCreator for an STS system test


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/d68286f7
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/d68286f7
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/d68286f7

Branch: refs/heads/master
Commit: d68286f715ef4a545989a04d31313a64078cf0cb
Parents: 864d3f3
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Feb 16 13:48:18 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Feb 16 13:48:18 2016 +0000

----------------------------------------------------------------------
 ...tUsernameTokenAuthenticatingInterceptor.java |  15 +++
 .../DefaultWSS4JSecurityContextCreator.java     |  13 --
 .../ws/security/wss4j/WSS4JInInterceptor.java   |  11 ++
 .../x509/CustomWSS4JSecurityContextCreator.java | 118 +++++++++++++++++++
 .../systest/sts/x509/cxf-asymmetric-service.xml |   4 +
 5 files changed, 148 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/d68286f7/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
index 3b3fa01..0d8d415 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
@@ -20,6 +20,8 @@ package org.apache.cxf.ws.security.wss4j;
 
 import java.security.Principal;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
 
@@ -34,6 +36,7 @@ import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.security.SecurityToken;
 import org.apache.cxf.common.security.UsernameToken;
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.security.DefaultSecurityContext;
 import org.apache.cxf.message.Message;
@@ -43,6 +46,7 @@ import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSecurityEngine;
 import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.handler.WSHandlerConstants;
 import org.apache.wss4j.dom.handler.WSHandlerResult;
 import org.apache.wss4j.dom.validate.UsernameTokenValidator;
 import org.apache.wss4j.dom.validate.Validator;
@@ -115,6 +119,17 @@ public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS
                              WSHandlerResult wsResult, 
                              boolean utWithCallbacks
     ) throws SOAPException, XMLStreamException, WSSecurityException {
+        /*
+         * All ok up to this point. Now construct and setup the security result
+         * structure. The service may fetch this and check it.
+         */
+        List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
+        if (results == null) {
+            results = new LinkedList<>();
+            msg.put(WSHandlerConstants.RECV_RESULTS, results);
+        }
+        results.add(0, wsResult);
+        
         new UsernameTokenSecurityContextCreator().createSecurityContext(msg, wsResult);
     }
     

http://git-wip-us.apache.org/repos/asf/cxf/blob/d68286f7/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
index 8069a95..5a832ef 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultWSS4JSecurityContextCreator.java
@@ -22,7 +22,6 @@ import java.security.Principal;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -31,7 +30,6 @@ import javax.security.auth.Subject;
 import javax.security.auth.kerberos.KerberosPrincipal;
 
 import org.apache.cxf.binding.soap.SoapMessage;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.security.DefaultSecurityContext;
 import org.apache.cxf.interceptor.security.RolePrefixSecurityContextImpl;
 import org.apache.cxf.message.MessageUtils;
@@ -44,7 +42,6 @@ import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
-import org.apache.wss4j.dom.handler.WSHandlerConstants;
 import org.apache.wss4j.dom.handler.WSHandlerResult;
 import org.apache.wss4j.dom.message.token.KerberosSecurity;
 
@@ -69,16 +66,6 @@ public class DefaultWSS4JSecurityContextCreator implements WSS4JSecurityContextC
      * Create a SecurityContext and store it on the SoapMessage parameter
      */
     public void createSecurityContext(SoapMessage msg, WSHandlerResult handlerResult) {
-        /*
-         * All ok up to this point. Now construct and setup the security result
-         * structure. The service may fetch this and check it.
-         */
-        List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
-        if (results == null) {
-            results = new LinkedList<>();
-            msg.put(WSHandlerConstants.RECV_RESULTS, results);
-        }
-        results.add(0, handlerResult);
         
         String allowUnsigned = 
             (String)SecurityUtils.getSecurityPropertyValue(

http://git-wip-us.apache.org/repos/asf/cxf/blob/d68286f7/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
index d996711..1a0a758 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
@@ -22,6 +22,7 @@ import java.security.Provider;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
@@ -472,6 +473,16 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
         WSHandlerResult wsResult,
         boolean utWithCallbacks
     ) throws SOAPException, XMLStreamException, WSSecurityException {
+        /*
+         * All ok up to this point. Now construct and setup the security result
+         * structure. The service may fetch this and check it.
+         */
+        List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
+        if (results == null) {
+            results = new LinkedList<>();
+            msg.put(WSHandlerConstants.RECV_RESULTS, results);
+        }
+        results.add(0, wsResult);
         
         WSS4JSecurityContextCreator contextCreator = 
             (WSS4JSecurityContextCreator)SecurityUtils.getSecurityPropertyValue(

http://git-wip-us.apache.org/repos/asf/cxf/blob/d68286f7/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/x509/CustomWSS4JSecurityContextCreator.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/x509/CustomWSS4JSecurityContextCreator.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/x509/CustomWSS4JSecurityContextCreator.java
new file mode 100644
index 0000000..31ec71b
--- /dev/null
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/x509/CustomWSS4JSecurityContextCreator.java
@@ -0,0 +1,118 @@
+/**
+ * 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.systest.sts.x509;
+
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.rt.security.claims.ClaimCollection;
+import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext;
+import org.apache.cxf.rt.security.saml.utils.SAMLUtils;
+import org.apache.cxf.rt.security.utils.SecurityUtils;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.wss4j.DefaultWSS4JSecurityContextCreator;
+import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
+import org.apache.wss4j.dom.handler.WSHandlerResult;
+
+/**
+ * A custom WSS4JSecurityContextCreator implementation. It creates a SecurityContext using the principal from an
+ * asymmetric signature, but populates the roles from a SAML Token.
+ */
+public class CustomWSS4JSecurityContextCreator extends DefaultWSS4JSecurityContextCreator {
+    
+    /**
+     * Create a SecurityContext and store it on the SoapMessage parameter
+     */
+    public void createSecurityContext(SoapMessage msg, WSHandlerResult handlerResult) {
+        Map<Integer, List<WSSecurityEngineResult>> actionResults = handlerResult.getActionResults();
+        
+        Principal asymmetricPrincipal = null;
+        
+        // Get Asymmetric Signature action
+        List<WSSecurityEngineResult> foundResults = actionResults.get(WSConstants.SIGN);
+        if (foundResults != null && !foundResults.isEmpty()) {
+            for (WSSecurityEngineResult result : foundResults) {
+                PublicKey publickey = 
+                    (PublicKey)result.get(WSSecurityEngineResult.TAG_PUBLIC_KEY);
+                X509Certificate cert = 
+                    (X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+                
+                if (publickey == null && cert == null) {
+                    continue;
+                }
+                SecurityContext context = createSecurityContext(msg, true, result);
+                if (context != null && context.getUserPrincipal() != null) {
+                    asymmetricPrincipal = context.getUserPrincipal();
+                    break;
+                }
+            }
+        }
+        
+        // We must have an asymmetric principal
+        if (asymmetricPrincipal == null) {
+            return;
+        }
+        
+        // Get signed SAML action
+        SAMLSecurityContext context = null;
+        foundResults = actionResults.get(WSConstants.ST_SIGNED);
+        if (foundResults != null && !foundResults.isEmpty()) {
+            for (WSSecurityEngineResult result : foundResults) {
+                Object receivedAssertion = result.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN);
+                if (receivedAssertion == null) {
+                    receivedAssertion = result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+                }
+
+                if (receivedAssertion instanceof SamlAssertionWrapper) {
+                    String roleAttributeName = 
+                        (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SAML_ROLE_ATTRIBUTENAME, 
+                                                                       msg);
+                    if (roleAttributeName == null || roleAttributeName.length() == 0) {
+                        roleAttributeName = WSS4JInInterceptor.SAML_ROLE_ATTRIBUTENAME_DEFAULT;
+                    }
+
+                    ClaimCollection claims = 
+                        SAMLUtils.getClaims((SamlAssertionWrapper)receivedAssertion);
+                    Set<Principal> roles = 
+                        SAMLUtils.parseRolesFromClaims(claims, roleAttributeName, null);
+
+                    context = new SAMLSecurityContext(asymmetricPrincipal, roles, claims);
+                    context.setIssuer(SAMLUtils.getIssuer(receivedAssertion));
+                    context.setAssertionElement(SAMLUtils.getAssertionElement(receivedAssertion));
+                    break;
+                }
+            }
+        }
+        
+        if (context != null) {
+            msg.put(SecurityContext.class, context);
+        }
+        
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/d68286f7/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/x509/cxf-asymmetric-service.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/x509/cxf-asymmetric-service.xml b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/x509/cxf-asymmetric-service.xml
index 02d3158..4402a09 100644
--- a/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/x509/cxf-asymmetric-service.xml
+++ b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/x509/cxf-asymmetric-service.xml
@@ -35,12 +35,16 @@
        </property>
     </bean>
     
+    <bean id="customSecurityContextCreator" 
+          class="org.apache.cxf.systest.sts.x509.CustomWSS4JSecurityContextCreator" />
+    
     <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="doubleitasymmetricsaml2" implementor="org.apache.cxf.systest.sts.common.DoubleItPortTypeImpl" endpointName="s:DoubleItAsymmetricSAML2Port" serviceName="s:DoubleItService" address="http://localhost:${testutil.ports.AsymmetricServer}/doubleit/services/doubleitasymmetricsaml2" wsdlLocation="org/apache/cxf/systest/sts/x509/DoubleItAsymmetric.wsdl">
         <jaxws:properties>
             <entry key="security.signature.username" value="myservicekey"/>
             <entry key="security.callback-handler" value="org.apache.cxf.systest.sts.common.CommonCallbackHandler"/>
             <entry key="security.signature.properties" value="serviceKeystore2.properties"/>
             <entry key="security.encryption.username" value="useReqSigCert"/>
+            <entry key="ws-security.security.context.creator" value-ref="customSecurityContextCreator"/>
         </jaxws:properties>
         <jaxws:inInterceptors>
              <ref bean="authorizationInterceptor"/>