Fixing merge
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/750b01a6 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/750b01a6 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/750b01a6 Branch: refs/heads/3.0.x-fixes Commit: 750b01a6ef16614c0c388537bff2503353831e7e Parents: aa00a2d Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Wed Apr 5 13:20:22 2017 +0100 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Wed Apr 5 13:20:22 2017 +0100 ---------------------------------------------------------------------- .../IssuedTokenInterceptorProvider.java | 73 ++++++- .../security/trust/DefaultSTSTokenCacher.java | 210 ------------------- 2 files changed, 67 insertions(+), 216 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/750b01a6/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java index a27493a..e2c09b2 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java @@ -19,6 +19,8 @@ package org.apache.cxf.ws.security.policy.interceptors; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; @@ -31,7 +33,11 @@ import java.util.logging.Logger; import javax.xml.namespace.QName; +import org.w3c.dom.CDATASection; import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.Text; + import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.helpers.CastUtils; @@ -59,6 +65,7 @@ import org.apache.cxf.ws.security.wss4j.policyvalidators.IssuedTokenPolicyValida import org.apache.wss4j.common.ext.WSSecurityException; import org.apache.wss4j.common.saml.SAMLKeyInfo; import org.apache.wss4j.common.saml.SamlAssertionWrapper; +import org.apache.wss4j.common.util.XMLUtils; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.WSSecurityEngineResult; import org.apache.wss4j.dom.handler.WSHandlerConstants; @@ -71,6 +78,7 @@ import org.apache.wss4j.policy.SPConstants; import org.apache.wss4j.policy.model.IssuedToken; import org.apache.wss4j.policy.model.Trust10; import org.apache.wss4j.policy.model.Trust13; +import org.apache.xml.security.utils.Base64; /** * @@ -312,19 +320,72 @@ public class IssuedTokenInterceptorProvider extends AbstractPolicyInterceptorPro return null; } - private String getIdFromToken(Element token) { + // Get an id from the token that is unique to that token + private static String getIdFromToken(Element token) { if (token != null) { - // Try to find the "Id" on the token. - if (token.hasAttributeNS(WSConstants.WSU_NS, "Id")) { - return token.getAttributeNS(WSConstants.WSU_NS, "Id"); - } else if (token.hasAttributeNS(null, "ID")) { + // For SAML tokens get the ID/AssertionID + if ("Assertion".equals(token.getLocalName()) + && WSConstants.SAML2_NS.equals(token.getNamespaceURI())) { return token.getAttributeNS(null, "ID"); - } else if (token.hasAttributeNS(null, "AssertionID")) { + } else if ("Assertion".equals(token.getLocalName()) + && WSConstants.SAML_NS.equals(token.getNamespaceURI())) { return token.getAttributeNS(null, "AssertionID"); } + + // For UsernameTokens get the username + if (WSConstants.USERNAME_TOKEN_LN.equals(token.getLocalName()) + && WSConstants.WSSE_NS.equals(token.getNamespaceURI())) { + Element usernameElement = + XMLUtils.getDirectChildElement(token, WSConstants.USERNAME_LN, WSConstants.WSSE_NS); + if (usernameElement != null) { + return getElementText(usernameElement); + } + } + + // For BinarySecurityTokens take the hash of the value + if (WSConstants.BINARY_TOKEN_LN.equals(token.getLocalName()) + && WSConstants.WSSE_NS.equals(token.getNamespaceURI())) { + String text = getElementText(token); + if (text != null && !"".equals(text)) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] bytes = digest.digest(text.getBytes()); + return Base64.encode(bytes); + } catch (NoSuchAlgorithmException e) { + // SHA-256 must be supported so not going to happen... + } + } + } } return ""; } + + /** + * Return the text content of an Element, or null if no such text content exists + */ + private static String getElementText(Element e) { + if (e != null) { + Node node = e.getFirstChild(); + StringBuilder builder = new StringBuilder(); + boolean found = false; + while (node != null) { + if (Node.TEXT_NODE == node.getNodeType()) { + found = true; + builder.append(((Text)node).getData()); + } else if (Node.CDATA_SECTION_NODE == node.getNodeType()) { + found = true; + builder.append(((CDATASection)node).getData()); + } + node = node.getNextSibling(); + } + + if (!found) { + return null; + } + return builder.toString(); + } + return null; + } private void storeDelegationTokens( Message message, http://git-wip-us.apache.org/repos/asf/cxf/blob/750b01a6/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/DefaultSTSTokenCacher.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/DefaultSTSTokenCacher.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/DefaultSTSTokenCacher.java deleted file mode 100644 index 972a9fd..0000000 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/DefaultSTSTokenCacher.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.cxf.ws.security.trust; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; - -import org.w3c.dom.Element; - -import org.apache.cxf.interceptor.Fault; -import org.apache.cxf.message.Message; -import org.apache.cxf.rt.security.utils.SecurityUtils; -import org.apache.cxf.ws.security.SecurityConstants; -import org.apache.cxf.ws.security.tokenstore.SecurityToken; -import org.apache.cxf.ws.security.tokenstore.TokenStore; -import org.apache.cxf.ws.security.tokenstore.TokenStoreUtils; -import org.apache.wss4j.common.ext.WSSecurityException; -import org.apache.wss4j.common.saml.SamlAssertionWrapper; -import org.apache.wss4j.common.util.XMLUtils; -import org.apache.wss4j.dom.WSConstants; -import org.apache.xml.security.utils.Base64; - -public class DefaultSTSTokenCacher implements STSTokenCacher { - - public SecurityToken retrieveToken(Message message) { - boolean cacheIssuedToken = - SecurityUtils.getSecurityPropertyBoolean(SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT, - message, - true); - SecurityToken tok = null; - if (cacheIssuedToken) { - tok = (SecurityToken)message.getContextualProperty(SecurityConstants.TOKEN); - if (tok == null) { - String tokId = (String)message.getContextualProperty(SecurityConstants.TOKEN_ID); - if (tokId != null) { - tok = TokenStoreUtils.getTokenStore(message).getToken(tokId); - } - } - } else { - tok = (SecurityToken)message.get(SecurityConstants.TOKEN); - if (tok == null) { - String tokId = (String)message.get(SecurityConstants.TOKEN_ID); - if (tokId != null) { - tok = TokenStoreUtils.getTokenStore(message).getToken(tokId); - } - } - } - return tok; - } - - public SecurityToken retrieveToken(Message message, Element delegationToken, String cacheKey) { - if (delegationToken == null) { - return null; - } - TokenStore tokenStore = TokenStoreUtils.getTokenStore(message); - - // See if the token corresponding to the delegation Token is stored in the cache - // and if it points to an issued token - String id = getIdFromToken(delegationToken); - SecurityToken cachedToken = tokenStore.getToken(id); - if (cachedToken != null) { - Map<String, Object> properties = cachedToken.getProperties(); - if (properties != null && properties.containsKey(cacheKey)) { - String associatedToken = (String)properties.get(cacheKey); - SecurityToken issuedToken = tokenStore.getToken(associatedToken); - if (issuedToken != null) { - return issuedToken; - } - } - } - - return null; - } - - public void storeToken(Message message, SecurityToken securityToken) { - boolean cacheIssuedToken = - SecurityUtils.getSecurityPropertyBoolean(SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT, - message, - true) - && !isOneTimeUse(securityToken); - if (cacheIssuedToken) { - message.getExchange().getEndpoint().put(SecurityConstants.TOKEN, securityToken); - message.getExchange().put(SecurityConstants.TOKEN, securityToken); - message.put(SecurityConstants.TOKEN_ELEMENT, securityToken.getToken()); - message.getExchange().put(SecurityConstants.TOKEN_ID, securityToken.getId()); - message.getExchange().getEndpoint().put(SecurityConstants.TOKEN_ID, - securityToken.getId()); - } else { - message.put(SecurityConstants.TOKEN, securityToken); - message.put(SecurityConstants.TOKEN_ID, securityToken.getId()); - message.put(SecurityConstants.TOKEN_ELEMENT, securityToken.getToken()); - } - // ? - TokenStoreUtils.getTokenStore(message).add(securityToken); - } - - public void storeToken(Message message, Element delegationToken, String secTokenId, String cacheKey) { - if (secTokenId == null || delegationToken == null) { - return; - } - - TokenStore tokenStore = TokenStoreUtils.getTokenStore(message); - - String id = getIdFromToken(delegationToken); - SecurityToken cachedToken = tokenStore.getToken(id); - if (cachedToken == null) { - cachedToken = new SecurityToken(id); - cachedToken.setToken(delegationToken); - } - Map<String, Object> properties = cachedToken.getProperties(); - if (properties == null) { - properties = new HashMap<>(); - cachedToken.setProperties(properties); - } - properties.put(cacheKey, secTokenId); - tokenStore.add(cachedToken); - } - - public void removeToken(Message message, SecurityToken securityToken) { - // Remove token from cache - message.getExchange().getEndpoint().remove(SecurityConstants.TOKEN); - message.getExchange().getEndpoint().remove(SecurityConstants.TOKEN_ID); - message.getExchange().remove(SecurityConstants.TOKEN_ID); - message.getExchange().remove(SecurityConstants.TOKEN); - if (securityToken != null) { - TokenStoreUtils.getTokenStore(message).remove(securityToken.getId()); - } - } - - // Check to see if the received token is a SAML2 Token with "OneTimeUse" set. If so, - // it should not be cached on the endpoint, but only on the message. - private static boolean isOneTimeUse(SecurityToken issuedToken) { - Element token = issuedToken.getToken(); - if (token != null && "Assertion".equals(token.getLocalName()) - && WSConstants.SAML2_NS.equals(token.getNamespaceURI())) { - try { - SamlAssertionWrapper assertion = new SamlAssertionWrapper(token); - - if (assertion.getSaml2().getConditions() != null - && assertion.getSaml2().getConditions().getOneTimeUse() != null) { - return true; - } - } catch (WSSecurityException ex) { - throw new Fault(ex); - } - } - - return false; - } - - // Get an id from the token that is unique to that token - private static String getIdFromToken(Element token) { - if (token != null) { - // For SAML tokens get the ID/AssertionID - if ("Assertion".equals(token.getLocalName()) - && WSConstants.SAML2_NS.equals(token.getNamespaceURI())) { - return token.getAttributeNS(null, "ID"); - } else if ("Assertion".equals(token.getLocalName()) - && WSConstants.SAML_NS.equals(token.getNamespaceURI())) { - return token.getAttributeNS(null, "AssertionID"); - } - - // For UsernameTokens get the username - if (WSConstants.USERNAME_TOKEN_LN.equals(token.getLocalName()) - && WSConstants.WSSE_NS.equals(token.getNamespaceURI())) { - Element usernameElement = - XMLUtils.getDirectChildElement(token, WSConstants.USERNAME_LN, WSConstants.WSSE_NS); - if (usernameElement != null) { - return XMLUtils.getElementText(usernameElement); - } - } - - // For BinarySecurityTokens take the hash of the value - if (WSConstants.BINARY_TOKEN_LN.equals(token.getLocalName()) - && WSConstants.WSSE_NS.equals(token.getNamespaceURI())) { - String text = XMLUtils.getElementText(token); - if (text != null && !"".equals(text)) { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - byte[] bytes = digest.digest(text.getBytes()); - return Base64.encode(bytes); - } catch (NoSuchAlgorithmException e) { - // SHA-256 must be supported so not going to happen... - } - } - } - } - return ""; - } - -} \ No newline at end of file