cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1173661 - in /cxf/trunk/services/sts/sts-core/src: main/java/org/apache/cxf/sts/token/validator/ test/java/org/apache/cxf/sts/token/validator/
Date Wed, 21 Sep 2011 14:16:41 GMT
Author: coheigea
Date: Wed Sep 21 14:16:40 2011
New Revision: 1173661

URL: http://svn.apache.org/viewvc?rev=1173661&view=rev
Log:
Defer token validation to the WSS4J Validator interface + make it pluggable

Modified:
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java
    cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/X509TokenValidatorTest.java

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java?rev=1173661&r1=1173660&r2=1173661&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java
(original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/SAMLTokenValidator.java
Wed Sep 21 14:16:40 2011
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.cxf.sts.token.validator;
 
 import java.util.logging.Level;
@@ -42,6 +41,7 @@ import org.apache.ws.security.saml.SAMLK
 import org.apache.ws.security.saml.ext.AssertionWrapper;
 import org.apache.ws.security.validate.Credential;
 import org.apache.ws.security.validate.SignatureTrustValidator;
+import org.apache.ws.security.validate.Validator;
 
 /**
  * Validate a SAML Assertion. It is valid if it was issued and signed by this STS.
@@ -50,6 +50,16 @@ public class SAMLTokenValidator implemen
     
     private static final Logger LOG = LogUtils.getL7dLogger(SAMLTokenValidator.class);
     
+    private Validator validator = new SignatureTrustValidator();
+    
+    /**
+     * 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.
@@ -89,39 +99,40 @@ public class SAMLTokenValidator implemen
         TokenValidatorResponse response = new TokenValidatorResponse();
         response.setValid(false);
         
-        if (validateTarget != null && validateTarget.isDOMElement()) {
-            try {
-                Element validateTargetElement = (Element)validateTarget.getToken();
-                AssertionWrapper assertion = new AssertionWrapper(validateTargetElement);
-                if (!assertion.isSigned()) {
-                    LOG.log(Level.WARNING, "The received assertion is not signed, and therefore
not trusted");
-                    return response;
-                }
-                // Verify the signature
-                assertion.verifySignature(
-                        requestData, new WSDocInfo(validateTargetElement.getOwnerDocument())
-                );
-                
-                // Now verify trust on the signature
-                Credential trustCredential = new Credential();
-                SAMLKeyInfo samlKeyInfo = assertion.getSignatureKeyInfo();
-                trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
-                trustCredential.setCertificates(samlKeyInfo.getCerts());
-                
-                SignatureTrustValidator trustValidator = new SignatureTrustValidator();
-                trustValidator.validate(trustCredential, requestData);
-                
-                // Finally check the issuer
-                String assertionIssuer = assertion.getIssuerString();
-                
-                if (issuer.equals(assertionIssuer)) {
-                    response.setValid(true);
-                    SAMLTokenPrincipal samlPrincipal = new SAMLTokenPrincipal(assertion);
-                    response.setPrincipal(samlPrincipal);
-                }
-            } catch (WSSecurityException ex) {
-                LOG.log(Level.WARNING, "", ex);
+        if (validateTarget == null || !validateTarget.isDOMElement()) {
+            return response;
+        }
+        
+        try {
+            Element validateTargetElement = (Element)validateTarget.getToken();
+            AssertionWrapper assertion = new AssertionWrapper(validateTargetElement);
+            if (!assertion.isSigned()) {
+                LOG.log(Level.WARNING, "The received assertion is not signed, and therefore
not trusted");
+                return response;
+            }
+            // Verify the signature
+            assertion.verifySignature(
+                requestData, new WSDocInfo(validateTargetElement.getOwnerDocument())
+            );
+
+            // Now verify trust on the signature
+            Credential trustCredential = new Credential();
+            SAMLKeyInfo samlKeyInfo = assertion.getSignatureKeyInfo();
+            trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
+            trustCredential.setCertificates(samlKeyInfo.getCerts());
+
+            validator.validate(trustCredential, requestData);
+
+            // Finally check the issuer
+            String assertionIssuer = assertion.getIssuerString();
+
+            if (issuer.equals(assertionIssuer)) {
+                response.setValid(true);
+                SAMLTokenPrincipal samlPrincipal = new SAMLTokenPrincipal(assertion);
+                response.setPrincipal(samlPrincipal);
             }
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.WARNING, "", ex);
         }
 
         return response;

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java?rev=1173661&r1=1173660&r2=1173661&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java
(original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java
Wed Sep 21 14:16:40 2011
@@ -16,40 +16,39 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.cxf.sts.token.validator;
 
-import java.io.IOException;
 import java.security.Principal;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.sts.QNameConstants;
 import org.apache.cxf.sts.STSPropertiesMBean;
 import org.apache.cxf.sts.request.ReceivedToken;
 import org.apache.cxf.sts.request.TokenRequirements;
 
-import org.apache.cxf.ws.security.sts.provider.model.secext.EncodedString;
-import org.apache.cxf.ws.security.sts.provider.model.secext.PasswordString;
 import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
 
 import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.WSUsernameTokenPrincipal;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.handler.RequestData;
-import org.apache.ws.security.message.token.BinarySecurity;
 import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.validate.Credential;
+import org.apache.ws.security.validate.Validator;
 
 /**
  * This class validates a wsse UsernameToken.
@@ -58,6 +57,16 @@ public class UsernameTokenValidator impl
     
     private static final Logger LOG = LogUtils.getL7dLogger(UsernameTokenValidator.class);
     
+    private Validator validator = new org.apache.ws.security.validate.UsernameTokenValidator();
+    
+    /**
+     * 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.
@@ -89,109 +98,60 @@ public class UsernameTokenValidator impl
         TokenValidatorResponse response = new TokenValidatorResponse();
         response.setValid(false);
         
-        if (validateTarget != null && validateTarget.isUsernameToken()) {
-            //
-            // Parse the JAXB object
-            //
-            String passwordType = null;
-            String passwordValue = null;
-            String nonce = null;
-            String created = null;
-            UsernameTokenType usernameTokenType = (UsernameTokenType)validateTarget.getToken();
-            for (Object any : usernameTokenType.getAny()) {
-                if (any instanceof JAXBElement<?>) {
-                    JAXBElement<?> anyElement = (JAXBElement<?>) any;
-                    if (QNameConstants.PASSWORD.equals(anyElement.getName())) {
-                        PasswordString passwordString = 
-                            (PasswordString)anyElement.getValue();
-                        passwordType = passwordString.getType();
-                        passwordValue = passwordString.getValue();
-                    } else if (QNameConstants.NONCE.equals(anyElement.getName())) {
-                        EncodedString nonceES = (EncodedString)anyElement.getValue();
-                        nonce = nonceES.getValue();
-                        // Encoding Type must be equal to Base64Binary
-                        if (!BinarySecurity.BASE64_ENCODING.equals(nonceES.getEncodingType()))
{
-                            String errorMsg = "The UsernameToken nonce element has a bad
encoding type";
-                            LOG.log(Level.WARNING, errorMsg + " : " + nonceES.getEncodingType());
-                            return response;
-                        }
-                    }
-                } else if (any instanceof Element) {
-                    Element element = (Element)any;
-                    if (WSConstants.WSU_NS.equals(element.getNamespaceURI()) 
-                        && WSConstants.CREATED_LN.equals(element.getLocalName()))
{
-                        created = element.getTextContent();
-                    }
-                }
-            }
-            
-            //
-            // Validate the token
-            //
-            try {
-                boolean valid = 
-                    verifyPassword(
-                        usernameTokenType.getUsername().getValue(), passwordValue, passwordType,

-                        nonce, created, requestData
-                    );
-                response.setValid(valid);
-                if (valid) {
-                    Principal principal = 
-                        createPrincipal(
-                            usernameTokenType.getUsername().getValue(), passwordValue, passwordType,

-                            nonce, created
-                        );
-                    response.setPrincipal(principal);
-                }
-            } catch (WSSecurityException ex) {
-                LOG.log(Level.WARNING, "", ex);
-            }
+        if (validateTarget == null || !validateTarget.isUsernameToken()) {
+            return response;
         }
-            
-        return response;
-    }
-    
-    private boolean verifyPassword(
-        String username,
-        String passwordValue,
-        String passwordType,
-        String nonce,
-        String createdTime,
-        RequestData requestData
-    ) throws WSSecurityException {
-        WSPasswordCallback pwCb = 
-            new WSPasswordCallback(
-                username, null, passwordType, WSPasswordCallback.USERNAME_TOKEN, requestData
-            );
+        
+        //
+        // Turn the JAXB UsernameTokenType into a DOM Element for validation
+        //
+        UsernameTokenType usernameTokenType = (UsernameTokenType)validateTarget.getToken();
+        Element rootElement = null;
         try {
-            requestData.getCallbackHandler().handle(new Callback[]{pwCb});
-        } catch (IOException e) {
-            LOG.log(Level.WARNING, "", e);
-            throw new WSSecurityException(
-                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-            );
-        } catch (UnsupportedCallbackException e) {
-            LOG.log(Level.WARNING, "", e);
-            throw new WSSecurityException(
-                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-            );
+            JAXBContext jaxbContext = 
+                JAXBContext.newInstance("org.apache.cxf.ws.security.sts.provider.model");
+            Marshaller marshaller = jaxbContext.createMarshaller();
+            Document doc = DOMUtils.createDocument();
+            rootElement = doc.createElement("root-element");
+            JAXBElement<UsernameTokenType> tokenType = 
+                new JAXBElement<UsernameTokenType>(
+                    QNameConstants.USERNAME_TOKEN, UsernameTokenType.class, usernameTokenType
+                );
+            marshaller.marshal(tokenType, rootElement);
+        } catch (JAXBException ex) {
+            LOG.log(Level.WARNING, "", ex);
+            return response;
         }
-        String origPassword = pwCb.getPassword();
-        if (origPassword == null) {
-            LOG.fine("Callback supplied no password for: " + username);
-            return false;
-        }
-        if (WSConstants.PASSWORD_DIGEST.equals(passwordType)) {
-            String passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
-            if (!passDigest.equals(passwordValue)) {
-                return false;
-            }
-        } else {
-            if (!origPassword.equals(passwordValue)) {
-                return false;
+        
+        //
+        // Validate the token
+        //
+        try {
+            boolean allowNamespaceQualifiedPasswordTypes = 
+                wssConfig.getAllowNamespaceQualifiedPasswordTypes();
+            boolean bspCompliant = wssConfig.isWsiBSPCompliant();
+            Element usernameTokenElement = (Element)rootElement.getFirstChild();
+            
+            UsernameToken ut = 
+                new UsernameToken(usernameTokenElement, allowNamespaceQualifiedPasswordTypes,
bspCompliant);
+            if (ut.getPassword() == null) {
+                return response;
             }
+            Credential credential = new Credential();
+            credential.setUsernametoken(ut);
+            validator.validate(credential, requestData);
+            
+            Principal principal = 
+                createPrincipal(
+                    ut.getName(), ut.getPassword(), ut.getPasswordType(), ut.getNonce(),
ut.getCreated()
+                );
+            response.setPrincipal(principal);
+            response.setValid(true);
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.WARNING, "", ex);
         }
-        return true;
+        
+        return response;
     }
     
     /**

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java?rev=1173661&r1=1173660&r2=1173661&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java
(original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/X509TokenValidator.java
Wed Sep 21 14:16:40 2011
@@ -36,16 +36,12 @@ import org.apache.cxf.sts.request.TokenR
 import org.apache.cxf.ws.security.sts.provider.model.secext.BinarySecurityTokenType;
 
 import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSDocInfo;
 import org.apache.ws.security.WSSConfig;
-import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.handler.RequestData;
 import org.apache.ws.security.message.token.BinarySecurity;
 import org.apache.ws.security.message.token.X509Security;
-import org.apache.ws.security.processor.BinarySecurityTokenProcessor;
-import org.apache.ws.security.processor.Processor;
 import org.apache.ws.security.validate.Credential;
 import org.apache.ws.security.validate.SignatureTrustValidator;
 import org.apache.ws.security.validate.Validator;
@@ -58,9 +54,21 @@ public class X509TokenValidator implemen
     
     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();
 
     /**
+     * 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.
      */
@@ -87,55 +95,53 @@ public class X509TokenValidator implemen
 
         RequestData requestData = new RequestData();
         requestData.setSigCrypto(sigCrypto);
-        WSSConfig wssConfig = WSSConfig.getNewInstance();
-        wssConfig.setValidator(WSSecurityEngine.BINARY_TOKEN, BSTValidator.class);
-        requestData.setWssConfig(wssConfig);
+        requestData.setWssConfig(WSSConfig.getNewInstance());
         requestData.setCallbackHandler(callbackHandler);
 
         TokenValidatorResponse response = new TokenValidatorResponse();
         response.setValid(false);
         
-        if (validateTarget != null && validateTarget.isBinarySecurityToken()) {
-            BinarySecurityTokenType binarySecurityType = 
-                (BinarySecurityTokenType)validateTarget.getToken();
-            //
-            // Turn the received JAXB object into a DOM element
-            //
-            Document doc = DOMUtils.createDocument();
-            BinarySecurity binarySecurity = new X509Security(doc);
-            binarySecurity.setEncodingType(binarySecurityType.getEncodingType());
-            String data = binarySecurityType.getValue();
-            ((Text)binarySecurity.getElement().getFirstChild()).setData(data);
-            
-            //
-            // Process and Validate the token
-            //
-            Processor processor = new BinarySecurityTokenProcessor();
-            try {
-                processor.handleToken(
-                    binarySecurity.getElement(), requestData, new WSDocInfo(doc)
-                );
-                X509Certificate cert = ((X509Security) binarySecurity).getX509Certificate(sigCrypto);
-                response.setPrincipal(cert.getSubjectX500Principal());
-                response.setValid(true);
-            } catch (WSSecurityException ex) {
-                LOG.log(Level.WARNING, "", ex);
-            }
+        if (validateTarget == null || !validateTarget.isBinarySecurityToken()) {
+            return response;
         }
-        return response;
-    }
-    
-    /**
-     * A Custom Validator for a BinarySecurityToken - it just sends the BinarySecurityToken
-     * to the SignatureTrustValidator for validation.
-     */
-    public static class BSTValidator implements Validator {
 
-        public Credential validate(Credential credential, RequestData data) throws WSSecurityException
{
-            Validator delegate = new SignatureTrustValidator();
-            return delegate.validate(credential, data);
+        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 binarySecurity = new X509Security(doc);
+        binarySecurity.setEncodingType(encodingType);
+        binarySecurity.setValueType(binarySecurityType.getValueType());
+        String data = binarySecurityType.getValue();
+        ((Text)binarySecurity.getElement().getFirstChild()).setData(data);
+
+        //
+        // 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);
+            response.setPrincipal(returnedCredential.getCertificates()[0].getSubjectX500Principal());
+            response.setValid(true);
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.WARNING, "", ex);
+        }
+        return response;
     }
     
 }

Modified: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/X509TokenValidatorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/X509TokenValidatorTest.java?rev=1173661&r1=1173660&r2=1173661&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/X509TokenValidatorTest.java
(original)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/X509TokenValidatorTest.java
Wed Sep 21 14:16:40 2011
@@ -82,13 +82,9 @@ public class X509TokenValidatorTest exte
         
         // This will fail as the encoding type is not set
         TokenValidatorResponse validatorResponse = null;
-        try {
-            validatorResponse = x509TokenValidator.validateToken(validatorParameters);
-            assertTrue(validatorResponse != null);
-            assertFalse(validatorResponse.isValid());
-        } catch (RuntimeException ex) {
-            // needed due to a bug in WSS4J 1.6.2
-        }
+        validatorResponse = x509TokenValidator.validateToken(validatorParameters);
+        assertTrue(validatorResponse != null);
+        assertFalse(validatorResponse.isValid());
         
         binarySecurityToken.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary");
         



Mime
View raw message