Repository: cxf Updated Branches: refs/heads/3.1.x-fixes eb98654ac -> b16f63b29
Change the ReceivedTokenCallbackHandler to follow an ordering when retrieving a token from the previous message # Conflicts: # rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/22a58c39 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/22a58c39 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/22a58c39 Branch: refs/heads/3.1.x-fixes Commit: 22a58c399ccdb94f5969ab3be9dfad46cf222af2 Parents: eb98654 Author: Colm O hEigeartaigh <[email protected]> Authored: Wed Apr 5 10:08:46 2017 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Wed Apr 5 11:41:58 2017 +0100 ---------------------------------------------------------------------- .../ReceivedTokenCallbackHandler.java | 91 ++++++++++++-------- 1 file changed, 57 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/22a58c39/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java index 523677b..7c32240 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/delegation/ReceivedTokenCallbackHandler.java @@ -21,24 +21,26 @@ package org.apache.cxf.ws.security.trust.delegation; import java.io.IOException; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; - import org.w3c.dom.Element; + import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.message.Message; import org.apache.cxf.phase.PhaseInterceptorChain; import org.apache.wss4j.common.saml.SamlAssertionWrapper; -import org.apache.wss4j.common.token.BinarySecurity; +import org.apache.wss4j.common.token.PKIPathSecurity; +import org.apache.wss4j.common.token.X509Security; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.engine.WSSecurityEngineResult; import org.apache.wss4j.dom.handler.WSHandlerConstants; import org.apache.wss4j.dom.handler.WSHandlerResult; -import org.apache.wss4j.dom.message.token.UsernameToken; /** * This CallbackHandler implementation obtains the previously received message from a @@ -46,7 +48,18 @@ import org.apache.wss4j.dom.message.token.UsernameToken; * (SAML/UsernameToken/BinarySecurityToken) from it to be used as the delegation token. */ public class ReceivedTokenCallbackHandler implements CallbackHandler { - + + private static final List<Integer> DEFAULT_SECURITY_PRIORITIES = new ArrayList<>(); + static { + DEFAULT_SECURITY_PRIORITIES.add(WSConstants.ST_SIGNED); + DEFAULT_SECURITY_PRIORITIES.add(WSConstants.ST_UNSIGNED); + DEFAULT_SECURITY_PRIORITIES.add(WSConstants.UT); + DEFAULT_SECURITY_PRIORITIES.add(WSConstants.BST); + DEFAULT_SECURITY_PRIORITIES.add(WSConstants.UT_NOPASSWORD); + } + + private List<Integer> securityPriorities = new ArrayList<>(DEFAULT_SECURITY_PRIORITIES); + private boolean useTransformedToken = true; @SuppressWarnings("unchecked") @@ -80,8 +93,8 @@ public class ReceivedTokenCallbackHandler implements CallbackHandler { List<WSHandlerResult> results = CastUtils.cast((List<?>)soapMessage.get(WSHandlerConstants.RECV_RESULTS)); if (results != null) { - for (WSHandlerResult rResult : results) { - Element token = findToken(rResult.getResults()); + for (WSHandlerResult handlerResult : results) { + Element token = getTokenFromResults(handlerResult); if (token != null) { return token; } @@ -90,38 +103,40 @@ public class ReceivedTokenCallbackHandler implements CallbackHandler { } return null; } - - private Element findToken( - List<WSSecurityEngineResult> wsSecEngineResults - ) { - for (WSSecurityEngineResult wser : wsSecEngineResults) { - // First check for a transformed token - Object transformedToken = wser.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN); - if (useTransformedToken && transformedToken instanceof SamlAssertionWrapper) { - return ((SamlAssertionWrapper)transformedToken).getElement(); - } - - // Otherwise check the actions - Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION); - if (actInt.intValue() == WSConstants.ST_SIGNED - || actInt.intValue() == WSConstants.ST_UNSIGNED) { - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)wser.get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - return assertion.getElement(); - } else if (actInt.intValue() == WSConstants.UT - || actInt.intValue() == WSConstants.UT_NOPASSWORD) { - UsernameToken token = - (UsernameToken)wser.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN); - return token.getElement(); - } else if (actInt.intValue() == WSConstants.BST) { - BinarySecurity token = - (BinarySecurity)wser.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN); - return token.getElement(); + + private Element getTokenFromResults(WSHandlerResult handlerResult) { + // Now go through the results in a certain order. Highest priority is first. + Map<Integer, List<WSSecurityEngineResult>> actionResults = handlerResult.getActionResults(); + for (Integer resultPriority : securityPriorities) { + List<WSSecurityEngineResult> foundResults = actionResults.get(resultPriority); + if (foundResults != null && !foundResults.isEmpty()) { + for (WSSecurityEngineResult result : foundResults) { + + if (!skipResult(resultPriority, result)) { + // First check for a transformed token + Object transformedToken = result.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN); + if (useTransformedToken && transformedToken instanceof SamlAssertionWrapper) { + return ((SamlAssertionWrapper)transformedToken).getElement(); + } + + if (result.get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT) != null) { + return (Element)result.get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT); + } + } + } } } + return null; } + protected boolean skipResult(Integer resultPriority, WSSecurityEngineResult result) { + Object binarySecurity = result.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN); + + return resultPriority == WSConstants.BST + && (binarySecurity instanceof X509Security || binarySecurity instanceof PKIPathSecurity); + } + public boolean isUseTransformedToken() { return useTransformedToken; } @@ -134,5 +149,13 @@ public class ReceivedTokenCallbackHandler implements CallbackHandler { public void setUseTransformedToken(boolean useTransformedToken) { this.useTransformedToken = useTransformedToken; } - + + public List<Integer> getSecurityPriorities() { + return securityPriorities; + } + + public void setSecurityPriorities(List<Integer> securityPriorities) { + this.securityPriorities = securityPriorities; + } + }
