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 2011/02/04 18:28:38 UTC
svn commit: r1067230 - in /cxf/branches/wss4j-1.6-port/rt/ws/security/src:
main/java/org/apache/cxf/ws/security/
main/java/org/apache/cxf/ws/security/wss4j/
test/java/org/apache/cxf/ws/security/wss4j/
Author: coheigea
Date: Fri Feb 4 17:28:38 2011
New Revision: 1067230
URL: http://svn.apache.org/viewvc?rev=1067230&view=rev
Log:
Some changes to UsernameToken processing following on the recent addition of Validators to WSS4J.
- Removed the custom Processor implementations as it is no longer necessary to swap in new processors to handle custom behaviour.
Removed:
cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
Modified:
cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
cxf/branches/wss4j-1.6-port/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/CustomProcessor.java
Modified: cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1067230&r1=1067229&r2=1067230&view=diff
==============================================================================
--- cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java (original)
+++ cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java Fri Feb 4 17:28:38 2011
@@ -32,6 +32,7 @@ public final class SecurityConstants {
public static final String PASSWORD = "ws-security.password";
public static final String VALIDATE_PASSWORD = "ws-security.validate.password";
public static final String USERNAME_TOKEN_NO_CALLBACKS = "ws-security.ut.no-callbacks";
+ public static final String USERNAME_TOKEN_VALIDATOR = "ws-security.ut.validator";
public static final String CALLBACK_HANDLER = "ws-security.callback-handler";
Modified: cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java?rev=1067230&r1=1067229&r2=1067230&view=diff
==============================================================================
--- cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java (original)
+++ cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java Fri Feb 4 17:28:38 2011
@@ -18,15 +18,12 @@
*/
package org.apache.cxf.ws.security.wss4j;
-import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
@@ -38,13 +35,10 @@ import org.apache.cxf.interceptor.securi
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.security.SecurityContext;
-import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityException;
-import org.apache.ws.security.WSUsernameTokenPrincipal;
-import org.apache.ws.security.handler.RequestData;
-import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.validate.UsernameTokenValidator;
+import org.apache.ws.security.validate.Validator;
/**
@@ -174,83 +168,61 @@ public abstract class AbstractUsernameTo
String nonce,
String created) throws SecurityException;
-
- /**
- * {@inheritDoc}
- *
- */
- @Override
- protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utNoCallbacks)
- throws WSSecurityException {
-
- // Given that a custom UT processor is used for dealing with digests
- // no callback handler is required when the request UT contains a digest;
- // however a custom callback may still be needed for decrypting the encrypted UT
-
- if ((doAction & WSConstants.UT) != 0) {
- CallbackHandler pwdCallback = null;
- try {
- pwdCallback = super.getCallback(reqData, doAction, false);
- } catch (Exception ex) {
- // ignore
- }
- return new SubjectCreatingCallbackHandler(pwdCallback);
- }
-
- return super.getCallback(reqData, doAction, false);
- }
-
@Override
protected WSSecurityEngine getSecurityEngine(boolean utNoCallbacks) {
- if (!supportDigestPasswords) {
- return super.getSecurityEngine(true);
- }
- Map<QName, Object> profiles = new HashMap<QName, Object>(3);
+ Map<QName, Object> profiles = new HashMap<QName, Object>(1);
- Processor processor = new CustomUsernameTokenProcessor();
- profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
- profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+ Validator validator = new CustomValidator();
+ profiles.put(WSSecurityEngine.USERNAME_TOKEN, validator);
return createSecurityEngine(profiles);
}
- protected class SubjectCreatingCallbackHandler extends DelegatingCallbackHandler {
-
- public SubjectCreatingCallbackHandler(CallbackHandler pwdHandler) {
- super(pwdHandler);
+ protected class CustomValidator extends UsernameTokenValidator {
+
+ @Override
+ protected void verifyCustomPassword(
+ org.apache.ws.security.message.token.UsernameToken usernameToken
+ ) throws WSSecurityException {
+ AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
+ usernameToken.getName(), usernameToken.getPassword(), false, null, null
+ );
+ }
+
+ @Override
+ protected void verifyPlaintextPassword(
+ org.apache.ws.security.message.token.UsernameToken usernameToken
+ ) throws WSSecurityException {
+ AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
+ usernameToken.getName(), usernameToken.getPassword(), false, null, null
+ );
}
@Override
- protected void handleCallback(Callback c) throws IOException {
- if (c instanceof WSPasswordCallback) {
- WSPasswordCallback pc = (WSPasswordCallback)c;
- if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType())
- && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
- AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
- pc.getIdentifier(), pc.getPassword(), false, null, null);
- }
+ protected void verifyDigestPassword(
+ org.apache.ws.security.message.token.UsernameToken usernameToken
+ ) throws WSSecurityException {
+ if (!supportDigestPasswords) {
+ throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
}
+ String user = usernameToken.getName();
+ String password = usernameToken.getPassword();
+ boolean isHashed = usernameToken.isDerivedKey();
+ String nonce = usernameToken.getNonce();
+ String createdTime = usernameToken.getCreated();
+ AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
+ user, password, isHashed, nonce, createdTime
+ );
}
- }
-
- /**
- * Custom UsernameTokenProcessor
- * Unfortunately, WSS4J UsernameTokenProcessor makes it impossible to
- * override its handleUsernameToken only.
- *
- */
- protected class CustomUsernameTokenProcessor extends UsernameTokenProcessorWithoutCallbacks {
@Override
- protected WSUsernameTokenPrincipal createPrincipal(String user,
- String password,
- boolean isHashed,
- String nonce,
- String createdTime,
- String pwType) throws WSSecurityException {
+ protected void verifyUnknownPassword(
+ org.apache.ws.security.message.token.UsernameToken usernameToken
+ ) throws WSSecurityException {
AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
- user, password, isHashed, nonce, createdTime);
- return super.createPrincipal(user, password, isHashed, nonce, createdTime, pwType);
+ usernameToken.getName(), null, false, null, null
+ );
}
+
}
}
Modified: cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java?rev=1067230&r1=1067229&r2=1067230&view=diff
==============================================================================
--- cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java (original)
+++ cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java Fri Feb 4 17:28:38 2011
@@ -20,11 +20,11 @@
package org.apache.cxf.ws.security.wss4j;
import java.security.Principal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.Vector;
import java.util.logging.Logger;
import javax.security.auth.Subject;
@@ -66,6 +66,7 @@ import org.apache.ws.security.handler.WS
import org.apache.ws.security.handler.WSHandlerResult;
import org.apache.ws.security.message.WSSecUsernameToken;
import org.apache.ws.security.processor.UsernameTokenProcessor;
+import org.apache.ws.security.validate.Validator;
/**
*
@@ -129,12 +130,16 @@ public class UsernameTokenInterceptor ex
try {
final WSUsernameTokenPrincipal princ = getPrincipal(child, message);
if (princ != null) {
- List<WSSecurityEngineResult>v = new Vector<WSSecurityEngineResult>();
- v.add(0, new WSSecurityEngineResult(WSConstants.UT, princ, null, null, null));
+ List<WSSecurityEngineResult>v = new ArrayList<WSSecurityEngineResult>();
+ int action = WSConstants.UT;
+ if (princ.getPassword() == null) {
+ action = WSConstants.UT_UNKNOWN;
+ }
+ v.add(0, new WSSecurityEngineResult(action, princ, null, null, null));
List<WSHandlerResult> results = CastUtils.cast((List<?>)message
.get(WSHandlerConstants.RECV_RESULTS));
if (results == null) {
- results = new Vector<WSHandlerResult>();
+ results = new ArrayList<WSHandlerResult>();
message.put(WSHandlerConstants.RECV_RESULTS, results);
}
WSHandlerResult rResult = new WSHandlerResult(null, v);
@@ -165,6 +170,11 @@ public class UsernameTokenInterceptor ex
Object validateProperty = message.getContextualProperty(SecurityConstants.VALIDATE_PASSWORD);
if (validateProperty == null || MessageUtils.isTrue(validateProperty)) {
UsernameTokenProcessor p = new UsernameTokenProcessor();
+ Object validator =
+ message.getContextualProperty(SecurityConstants.USERNAME_TOKEN_VALIDATOR);
+ if (validator instanceof Validator) {
+ p.setValidator((Validator)validator);
+ }
WSDocInfo wsDocInfo = new WSDocInfo(tokenElement.getOwnerDocument());
List<WSSecurityEngineResult> results =
p.handleToken(tokenElement, null, null, getCallback(message), wsDocInfo, null);
Modified: cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1067230&r1=1067229&r2=1067230&view=diff
==============================================================================
--- cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ cxf/branches/wss4j-1.6-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Fri Feb 4 17:28:38 2011
@@ -20,10 +20,10 @@ package org.apache.cxf.ws.security.wss4j
import java.io.IOException;
import java.security.Principal;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -68,9 +68,10 @@ import org.apache.ws.security.handler.Re
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.handler.WSHandlerResult;
import org.apache.ws.security.message.token.SecurityTokenReference;
-import org.apache.ws.security.message.token.Timestamp;
import org.apache.ws.security.processor.Processor;
import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.validate.NoOpValidator;
+import org.apache.ws.security.validate.Validator;
/**
* Performs WS-Security inbound actions.
@@ -83,6 +84,7 @@ public class WSS4JInInterceptor extends
public static final String SIGNATURE_RESULT = "wss4j.signature.result";
public static final String PRINCIPAL_RESULT = "wss4j.principal.result";
public static final String PROCESSOR_MAP = "wss4j.processor.map";
+ public static final String VALIDATOR_MAP = "wss4j.validator.map";
public static final String SECURITY_PROCESSED = WSS4JInInterceptor.class.getName() + ".DONE";
@@ -113,10 +115,21 @@ public class WSS4JInInterceptor extends
public WSS4JInInterceptor(Map<String, Object> properties) {
this();
setProperties(properties);
- final Map<QName, Object> map = CastUtils.cast(
+ final Map<QName, Object> processorMap = CastUtils.cast(
(Map<?, ?>)properties.get(PROCESSOR_MAP));
- if (map != null) {
- secEngineOverride = createSecurityEngine(map);
+ final Map<QName, Object> validatorMap = CastUtils.cast(
+ (Map<?, ?>)properties.get(VALIDATOR_MAP));
+
+ if (processorMap != null) {
+ if (validatorMap != null) {
+ processorMap.putAll(validatorMap);
+ }
+ secEngineOverride = createSecurityEngine(processorMap);
+ } else if (validatorMap != null) {
+ if (processorMap != null) {
+ validatorMap.putAll(processorMap);
+ }
+ secEngineOverride = createSecurityEngine(validatorMap);
}
}
@@ -192,7 +205,7 @@ public class WSS4JInInterceptor extends
try {
reqData.setMsgContext(msg);
computeAction(msg, reqData);
- List<Integer> actions = new Vector<Integer>();
+ List<Integer> actions = new ArrayList<Integer>();
String action = getAction(msg, version);
int doAction = WSSecurityUtil.decodeAction(action, actions);
@@ -233,14 +246,14 @@ public class WSS4JInInterceptor extends
checkSignatureConfirmation(reqData, wsResult);
}
- checkSignatures(msg, reqData, wsResult);
- checkTimestamps(msg, reqData, wsResult);
+ storeSignature(msg, reqData, wsResult);
+ storeTimestamp(msg, reqData, wsResult);
checkActions(msg, reqData, wsResult, actions);
doResults(msg, actor, doc, wsResult, utWithCallbacks);
} else { // no security header found
- // Create an empty result vector to pass into the required validation
+ // Create an empty result list to pass into the required validation
// methods.
- wsResult = new Vector<WSSecurityEngineResult>();
+ wsResult = new ArrayList<WSSecurityEngineResult>();
if (doc.getSOAPPart().getEnvelope().getBody().hasFault()) {
LOG.warning("Request does not contain Security header, "
@@ -303,11 +316,11 @@ public class WSS4JInInterceptor extends
}
}
- private void checkSignatures(
+ private void storeSignature(
SoapMessage msg, RequestData reqData, List<WSSecurityEngineResult> wsResult
) throws WSSecurityException {
- // Extract the signature action result from the action vector
- List<WSSecurityEngineResult> signatureResults = new Vector<WSSecurityEngineResult>();
+ // Extract the signature action result from the action list
+ List<WSSecurityEngineResult> signatureResults = new ArrayList<WSSecurityEngineResult>();
signatureResults =
WSSecurityUtil.fetchAllActionResults(wsResult, WSConstants.SIGN, signatureResults);
@@ -317,32 +330,16 @@ public class WSS4JInInterceptor extends
}
}
- protected void checkTimestamps(
+ private void storeTimestamp(
SoapMessage msg, RequestData reqData, List<WSSecurityEngineResult> wsResult
) throws WSSecurityException {
- /*
- * Perform further checks on the timestamp that was transmitted in
- * the header. In the following implementation the timestamp is
- * valid if it was created after (now-ttl), where ttl is set on
- * server side, not by the client. Note: the method
- * verifyTimestamp(Timestamp) allows custom implementations with
- * other validation algorithms for subclasses.
- */
- // Extract the timestamp action result from the action vector
- List<WSSecurityEngineResult> timestampResults = new Vector<WSSecurityEngineResult>();
+ // Extract the timestamp action result from the action list
+ List<WSSecurityEngineResult> timestampResults = new ArrayList<WSSecurityEngineResult>();
timestampResults =
WSSecurityUtil.fetchAllActionResults(wsResult, WSConstants.TS, timestampResults);
if (!timestampResults.isEmpty()) {
- for (WSSecurityEngineResult result : timestampResults) {
- Timestamp timestamp = (Timestamp)result.get(WSSecurityEngineResult.TAG_TIMESTAMP);
-
- if (timestamp != null && !verifyTimestamp(timestamp, decodeTimeToLive(reqData))) {
- LOG.warning("The timestamp could not be validated");
- throw new WSSecurityException(WSSecurityException.MESSAGE_EXPIRED);
- }
- msg.put(TIMESTAMP_RESULT, result);
- }
+ msg.put(TIMESTAMP_RESULT, timestampResults.get(timestampResults.size() - 1));
}
}
@@ -373,7 +370,7 @@ public class WSS4JInInterceptor extends
*/
List<WSHandlerResult> results = CastUtils.cast((List<?>)msg.get(WSHandlerConstants.RECV_RESULTS));
if (results == null) {
- results = new Vector<WSHandlerResult>();
+ results = new ArrayList<WSHandlerResult>();
msg.put(WSHandlerConstants.RECV_RESULTS, results);
}
WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
@@ -479,7 +476,8 @@ public class WSS4JInInterceptor extends
protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utWithCallbacks)
throws WSSecurityException {
- if (!utWithCallbacks && (doAction & WSConstants.UT) != 0) {
+ if (!utWithCallbacks
+ && ((doAction & WSConstants.UT) != 0 || (doAction & WSConstants.UT_UNKNOWN) != 0)) {
CallbackHandler pwdCallback = null;
try {
pwdCallback = getCallback(reqData, doAction);
@@ -553,10 +551,9 @@ public class WSS4JInInterceptor extends
}
if (!utWithCallbacks) {
- Map<QName, Object> profiles = new HashMap<QName, Object>(3);
- Processor processor = new UsernameTokenProcessorWithoutCallbacks();
- profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
- profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+ Map<QName, Object> profiles = new HashMap<QName, Object>(1);
+ Validator validator = new NoOpValidator();
+ profiles.put(WSSecurityEngine.USERNAME_TOKEN, validator);
return createSecurityEngine(profiles);
}
@@ -581,6 +578,8 @@ public class WSS4JInInterceptor extends
config.setProcessor(key, (Class<?>)val);
} else if (val instanceof Processor) {
config.setProcessor(key, (Processor)val);
+ } else if (val instanceof Validator) {
+ config.setValidator(key, (Validator)val);
} else if (val == null) {
config.setProcessor(key, (Class<?>)val);
}
Modified: cxf/branches/wss4j-1.6-port/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/CustomProcessor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j-1.6-port/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/CustomProcessor.java?rev=1067230&r1=1067229&r2=1067230&view=diff
==============================================================================
--- cxf/branches/wss4j-1.6-port/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/CustomProcessor.java (original)
+++ cxf/branches/wss4j-1.6-port/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/CustomProcessor.java Fri Feb 4 17:28:38 2011
@@ -26,6 +26,7 @@ import org.apache.ws.security.WSSecurity
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.message.token.SecurityContextToken;
import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.validate.Validator;
/**
* a custom processor that inserts itself into the results vector
@@ -49,5 +50,9 @@ public class CustomProcessor implements
result.put("foo", this);
return java.util.Collections.singletonList(result);
}
+
+ public void setValidator(Validator validator) {
+ //
+ }
}