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 2017/01/24 12:39:01 UTC

[3/3] cxf git commit: Updating STS test

Updating STS test


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

Branch: refs/heads/master
Commit: 306b878d297a8cf05073248c2cb22581f19713ce
Parents: 4a021b7
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Jan 24 10:59:28 2017 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Jan 24 10:59:28 2017 +0000

----------------------------------------------------------------------
 .../systest/sts/custom/CustomParameterTest.java |  24 ++-
 .../systest/sts/custom/CustomUTValidator.java   | 194 ++-----------------
 .../cxf/systest/sts/custom/cxf-client.xml       |  16 --
 .../systest/sts/deployment/cxf-sts-common.xml   |   1 +
 4 files changed, 43 insertions(+), 192 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/306b878d/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomParameterTest.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomParameterTest.java b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomParameterTest.java
index de8a900..3ddae05 100644
--- a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomParameterTest.java
+++ b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomParameterTest.java
@@ -19,6 +19,8 @@
 package org.apache.cxf.systest.sts.custom;
 
 import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.xml.namespace.QName;
 import javax.xml.ws.BindingProvider;
@@ -26,9 +28,11 @@ import javax.xml.ws.Service;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.rt.security.SecurityConstants;
 import org.apache.cxf.systest.sts.common.SecurityTestUtil;
 import org.apache.cxf.systest.sts.common.TokenTestUtils;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.ws.security.trust.STSClient;
 import org.example.contract.doubleit.DoubleItPortType;
 import org.junit.BeforeClass;
 
@@ -69,7 +73,8 @@ public class CustomParameterTest extends AbstractBusClientServerTestBase {
     }
 
     @org.junit.Test
