Repository: cxf Updated Branches: refs/heads/master 037b0ee94 -> 66c2c5b99
Change the ReceivedTokenCallbackHandler to follow an ordering when retrieving a token from the previous message Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/631ac6ba Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/631ac6ba Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/631ac6ba Branch: refs/heads/master Commit: 631ac6ba0765022a0f53500ac986b61cbabca60c Parents: 037b0ee 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 10:08:46 2017 +0100 ---------------------------------------------------------------------- .../ReceivedTokenCallbackHandler.java | 83 +++++++++++++------- 1 file changed, 53 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/631ac6ba/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 cdb515a..3ef5cfe 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 @@ -47,6 +49,17 @@ import org.apache.wss4j.dom.message.token.UsernameToken; */ 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; } @@ -91,37 +104,39 @@ 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(); - } + 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(); + } - // 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(); + 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; } @@ -135,4 +150,12 @@ public class ReceivedTokenCallbackHandler implements CallbackHandler { this.useTransformedToken = useTransformedToken; } + public List<Integer> getSecurityPriorities() { + return securityPriorities; + } + + public void setSecurityPriorities(List<Integer> securityPriorities) { + this.securityPriorities = securityPriorities; + } + }
