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 2015/04/17 13:13:25 UTC

cxf-fediz git commit: Downgrading to CXF 3.0.4 for the release

Repository: cxf-fediz
Updated Branches:
  refs/heads/master 541c991fa -> 9d8f98acd


Downgrading to CXF 3.0.4 for the release


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

Branch: refs/heads/master
Commit: 9d8f98acd71b2b2d2c2eb257b38419926e4ffd64
Parents: 541c991
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Apr 17 12:13:09 2015 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Apr 17 12:13:09 2015 +0100

----------------------------------------------------------------------
 pom.xml                                         |   2 +-
 .../service/sts/DefaultSubjectProvider.java     | 298 +++++++++++++++++++
 .../fediz/service/sts/X509TokenValidator.java   | 199 +++++++++++++
 .../src/main/webapp/WEB-INF/cxf-transport.xml   |   5 +-
 4 files changed, 502 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/9d8f98ac/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f4c9429..3348d25 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
         <apacheds.version>2.0.0-M19</apacheds.version>
         <commons.lang.version>3.3.2</commons.lang.version>
         <commons.logging.version>1.1.3</commons.logging.version>
-        <cxf.version>3.0.5-SNAPSHOT</cxf.version>
+        <cxf.version>3.0.4</cxf.version>
         <cxf.build-utils.version>3.0.0</cxf.build-utils.version>
         <easymock.version>3.3</easymock.version>
         <ehcache.version>2.8.5</ehcache.version>

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/9d8f98ac/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/DefaultSubjectProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/DefaultSubjectProvider.java b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/DefaultSubjectProvider.java
new file mode 100644
index 0000000..cf0f7d4
--- /dev/null
+++ b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/DefaultSubjectProvider.java
@@ -0,0 +1,298 @@
+/**
+ * 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.fediz.service.sts;
+
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedKey;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.ReceivedToken.STATE;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.token.provider.SubjectProvider;
+import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.bean.KeyInfoBean;
+import org.apache.wss4j.common.saml.bean.KeyInfoBean.CERT_IDENTIFIER;
+import org.apache.wss4j.common.saml.bean.SubjectBean;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.message.WSSecEncryptedKey;
+
+/**
+ * A default implementation of SubjectProvider to create a SAML Assertion. The Subject name is the name
+ * of the current principal, the subject name qualifier is a default URL that can be configured, and the
+ * subject confirmation method is created according to the token type and key type. If the Subject
+ * Confirmation Method is SymmetricKey or PublicKey, the appropriate KeyInfoBean object is created and
+ * attached to the Subject.
+ */
+public class DefaultSubjectProvider implements SubjectProvider {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(DefaultSubjectProvider.class);
+    private String subjectNameQualifier = "http://cxf.apache.org/sts";
+    private String subjectNameIDFormat = SAML2Constants.NAMEID_FORMAT_UNSPECIFIED;
+    
+    /**
+     * Set the SubjectNameQualifier.
+     */
+    public void setSubjectNameQualifier(String subjectNameQualifier) {
+        this.subjectNameQualifier = subjectNameQualifier;
+        LOG.fine("Setting Subject Name Qualifier: " + subjectNameQualifier);
+    }
+    
+    /**
+     * Set the SubjectNameIDFormat.
+     */
+    public void setSubjectNameIDFormat(String subjectNameIDFormat) {
+        this.subjectNameIDFormat = subjectNameIDFormat;
+        LOG.fine("Setting Subject Name format: " + subjectNameIDFormat);
+    }
+
+    /**
+     * Get a SubjectBean object.
+     */
+    public SubjectBean getSubject(
+        TokenProviderParameters providerParameters, Document doc, byte[] secret
+    ) {
+        TokenRequirements tokenRequirements = providerParameters.getTokenRequirements();
+        KeyRequirements keyRequirements = providerParameters.getKeyRequirements();
+        STSPropertiesMBean stsProperties = providerParameters.getStsProperties();
+
+        String tokenType = tokenRequirements.getTokenType();
+        String keyType = keyRequirements.getKeyType();
+        String confirmationMethod = getSubjectConfirmationMethod(tokenType, keyType);
+        
+        Principal principal = null;
+        ReceivedToken receivedToken = null;
+        //TokenValidator in IssueOperation has validated the ReceivedToken
+        //if validation was successful, the principal was set in ReceivedToken 
+        if (providerParameters.getTokenRequirements().getOnBehalfOf() != null) {
+            receivedToken = providerParameters.getTokenRequirements().getOnBehalfOf();    
+            if (receivedToken.getState().equals(STATE.VALID)) {
+                principal = receivedToken.getPrincipal();
+            }
+        } else if (providerParameters.getTokenRequirements().getActAs() != null) {
+            receivedToken = providerParameters.getTokenRequirements().getActAs();
+            if (receivedToken.getState().equals(STATE.VALID)) {
+                principal = receivedToken.getPrincipal();
+            }
+        } else if (providerParameters.getTokenRequirements().getValidateTarget() != null) {
+            receivedToken = providerParameters.getTokenRequirements().getValidateTarget();
+            if (receivedToken.getState().equals(STATE.VALID)) {
+                principal = receivedToken.getPrincipal();
+            }
+        } else {
+            principal = providerParameters.getPrincipal();
+        }
+        
+        if (principal == null) {
+            LOG.fine("Error in getting principal");
+            throw new STSException("Error in getting principal", STSException.REQUEST_FAILED);
+        }
+        
+        String subjectName = principal.getName();
+        if (SAML2Constants.NAMEID_FORMAT_UNSPECIFIED.equals(subjectNameIDFormat)
+            && principal instanceof X500Principal) {
+            // Just use the "cn" instead of the entire DN
+            try {
+                String principalName = principal.getName();
+                int index = principalName.indexOf('=');
+                principalName = principalName.substring(index + 1, principalName.indexOf(',', index));
+                subjectName = principalName;
+            } catch (Throwable ex) {
+                subjectName = principal.getName();
+                //Ignore, not X500 compliant thus use the whole string as the value
+            }
+        }
+        
+        SubjectBean subjectBean = 
+            new SubjectBean(subjectName, subjectNameQualifier, confirmationMethod);
+        LOG.fine("Creating new subject with principal name: " + principal.getName());
+        if (subjectNameIDFormat != null && subjectNameIDFormat.length() > 0) {
+            subjectBean.setSubjectNameIDFormat(subjectNameIDFormat);
+        }
+        
+        if (STSConstants.SYMMETRIC_KEY_KEYTYPE.equals(keyType)) {
+            Crypto crypto = stsProperties.getEncryptionCrypto();
+
+            EncryptionProperties encryptionProperties = providerParameters.getEncryptionProperties();
+            String encryptionName = encryptionProperties.getEncryptionName();
+            if (encryptionName == null) {
+                // Fall back on the STS encryption name
+                encryptionName = stsProperties.getEncryptionUsername();
+            }
+            if (encryptionName == null) {
+                LOG.fine("No encryption Name is configured for Symmetric KeyType");
+                throw new STSException("No Encryption Name is configured", STSException.REQUEST_FAILED);
+            }
+            
+            CryptoType cryptoType = null;
+
+            // Check for using of service endpoint (AppliesTo) as certificate identifier
+            if (STSConstants.USE_ENDPOINT_AS_CERT_ALIAS.equals(encryptionName)) {
+                if (providerParameters.getAppliesToAddress() == null) {
+                    throw new STSException("AppliesTo is not initilaized for encryption name "
+                                           + STSConstants.USE_ENDPOINT_AS_CERT_ALIAS);
+                }
+                cryptoType = new CryptoType(CryptoType.TYPE.ENDPOINT);
+                cryptoType.setEndpoint(providerParameters.getAppliesToAddress());
+            } else {
+                cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+                cryptoType.setAlias(encryptionName);
+            }
+
+            try {
+                X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+                if ((certs == null) || (certs.length == 0)) {
+                    throw new STSException("Encryption certificate is not found for alias: " + encryptionName);
+                }
+                KeyInfoBean keyInfo = 
+                    createKeyInfo(certs[0], secret, doc, encryptionProperties, crypto);
+                subjectBean.setKeyInfo(keyInfo);
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+                throw new STSException(ex.getMessage(), ex);
+            }
+        } else if (STSConstants.PUBLIC_KEY_KEYTYPE.equals(keyType)) {
+            ReceivedKey receivedKey = keyRequirements.getReceivedKey();
+            
+            // Validate UseKey trust
+            if (stsProperties.isValidateUseKey() && stsProperties.getSignatureCrypto() != null) {
+                if (receivedKey.getX509Cert() != null) {
+                    try {
+                        Collection<Pattern> constraints = Collections.emptyList();
+                        stsProperties.getSignatureCrypto().verifyTrust(
+                            new X509Certificate[]{receivedKey.getX509Cert()}, false, constraints);
+                    } catch (WSSecurityException e) {
+                        LOG.log(Level.FINE, "Error in trust validation of UseKey: ", e);
+                        throw new STSException("Error in trust validation of UseKey", STSException.REQUEST_FAILED);
+                    }
+                }
+                if (receivedKey.getPublicKey() != null) {
+                    try {
+                        stsProperties.getSignatureCrypto().verifyTrust(receivedKey.getPublicKey());
+                    } catch (WSSecurityException e) {
+                        LOG.log(Level.FINE, "Error in trust validation of UseKey: ", e);
+                        throw new STSException("Error in trust validation of UseKey", STSException.REQUEST_FAILED);
+                    }
+                }
+            }
+            
+            KeyInfoBean keyInfo = createKeyInfo(receivedKey.getX509Cert(), receivedKey.getPublicKey());
+            subjectBean.setKeyInfo(keyInfo);
+        }
+        
+        return subjectBean;
+    }
+        
+    /**
+     * Get the SubjectConfirmation method given a tokenType and keyType
+     */
+    protected String getSubjectConfirmationMethod(String tokenType, String keyType) {
+        if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
+            || WSConstants.SAML2_NS.equals(tokenType)) {
+            if (STSConstants.SYMMETRIC_KEY_KEYTYPE.equals(keyType) 
+                || STSConstants.PUBLIC_KEY_KEYTYPE.equals(keyType)) {
+                return SAML2Constants.CONF_HOLDER_KEY;
+            } else {
+                return SAML2Constants.CONF_BEARER;
+            }
+        } else {
+            if (STSConstants.SYMMETRIC_KEY_KEYTYPE.equals(keyType) 
+                || STSConstants.PUBLIC_KEY_KEYTYPE.equals(keyType)) {
+                return SAML1Constants.CONF_HOLDER_KEY;
+            } else {
+                return SAML1Constants.CONF_BEARER;
+            }
+        }
+    }
+
+    /**
+     * Create a KeyInfoBean that contains an X.509 certificate or Public Key
+     */
+    protected static KeyInfoBean createKeyInfo(X509Certificate certificate, PublicKey publicKey) {
+        KeyInfoBean keyInfo = new KeyInfoBean();
+
+        if (certificate != null) {
+            keyInfo.setCertificate(certificate);
+            keyInfo.setCertIdentifer(CERT_IDENTIFIER.X509_CERT);
+        } else if (publicKey != null) {
+            keyInfo.setPublicKey(publicKey);
+            keyInfo.setCertIdentifer(CERT_IDENTIFIER.KEY_VALUE);
+        }
+
+        return keyInfo;
+    }
+
+    /**
+     * Create an EncryptedKey KeyInfo.
+     */
+    protected static KeyInfoBean createKeyInfo(
+        X509Certificate certificate, 
+        byte[] secret,
+        Document doc,
+        EncryptionProperties encryptionProperties,
+        Crypto encryptionCrypto
+    ) throws WSSecurityException {
+        KeyInfoBean keyInfo = new KeyInfoBean();
+
+        // Create an EncryptedKey
+        WSSecEncryptedKey encrKey = new WSSecEncryptedKey();
+        encrKey.setKeyIdentifierType(encryptionProperties.getKeyIdentifierType());
+        encrKey.setEphemeralKey(secret);
+        encrKey.setSymmetricEncAlgorithm(encryptionProperties.getEncryptionAlgorithm());
+        encrKey.setUseThisCert(certificate);
+        encrKey.setKeyEncAlgo(encryptionProperties.getKeyWrapAlgorithm());
+        encrKey.prepare(doc, encryptionCrypto);
+        Element encryptedKeyElement = encrKey.getEncryptedKeyElement();
+
+        // Append the EncryptedKey to a KeyInfo element
+        Element keyInfoElement = 
+            doc.createElementNS(
+                WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
+            );
+        keyInfoElement.setAttributeNS(
+            WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
+        );
+        keyInfoElement.appendChild(encryptedKeyElement);
+
+        keyInfo.setElement(keyInfoElement);
+
+        return keyInfo;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/9d8f98ac/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/X509TokenValidator.java
----------------------------------------------------------------------
diff --git a/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/X509TokenValidator.java b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/X509TokenValidator.java
new file mode 100644
index 0000000..c2bf638
--- /dev/null
+++ b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/X509TokenValidator.java
@@ -0,0 +1,199 @@
+/**
+ * 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.fediz.service.sts;
+
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.ReceivedToken.STATE;
+import org.apache.cxf.sts.token.realm.CertConstraintsParser;
+import org.apache.cxf.sts.token.validator.TokenValidator;
+import org.apache.cxf.sts.token.validator.TokenValidatorParameters;
+import org.apache.cxf.sts.token.validator.TokenValidatorResponse;
+import org.apache.cxf.ws.security.sts.provider.model.secext.BinarySecurityTokenType;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSSConfig;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.message.token.BinarySecurity;
+import org.apache.wss4j.dom.message.token.X509Security;
+import org.apache.wss4j.dom.validate.Credential;
+import org.apache.wss4j.dom.validate.SignatureTrustValidator;
+import org.apache.wss4j.dom.validate.Validator;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.content.X509Data;
+
+/**
+ * This class validates an X.509 V.3 certificate (received as a BinarySecurityToken or an X509Data
+ * DOM Element). The cert must be known (or trusted) by the STS crypto object.
+ */
+public class X509TokenValidator implements TokenValidator {
+    
+    public static final String X509_V3_TYPE = WSConstants.X509TOKEN_NS + "#X509v3";
+    
+    public static final String BASE64_ENCODING = WSConstants.SOAPMESSAGE_NS + "#Base64Binary";
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(X509TokenValidator.class);
+    
+    private Validator validator = new SignatureTrustValidator();
+    
+    private CertConstraintsParser certConstraints = new CertConstraintsParser();
+
+    /**
+     * Set a list of Strings corresponding to regular expression constraints on the subject DN
+     * of a certificate
+     */
+    public void setSubjectConstraints(List<String> subjectConstraints) {
+        certConstraints.setSubjectConstraints(subjectConstraints);
+    }
+    
+    /**
+     * Set the WSS4J Validator instance to use to validate the token.
+     * @param validator the WSS4J Validator instance to use to validate the token
+     */
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
+    
+    /**
+     * Return true if this TokenValidator implementation is capable of validating the
+     * ReceivedToken argument.
+     */
+    public boolean canHandleToken(ReceivedToken validateTarget) {
+        return canHandleToken(validateTarget, null);
+    }
+    
+    /**
+     * Return true if this TokenValidator implementation is capable of validating the
+     * ReceivedToken argument. The realm is ignored in this token Validator.
+     */
+    public boolean canHandleToken(ReceivedToken validateTarget, String realm) {
+        Object token = validateTarget.getToken();
+        if ((token instanceof BinarySecurityTokenType)
+            && X509_V3_TYPE.equals(((BinarySecurityTokenType)token).getValueType())) {
+            return true;
+        } else if (token instanceof Element
+            && WSConstants.SIG_NS.equals(((Element)token).getNamespaceURI())
+            && WSConstants.X509_DATA_LN.equals(((Element)token).getLocalName())) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Validate a Token using the given TokenValidatorParameters.
+     */
+    public TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) {
+        LOG.fine("Validating X.509 Token");
+        STSPropertiesMBean stsProperties = tokenParameters.getStsProperties();
+        Crypto sigCrypto = stsProperties.getSignatureCrypto();
+        CallbackHandler callbackHandler = stsProperties.getCallbackHandler();
+
+        RequestData requestData = new RequestData();
+        requestData.setSigVerCrypto(sigCrypto);
+        requestData.setWssConfig(WSSConfig.getNewInstance());
+        requestData.setCallbackHandler(callbackHandler);
+        requestData.setMsgContext(tokenParameters.getWebServiceContext().getMessageContext());
+        requestData.setSubjectCertConstraints(certConstraints.getCompiledSubjectContraints());
+
+        TokenValidatorResponse response = new TokenValidatorResponse();
+        ReceivedToken validateTarget = tokenParameters.getToken();
+        validateTarget.setState(STATE.INVALID);
+        response.setToken(validateTarget);
+        
+        BinarySecurity binarySecurity = null;
+        if (validateTarget.isBinarySecurityToken()) {
+            BinarySecurityTokenType binarySecurityType = (BinarySecurityTokenType)validateTarget.getToken();
+    
+            // Test the encoding type
+            String encodingType = binarySecurityType.getEncodingType();
+            if (!BASE64_ENCODING.equals(encodingType)) {
+                LOG.fine("Bad encoding type attribute specified: " + encodingType);
+                return response;
+            }
+            
+            //
+            // Turn the received JAXB object into a DOM element
+            //
+            Document doc = DOMUtils.createDocument();
+            binarySecurity = new X509Security(doc);
+            binarySecurity.setEncodingType(encodingType);
+            binarySecurity.setValueType(binarySecurityType.getValueType());
+            String data = binarySecurityType.getValue();
+            ((Text)binarySecurity.getElement().getFirstChild()).setData(data);
+        } else if (validateTarget.isDOMElement()) {
+            try {
+                Document doc = DOMUtils.createDocument();
+                binarySecurity = new X509Security(doc);
+                binarySecurity.setEncodingType(BASE64_ENCODING);
+                X509Data x509Data = new X509Data((Element)validateTarget.getToken(), "");
+                if (x509Data.containsCertificate()) {
+                    X509Certificate cert = x509Data.itemCertificate(0).getX509Certificate();
+                    ((X509Security)binarySecurity).setX509Certificate(cert);
+                }
+            } catch (WSSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+                return response;
+            } catch (XMLSecurityException ex) {
+                LOG.log(Level.WARNING, "", ex);
+                return response;
+            }
+        } else {
+            return response;
+        }
+
+        //
+        // Validate the token
+        //
+        try {
+            Credential credential = new Credential();
+            credential.setBinarySecurityToken(binarySecurity);
+            if (sigCrypto != null) {
+                X509Certificate cert = ((X509Security)binarySecurity).getX509Certificate(sigCrypto);
+                credential.setCertificates(new X509Certificate[]{cert});
+            }
+
+            Credential returnedCredential = validator.validate(credential, requestData);
+            Principal principal = returnedCredential.getPrincipal();
+            if (principal == null) {
+                principal = returnedCredential.getCertificates()[0].getSubjectX500Principal();
+            }
+            response.setPrincipal(principal);
+            validateTarget.setState(STATE.VALID);
+            LOG.fine("X.509 Token successfully validated");
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.WARNING, "", ex);
+        }
+        return response;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/9d8f98ac/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
----------------------------------------------------------------------
diff --git a/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml b/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
index d5dd55e..48df6bd 100644
--- a/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
+++ b/services/sts/src/main/webapp/WEB-INF/cxf-transport.xml
@@ -108,7 +108,7 @@
 
     <util:list id="transportTokenValidators">
         <ref bean="transportSamlTokenValidator" />
-        <bean class="org.apache.cxf.sts.token.validator.X509TokenValidator" />
+        <bean class="org.apache.cxf.fediz.service.sts.X509TokenValidator" />
     </util:list>
 
     <bean id="realmA" class="org.apache.cxf.sts.token.realm.SAMLRealm">
@@ -129,11 +129,14 @@
         <entry key="REALMA" value-ref="realmA" />
         <entry key="REALMB" value-ref="realmB" />
     </util:map>
+    
+    <bean id="subjectProvider" class="org.apache.cxf.fediz.service.sts.DefaultSubjectProvider"/>
 
     <bean id="transportSamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
         <property name="attributeStatementProviders" ref="attributeStatementProvidersList" />
         <property name="realmMap" ref="realms" />
         <property name="conditionsProvider" ref="conditionsProvider" />
+        <property name="subjectProvider" ref="subjectProvider" />
     </bean>
 
     <bean id="conditionsProvider"