-    public void testCustomParameter() throws Exception {
+    @org.junit.Ignore
+    public void testCustomParameterInRST() throws Exception {
 
         SpringBusFactory bf = new SpringBusFactory();
         URL busFile = CustomParameterTest.class.getResource("cxf-client.xml");
@@ -87,6 +92,23 @@ public class CustomParameterTest extends AbstractBusClientServerTestBase {
         
         TokenTestUtils.updateSTSPort((BindingProvider)transportClaimsPort, STSPORT);
         
+        STSClient stsClient = new STSClient(bus);
+        stsClient.setWsdlLocation("https://localhost:" + STSPORT + "/SecurityTokenService/UT?wsdl");
+        stsClient.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService");
+        stsClient.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}UT_Port");
+        // Add custom content to the RST
+        stsClient.setCustomContent("<realm xmlns=\"http://cxf.apache.org/custom\">custom-realm</realm>");
+        
+        Map<String, Object> properties = new HashMap<>();
+        properties.put("security.username", "alice");
+        properties.put("security.callback-handler", "org.apache.cxf.systest.sts.common.CommonCallbackHandler");
+        properties.put("security.sts.token.username", "myclientkey");
+        properties.put("security.sts.token.properties", "clientKeystore.properties");
+        properties.put("security.sts.token.usecert", "true");
+        stsClient.setProperties(properties);
+        
+        ((BindingProvider)transportClaimsPort).getRequestContext().put(SecurityConstants.STS_CLIENT, stsClient);
+        
         doubleIt(transportClaimsPort, 25);
         
         ((java.io.Closeable)transportClaimsPort).close();

http://git-wip-us.apache.org/repos/asf/cxf/blob/306b878d/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomUTValidator.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomUTValidator.java b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomUTValidator.java
index 2e441d5..1e5f2de 100644
--- a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomUTValidator.java
+++ b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/custom/CustomUTValidator.java
@@ -19,198 +19,42 @@
 
 package org.apache.cxf.systest.sts.custom;
 
-import java.io.IOException;
-import java.util.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.apache.wss4j.common.ext.WSPasswordCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
-import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.token.UsernameToken;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.wss4j.dom.validate.Credential;
+import org.apache.wss4j.dom.validate.UsernameTokenValidator;
 import org.apache.wss4j.dom.validate.Validator;
 
 /**
- * This class validates a processed UsernameToken, extracted from the Credential passed to
- * the validate method.
+ * A Validator that checks for a custom "realm" parameter in the RST request and only allows 
+ * authentication if the value is equal to "custom-realm".
  */
 public class CustomUTValidator implements Validator {
 
-    private static final org.slf4j.Logger LOG =
-        org.slf4j.LoggerFactory.getLogger(CustomUTValidator.class);
-
-    /**
-     * Validate the credential argument. It must contain a non-null UsernameToken. A
-     * CallbackHandler implementation is also required to be set.
-     *
-     * If the password type is either digest or plaintext, it extracts a password from the
-     * CallbackHandler and then compares the passwords appropriately.
-     *
-     * If the password is null it queries a hook to allow the user to validate UsernameTokens
-     * of this type.
-     *
-     * @param credential the Credential to be validated
-     * @param data the RequestData associated with the request
-     * @throws WSSecurityException on a failed validation
-     */
     public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
         if (credential == null || credential.getUsernametoken() == null) {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCredential");
         }
+        
+        // Find custom Element in the SOAP Body
+        Document doc = credential.getUsernametoken().getElement().getOwnerDocument();
+        Element soapBody = WSSecurityUtil.findBodyElement(doc);
+        Element realm = XMLUtils.findElement(soapBody, "realm", "http://cxf.apache.org/custom");
+        if (realm != null) {
+            String realmStr = realm.getTextContent();
+            if ("custom-realm".equals(realmStr)) {
 
-        boolean handleCustomPasswordTypes = data.isHandleCustomPasswordTypes();
-        boolean passwordsAreEncoded = data.isEncodePasswords();
-        String requiredPasswordType = data.getRequiredPasswordType();
-
-        UsernameToken usernameToken = credential.getUsernametoken();
-        usernameToken.setPasswordsAreEncoded(passwordsAreEncoded);
-
-        String pwType = usernameToken.getPasswordType();
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("UsernameToken user " + usernameToken.getName());
-            LOG.debug("UsernameToken password type " + pwType);
-        }
-
-        if (requiredPasswordType != null && !requiredPasswordType.equals(pwType)) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Authentication failed as the received password type does not "
-                    + "match the required password type of: " + requiredPasswordType);
-            }
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
-        }
-
-        //
-        // If the UsernameToken is hashed or plaintext, then retrieve the password from the
-        // callback handler and compare directly. If the UsernameToken is of some unknown type,
-        // then delegate authentication to the callback handler
-        //
-        String password = usernameToken.getPassword();
-        if (usernameToken.isHashed()) {
-            verifyDigestPassword(usernameToken, data);
-        } else if (WSConstants.PASSWORD_TEXT.equals(pwType)
-            || password != null && (pwType == null || "".equals(pwType.trim()))) {
-            verifyPlaintextPassword(usernameToken, data);
-        } else if (password != null) {
-            if (!handleCustomPasswordTypes) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Authentication failed as handleCustomUsernameTokenTypes is false");
-                }
-                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
-            }
-            verifyCustomPassword(usernameToken, data);
-        } else {
-            verifyUnknownPassword(usernameToken, data);
-        }
-        return credential;
-    }
-
-    /**
-     * Verify a UsernameToken containing a password of some unknown (but specified) password
-     * type. It does this by querying a CallbackHandler instance to obtain a password for the
-     * given username, and then comparing it against the received password.
-     * This method currently uses the same LOG.c as the verifyPlaintextPassword case, but it in
-     * a separate protected method to allow users to override the validation of the custom
-     * password type specific case.
-     * @param usernameToken The UsernameToken instance to verify
-     * @throws WSSecurityException on a failed authentication.
-     */
-    protected void verifyCustomPassword(UsernameToken usernameToken,
-                                        RequestData data) throws WSSecurityException {
-        verifyPlaintextPassword(usernameToken, data);
-    }
-
-    /**
-     * Verify a UsernameToken containing a plaintext password. It does this by querying a
-     * CallbackHandler instance to obtain a password for the given username, and then comparing
-     * it against the received password.
-     * This method currently uses the same LOG.c as the verifyDigestPassword case, but it in
-     * a separate protected method to allow users to override the validation of the plaintext
-     * password specific case.
-     * @param usernameToken The UsernameToken instance to verify
-     * @throws WSSecurityException on a failed authentication.
-     */
-    protected void verifyPlaintextPassword(UsernameToken usernameToken,
-                                           RequestData data) throws WSSecurityException {
-        verifyDigestPassword(usernameToken, data);
-    }
-
-    /**
-     * Verify a UsernameToken containing a password digest. It does this by querying a
-     * CallbackHandler instance to obtain a password for the given username, and then comparing
-     * it against the received password.
-     * @param usernameToken The UsernameToken instance to verify
-     * @throws WSSecurityException on a failed authentication.
-     */
-    protected void verifyDigestPassword(UsernameToken usernameToken,
-                                        RequestData data) throws WSSecurityException {
-        if (data.getCallbackHandler() == null) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCallback");
-        }
-
-        String user = usernameToken.getName();
-        String password = usernameToken.getPassword();
-        String nonce = usernameToken.getNonce();
-        String createdTime = usernameToken.getCreated();
-        String pwType = usernameToken.getPasswordType();
-        boolean passwordsAreEncoded = usernameToken.getPasswordsAreEncoded();
-
-        WSPasswordCallback pwCb =
-            new WSPasswordCallback(user, null, pwType, WSPasswordCallback.USERNAME_TOKEN);
-        try {
-            data.getCallbackHandler().handle(new Callback[]{pwCb});
-        } catch (IOException | UnsupportedCallbackException e) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug(e.getMessage(), e);
-            }
-            throw new WSSecurityException(
-                WSSecurityException.ErrorCode.FAILED_AUTHENTICATION, e
-            );
-        }
-        String origPassword = pwCb.getPassword();
-        if (origPassword == null) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Callback supplied no password for: " + user);
-            }
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
-        }
-        if (usernameToken.isHashed()) {
-            String passDigest;
-            if (passwordsAreEncoded) {
-                passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, 
-                                                            Base64.getMimeDecoder().decode(origPassword));
-            } else {
-                passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
-            }
-            if (!passDigest.equals(password)) {
-                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
-            }
-        } else {
-            if (!origPassword.equals(password)) {
-                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
-            }
-        }
-    }
-
-    /**
-     * Verify a UsernameToken containing no password. An exception is thrown unless the user
-     * has explicitly allowed this use-case via WSHandlerConstants.ALLOW_USERNAMETOKEN_NOPASSWORD
-     * @param usernameToken The UsernameToken instance to verify
-     * @throws WSSecurityException on a failed authentication.
-     */
-    protected void verifyUnknownPassword(UsernameToken usernameToken,
-                                         RequestData data) throws WSSecurityException {
-
-        boolean allowUsernameTokenDerivedKeys = data.isAllowUsernameTokenNoPassword();
-        if (!allowUsernameTokenDerivedKeys) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Authentication failed as the received UsernameToken does not "
-                    + "contain any password element");
+                UsernameTokenValidator validator = new UsernameTokenValidator();
+                return validator.validate(credential, data);
             }
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
+        
+        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCredential");
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/306b878d/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/custom/cxf-client.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/custom/cxf-client.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/custom/cxf-client.xml
index de5079b..003083f 100644
--- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/custom/cxf-client.xml
+++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/custom/cxf-client.xml
@@ -24,24 +24,8 @@
             <cxf:logging/>
         </cxf:features>
     </cxf:bus>
