[CXF-6401] - Change the order that the set of security results are searched to create a security context
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/44bf65e6 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/44bf65e6 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/44bf65e6 Branch: refs/heads/master Commit: 44bf65e6dd21fbbde4c24685b20dcbcb0f0ccc1d Parents: a64265c Author: Colm O hEigeartaigh <[email protected]> Authored: Tue May 12 12:33:33 2015 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Tue May 12 14:17:32 2015 +0100 ---------------------------------------------------------------------- .../wss4j/StaxSecurityContextInInterceptor.java | 56 ++++++++++------- .../ws/security/wss4j/WSS4JInInterceptor.java | 65 ++++++++++++-------- 2 files changed, 74 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/44bf65e6/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSecurityContextInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSecurityContextInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSecurityContextInInterceptor.java index 2249335..9cd3f80 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSecurityContextInInterceptor.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSecurityContextInInterceptor.java @@ -19,6 +19,7 @@ package org.apache.cxf.ws.security.wss4j; import java.security.Principal; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -39,6 +40,7 @@ import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.SecurityContext; import org.apache.cxf.ws.security.SecurityConstants; import org.apache.wss4j.common.ext.WSSecurityException; +import org.apache.wss4j.common.principal.SAMLTokenPrincipal; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.apache.wss4j.stax.securityEvent.KerberosTokenSecurityEvent; import org.apache.wss4j.stax.securityEvent.KeyValueTokenSecurityEvent; @@ -49,6 +51,7 @@ import org.apache.wss4j.stax.securityEvent.X509TokenSecurityEvent; import org.apache.wss4j.stax.securityToken.SubjectAndPrincipalSecurityToken; import org.apache.xml.security.exceptions.XMLSecurityException; import org.apache.xml.security.stax.securityEvent.SecurityEvent; +import org.apache.xml.security.stax.securityEvent.SecurityEventConstants.Event; import org.apache.xml.security.stax.securityToken.SecurityTokenConstants.TokenUsage; /** @@ -85,11 +88,20 @@ public class StaxSecurityContextInInterceptor extends AbstractPhaseInterceptor<S } private void doResults(SoapMessage msg, List<SecurityEvent> incomingSecurityEventList) throws WSSecurityException { - for (SecurityEvent event : incomingSecurityEventList) { + + // Now go through the results in a certain order to set up a security context. Highest priority is first. + + List<Event> desiredSecurityEvents = new ArrayList<>(); + desiredSecurityEvents.add(WSSecurityEventConstants.SamlToken); + desiredSecurityEvents.add(WSSecurityEventConstants.UsernameToken); + desiredSecurityEvents.add(WSSecurityEventConstants.KerberosToken); + desiredSecurityEvents.add(WSSecurityEventConstants.X509Token); + desiredSecurityEvents.add(WSSecurityEventConstants.KeyValueToken); + for (Event desiredEvent : desiredSecurityEvents) { SubjectAndPrincipalSecurityToken token = null; try { - token = getSubjectPrincipalToken(event); + token = getSubjectPrincipalToken(incomingSecurityEventList, desiredEvent); } catch (XMLSecurityException ex) { // proceed } @@ -118,15 +130,14 @@ public class StaxSecurityContextInInterceptor extends AbstractPhaseInterceptor<S Object receivedAssertion = null; - if (event.getSecurityEventType() == WSSecurityEventConstants.SamlToken) { + if (desiredEvent == WSSecurityEventConstants.SamlToken) { String roleAttributeName = (String)SecurityUtils.getSecurityPropertyValue( SecurityConstants.SAML_ROLE_ATTRIBUTENAME, msg); if (roleAttributeName == null || roleAttributeName.length() == 0) { roleAttributeName = SAML_ROLE_ATTRIBUTENAME_DEFAULT; } - SamlTokenSecurityEvent samlEvent = (SamlTokenSecurityEvent)event; - receivedAssertion = samlEvent.getSamlAssertionWrapper(); + receivedAssertion = ((SAMLTokenPrincipal)token.getPrincipal()).getToken(); if (receivedAssertion != null) { ClaimCollection claims = SAMLUtils.getClaims((SamlAssertionWrapper)receivedAssertion); @@ -147,22 +158,25 @@ public class StaxSecurityContextInInterceptor extends AbstractPhaseInterceptor<S } } - private SubjectAndPrincipalSecurityToken getSubjectPrincipalToken( - SecurityEvent event - ) throws XMLSecurityException { - if (event.getSecurityEventType() == WSSecurityEventConstants.UsernameToken) { - return ((UsernameTokenSecurityEvent)event).getSecurityToken(); - } else if (event.getSecurityEventType() == WSSecurityEventConstants.SamlToken - && isSamlEventSigned((SamlTokenSecurityEvent)event)) { - return ((SamlTokenSecurityEvent)event).getSecurityToken(); - } else if (event.getSecurityEventType() == WSSecurityEventConstants.X509Token - && isUsedForPublicKeySignature(((X509TokenSecurityEvent)event).getSecurityToken())) { - return ((X509TokenSecurityEvent)event).getSecurityToken(); - } else if (event.getSecurityEventType() == WSSecurityEventConstants.KeyValueToken - && isUsedForPublicKeySignature(((KeyValueTokenSecurityEvent)event).getSecurityToken())) { - return ((KeyValueTokenSecurityEvent)event).getSecurityToken(); - } else if (event.getSecurityEventType() == WSSecurityEventConstants.KerberosToken) { - return ((KerberosTokenSecurityEvent)event).getSecurityToken(); + private SubjectAndPrincipalSecurityToken getSubjectPrincipalToken(List<SecurityEvent> incomingSecurityEventList, + Event desiredEvent) throws XMLSecurityException { + for (SecurityEvent event : incomingSecurityEventList) { + if (desiredEvent == event.getSecurityEventType()) { + if (event.getSecurityEventType() == WSSecurityEventConstants.UsernameToken) { + return ((UsernameTokenSecurityEvent)event).getSecurityToken(); + } else if (event.getSecurityEventType() == WSSecurityEventConstants.SamlToken + && isSamlEventSigned((SamlTokenSecurityEvent)event)) { + return ((SamlTokenSecurityEvent)event).getSecurityToken(); + } else if (event.getSecurityEventType() == WSSecurityEventConstants.X509Token + && isUsedForPublicKeySignature(((X509TokenSecurityEvent)event).getSecurityToken())) { + return ((X509TokenSecurityEvent)event).getSecurityToken(); + } else if (event.getSecurityEventType() == WSSecurityEventConstants.KeyValueToken + && isUsedForPublicKeySignature(((KeyValueTokenSecurityEvent)event).getSecurityToken())) { + return ((KeyValueTokenSecurityEvent)event).getSecurityToken(); + } else if (event.getSecurityEventType() == WSSecurityEventConstants.KerberosToken) { + return ((KerberosTokenSecurityEvent)event).getSecurityToken(); + } + } } return null; } http://git-wip-us.apache.org/repos/asf/cxf/blob/44bf65e6/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java index bed0c11..4d8c507 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java @@ -520,43 +520,56 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor { useJAASSubject = Boolean.parseBoolean(useJAASSubjectStr); } - for (int i = wsResult.getResults().size() - 1; i >= 0; i--) { - WSSecurityEngineResult o = wsResult.getResults().get(i); - - Integer action = (Integer)o.get(WSSecurityEngineResult.TAG_ACTION); - final Principal p = (Principal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL); - final Subject subject = (Subject)o.get(WSSecurityEngineResult.TAG_SUBJECT); - final Object binarySecurity = o.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN); - - final boolean isValidSamlToken = action == WSConstants.ST_SIGNED - || (allowUnsignedSamlPrincipals && action == WSConstants.ST_UNSIGNED); + // Now go through the results in a certain order to set up a security context. Highest priority is first. + + List<Integer> resultPriorities = new ArrayList<>(); + resultPriorities.add(WSConstants.ST_SIGNED); + resultPriorities.add(WSConstants.ST_UNSIGNED); + resultPriorities.add(WSConstants.UT); + resultPriorities.add(WSConstants.BST); + resultPriorities.add(WSConstants.SIGN); + resultPriorities.add(WSConstants.UT_NOPASSWORD); + + Map<Integer, List<WSSecurityEngineResult>> actionResults = wsResult.getActionResults(); + for (Integer resultPriority : resultPriorities) { + if (resultPriority == WSConstants.ST_UNSIGNED && !allowUnsignedSamlPrincipals) { + continue; + } - // UsernameToken, Kerberos, SAML token or XML Signature - if (action == WSConstants.UT || action == WSConstants.UT_NOPASSWORD - || (action == WSConstants.BST && binarySecurity instanceof KerberosSecurity) - || isValidSamlToken || action == WSConstants.SIGN) { - - if (action == WSConstants.SIGN) { - // Check we have a public key / certificate for the signing case + List<WSSecurityEngineResult> foundResults = actionResults.get(resultPriority); + if (foundResults != null && !foundResults.isEmpty()) { + for (WSSecurityEngineResult result : foundResults) { + final Object binarySecurity = result.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN); PublicKey publickey = - (PublicKey)o.get(WSSecurityEngineResult.TAG_PUBLIC_KEY); + (PublicKey)result.get(WSSecurityEngineResult.TAG_PUBLIC_KEY); X509Certificate cert = - (X509Certificate)o.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE); + (X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE); - if (publickey == null && cert == null) { + if ((resultPriority == WSConstants.BST && !(binarySecurity instanceof KerberosSecurity)) + || (resultPriority == WSConstants.SIGN && publickey == null && cert == null)) { continue; } - } - SecurityContext context = - createSecurityContext(msg, subject, p, useJAASSubject, o, utWithCallbacks); - if (context != null) { - msg.put(SecurityContext.class, context); - break; + SecurityContext context = + createSecurityContext(msg, useJAASSubject, result, utWithCallbacks); + if (context != null) { + msg.put(SecurityContext.class, context); + break; + } } } } } + private SecurityContext createSecurityContext( + SoapMessage msg, boolean useJAASSubject, + WSSecurityEngineResult wsResult, boolean utWithCallbacks + ) { + final Principal p = (Principal)wsResult.get(WSSecurityEngineResult.TAG_PRINCIPAL); + final Subject subject = (Subject)wsResult.get(WSSecurityEngineResult.TAG_SUBJECT); + + return createSecurityContext(msg, subject, p, useJAASSubject, wsResult, utWithCallbacks); + } + protected SecurityContext createSecurityContext( SoapMessage msg, Subject subject, Principal p, boolean useJAASSubject, WSSecurityEngineResult wsResult, boolean utWithCallbacks
