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"/>