-    <bean id="stsClient" class="org.apache.cxf.ws.security.trust.STSClient">
-        <constructor-arg ref="cxf"/>
-        <property name="wsdlLocation" value="https://localhost:${testutil.ports.STSServer}/SecurityTokenService/UT?wsdl"/>
-        <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/>
-        <property name="endpointName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}UT_Port"/>
-        <property name="properties">
-            <map>
-                <entry key="security.username" value="alice"/>
-                <entry key="security.callback-handler" value="org.apache.cxf.systest.sts.common.CommonCallbackHandler"/>
-                <entry key="security.sts.token.username" value="myclientkey"/>
-                <entry key="security.sts.token.properties" value="clientKeystore.properties"/>
-                <entry key="security.sts.token.usecert" value="true"/>
-            </map>
-        </property>
-    </bean>
     <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItTransportCustomParameterPort" createdFromAPI="true">
         <jaxws:properties>
-            <entry key="security.sts.client" value-ref="stsClient"/>
         </jaxws:properties>
     </jaxws:client>
     <http:conduit name="https://localhost:.*">

http://git-wip-us.apache.org/repos/asf/cxf/blob/306b878d/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts-common.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts-common.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts-common.xml
index e426c7b..8876b6c 100644
--- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts-common.xml
+++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts-common.xml
@@ -41,6 +41,7 @@
         <property name="tokenStore" ref="defaultTokenStore"/>
         <property name="delegationHandlers" ref="utDelegationHandler"/>
         <property name="tokenValidators" ref="transportTokenValidators"/>
+        <property name="allowCustomContent" value="true" />
     </bean>
     <bean id="transportValidateDelegate" class="org.apache.cxf.sts.operation.TokenValidateOperation">
         <property name="tokenProviders" ref="transportTokenProviders"/>