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 2017/04/04 16:29:13 UTC
[2/3] cxf git commit: CXF-7315 - Abstract the STS client token
caching behaviour to allow the user to plug in a custom implementation
CXF-7315 - Abstract the STS client token caching behaviour to allow the user to plug in a custom implementation
# Conflicts:
# rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
# rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/IssuedTokenInterceptorProvider.java
# rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java
# rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4b4bb843
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4b4bb843
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4b4bb843
Branch: refs/heads/3.1.x-fixes
Commit: 4b4bb8431520ac3571cce86a6557eb2480743815
Parents: d3f9087
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Apr 4 15:59:33 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Apr 4 16:50:16 2017 +0100
----------------------------------------------------------------------
.../cxf/rt/security/SecurityConstants.java | 11 +-
.../IssuedTokenInterceptorProvider.java | 15 +-
.../interceptors/STSTokenOutInterceptor.java | 22 +-
.../security/trust/DefaultSTSTokenCacher.java | 180 ++++++++++++++
.../cxf/ws/security/trust/STSTokenCacher.java | 59 +++++
.../ws/security/trust/STSTokenRetriever.java | 240 +++----------------
6 files changed, 315 insertions(+), 212 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
----------------------------------------------------------------------
diff --git a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
index aa0106d..61d3966 100644
--- a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
+++ b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
@@ -343,7 +343,14 @@ public class SecurityConstants {
*/
public static final String STS_TOKEN_IMMINENT_EXPIRY_VALUE =
"security.sts.token.imminent-expiry-value";
-
+
+ /**
+ * An implementation of the STSTokenCacher interface, if you want to plug in custom caching behaviour for
+ * STS clients. The default value is the DefaultSTSTokenCacher.
+ */
+ public static final String STS_TOKEN_CACHER_IMPL =
+ "security.sts.token.cacher.impl";
+
public static final Set<String> COMMON_PROPERTIES;
static {
@@ -359,7 +366,7 @@ public class SecurityConstants {
DISABLE_STS_CLIENT_WSMEX_CALL_USING_EPR_ADDRESS, STS_TOKEN_CRYPTO,
STS_TOKEN_PROPERTIES, STS_TOKEN_USERNAME, STS_TOKEN_ACT_AS, STS_TOKEN_ON_BEHALF_OF,
STS_CLIENT, STS_APPLIES_TO, CACHE_ISSUED_TOKEN_IN_ENDPOINT, PREFER_WSMEX_OVER_STS_CLIENT_CONFIG,
- STS_TOKEN_IMMINENT_EXPIRY_VALUE
+ STS_TOKEN_IMMINENT_EXPIRY_VALUE, STS_TOKEN_CACHER_IMPL
}));
COMMON_PROPERTIES = Collections.unmodifiableSet(s);
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/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 141ec94..47615fc 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
@@ -32,12 +32,15 @@ import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
+import org.apache.cxf.rt.security.utils.SecurityUtils;
import org.apache.cxf.ws.policy.AbstractPolicyInterceptorProvider;
import org.apache.cxf.ws.policy.AssertionInfo;
import org.apache.cxf.ws.policy.AssertionInfoMap;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.policy.PolicyUtils;
import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.trust.DefaultSTSTokenCacher;
+import org.apache.cxf.ws.security.trust.STSTokenCacher;
import org.apache.cxf.ws.security.trust.STSTokenRetriever;
import org.apache.cxf.ws.security.trust.STSTokenRetriever.TokenRequestParams;
import org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor;
@@ -130,8 +133,16 @@ public class IssuedTokenInterceptorProvider extends AbstractPolicyInterceptorPro
params.setTrust13(NegotiationUtils.getTrust13(aim));
params.setTokenTemplate(itok.getRequestSecurityTokenTemplate());
- SecurityToken tok = STSTokenRetriever.getToken(message, params);
-
+ // Get a custom STSTokenCacher implementation if specified
+ STSTokenCacher tokenCacher =
+ (STSTokenCacher)SecurityUtils.getSecurityPropertyValue(
+ SecurityConstants.STS_TOKEN_CACHER_IMPL, message
+ );
+ if (tokenCacher == null) {
+ tokenCacher = new DefaultSTSTokenCacher();
+ }
+ SecurityToken tok = STSTokenRetriever.getToken(message, params, tokenCacher);
+
if (tok != null) {
assertIssuedToken(itok, aim);
for (AssertionInfo ai : ais) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java
index ac71eac..c49c364 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/STSTokenOutInterceptor.java
@@ -33,7 +33,9 @@ import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.trust.DefaultSTSTokenCacher;
import org.apache.cxf.ws.security.trust.STSClient;
+import org.apache.cxf.ws.security.trust.STSTokenCacher;
import org.apache.cxf.ws.security.trust.STSTokenRetriever;
import org.apache.cxf.ws.security.trust.STSTokenRetriever.TokenRequestParams;
@@ -49,6 +51,7 @@ public class STSTokenOutInterceptor extends AbstractPhaseInterceptor<Message> {
private STSClient stsClient;
private TokenRequestParams tokenParams;
+ private STSTokenCacher tokenCacher = new DefaultSTSTokenCacher();
public STSTokenOutInterceptor(AuthParams authParams, String stsWsdlLocation, Bus bus) {
this(Phase.PREPARE_SEND, authParams, stsWsdlLocation, bus);
@@ -79,7 +82,7 @@ public class STSTokenOutInterceptor extends AbstractPhaseInterceptor<Message> {
if (stsClient != null) {
message.put(SecurityConstants.STS_CLIENT, stsClient);
}
- SecurityToken tok = STSTokenRetriever.getToken(message, tokenParams);
+ SecurityToken tok = STSTokenRetriever.getToken(message, tokenParams, tokenCacher);
if (tok == null) {
LOG.warning("Security token was not retrieved from STS");
}
@@ -94,7 +97,24 @@ public class STSTokenOutInterceptor extends AbstractPhaseInterceptor<Message> {
public STSClient getSTSClient() {
return stsClient;
}
+<<<<<<< HEAD
+=======
+
+ public STSTokenCacher getTokenCacher() {
+ return tokenCacher;
+ }
+
+ public void setTokenCacher(STSTokenCacher tokenCacher) {
+ this.tokenCacher = tokenCacher;
+ }
+
+ /**
+ * A enumeration to specify authentication mode in communication with STS.
+ * @deprecated use {@link org.apache.cxf.ws.security.trust.STSAuthParams.AuthMode}
+ */
+ @Deprecated
+>>>>>>> 048b46d... CXF-7315 - Abstract the STS client token caching behaviour to allow the user to plug in a custom implementation
public enum AuthMode {
X509(X509_ENDPOINT, KEY_TYPE_X509),
TRANSPORT(TRANSPORT_ENDPOINT, null);
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/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
new file mode 100644
index 0000000..6fc26f0
--- /dev/null
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/DefaultSTSTokenCacher.java
@@ -0,0 +1,180 @@
+/**
+ * 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.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.dom.WSConstants;
+
+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;
+ }
+
+ 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")) {
+ return token.getAttributeNS(null, "ID");
+ } else if (token.hasAttributeNS(null, "AssertionID")) {
+ return token.getAttributeNS(null, "AssertionID");
+ }
+ }
+ return "";
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenCacher.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenCacher.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenCacher.java
new file mode 100644
index 0000000..9a5d128
--- /dev/null
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenCacher.java
@@ -0,0 +1,59 @@
+/**
+ * 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 org.w3c.dom.Element;
+
+import org.apache.cxf.message.Message;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+
+/**
+ * This interface allows you to plug in some custom logic when storing/retrieving STS tokens in/from the cache
+ */
+public interface STSTokenCacher {
+
+ /**
+ * Retrieve a cached STS token
+ */
+ SecurityToken retrieveToken(Message message);
+
+ /**
+ * Retrieve a cached STS token for a given delegation token Element
+ */
+ SecurityToken retrieveToken(Message message, Element delegationToken, String cacheKey);
+
+ /**
+ * Store a token in the cache
+ */
+ void storeToken(Message message, SecurityToken securityToken);
+
+ /**
+ * Store a given delegation token in the cache (or update it if it's already there), with a reference to the
+ * security token obtained from the STS.
+ */
+ void storeToken(Message message, Element delegationToken, String secTokenId, String cacheKey);
+
+ /**
+ * Remove a cached STS token
+ */
+ void removeToken(Message message, SecurityToken securityToken);
+
+}
+
http://git-wip-us.apache.org/repos/asf/cxf/blob/4b4bb843/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java
index 41556a7..cf25b27 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSTokenRetriever.java
@@ -19,7 +19,6 @@
package org.apache.cxf.ws.security.trust;
-import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -33,11 +32,6 @@ import org.apache.cxf.rt.security.utils.SecurityUtils;
import org.apache.cxf.ws.addressing.AddressingProperties;
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.dom.WSConstants;
import org.apache.wss4j.policy.model.Trust10;
import org.apache.wss4j.policy.model.Trust13;
@@ -53,63 +47,23 @@ public final class STSTokenRetriever {
}
public static SecurityToken getToken(Message message, TokenRequestParams params) {
- SecurityToken tok = retrieveCachedToken(message);
- if (tok == null) {
- tok = issueToken(message, params);
- } else {
- tok = renewToken(message, tok, params);
- }
+ return getToken(message, params, new DefaultSTSTokenCacher());
+ }
- boolean cacheIssuedToken =
- SecurityUtils.getSecurityPropertyBoolean(SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT,
- message,
- true)
- && !isOneTimeUse(tok);
- if (cacheIssuedToken) {
- message.getExchange().getEndpoint().put(SecurityConstants.TOKEN, tok);
- message.getExchange().put(SecurityConstants.TOKEN, tok);
- message.put(SecurityConstants.TOKEN_ELEMENT, tok.getToken());
- message.getExchange().put(SecurityConstants.TOKEN_ID, tok.getId());
- message.getExchange().getEndpoint().put(SecurityConstants.TOKEN_ID,
- tok.getId());
+ public static SecurityToken getToken(Message message, TokenRequestParams params, STSTokenCacher tokenCacher) {
+ SecurityToken tok = tokenCacher.retrieveToken(message);
+ if (tok == null) {
+ tok = issueToken(message, params, tokenCacher);
} else {
- message.put(SecurityConstants.TOKEN, tok);
- message.put(SecurityConstants.TOKEN_ID, tok.getId());
- message.put(SecurityConstants.TOKEN_ELEMENT, tok.getToken());
+ tok = renewToken(message, tok, params, tokenCacher);
}
- // ?
- TokenStoreUtils.getTokenStore(message).add(tok);
- return tok;
- }
+ tokenCacher.storeToken(message, tok);
- private static SecurityToken retrieveCachedToken(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;
}
- private static SecurityToken issueToken(Message message, TokenRequestParams params) {
+ private static SecurityToken issueToken(Message message, TokenRequestParams params, STSTokenCacher tokenCacher) {
AddressingProperties maps =
(AddressingProperties)message
.get("javax.xml.ws.addressing.context.outbound");
@@ -152,20 +106,27 @@ public final class STSTokenRetriever {
Element onBehalfOfToken = client.getOnBehalfOfToken();
Element actAsToken = client.getActAsToken();
- SecurityToken secToken =
- handleDelegation(
- message, onBehalfOfToken, actAsToken, appliesTo,
- enableAppliesTo
- );
+ String key = appliesTo;
+ if (!enableAppliesTo || key == null || "".equals(key)) {
+ key = ASSOCIATED_TOKEN;
+ }
+ // See if the token corresponding to the OnBehalfOf/ActAs Token is stored in the cache
+ // and if it points to an issued token
+ SecurityToken secToken = tokenCacher.retrieveToken(message, onBehalfOfToken, key);
+ if (secToken == null) {
+ secToken = tokenCacher.retrieveToken(message, actAsToken, key);
+ }
if (secToken != null) {
// Check to see whether the delegated token needs to be renewed
- secToken = renewToken(message, secToken, params);
+ secToken = renewToken(message, secToken, params, tokenCacher);
} else {
secToken = getTokenFromSTS(message, client, maps, appliesTo, params);
}
- storeDelegationTokens(
- message, secToken, onBehalfOfToken, actAsToken, appliesTo,
- enableAppliesTo);
+
+ if (secToken != null) {
+ tokenCacher.storeToken(message, onBehalfOfToken, secToken.getId(), key);
+ tokenCacher.storeToken(message, actAsToken, secToken.getId(), key);
+ }
return secToken;
} catch (RuntimeException e) {
throw e;
@@ -183,7 +144,8 @@ public final class STSTokenRetriever {
private static SecurityToken renewToken(
Message message,
SecurityToken tok,
- TokenRequestParams params) {
+ TokenRequestParams params,
+ STSTokenCacher tokenCacher) {
String imminentExpiryValue =
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.STS_TOKEN_IMMINENT_EXPIRY_VALUE,
message);
@@ -198,17 +160,13 @@ public final class STSTokenRetriever {
}
// 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);
- TokenStoreUtils.getTokenStore(message).remove(tok.getId());
+ tokenCacher.removeToken(message, tok);
// If the user has explicitly disabled Renewing then we can't renew a token,
// so just get a new one
STSClient client = STSUtils.getClientWithIssuer(message, "sts", params.getIssuer());
if (!client.isAllowRenewing()) {
- return issueToken(message, params);
+ return issueToken(message, params, tokenCacher);
}
AddressingProperties maps =
@@ -241,7 +199,7 @@ public final class STSTokenRetriever {
SecurityConstants.STS_ISSUE_AFTER_FAILED_RENEW, message, true);
if (issueAfterFailedRenew) {
// Perhaps the STS does not support renewing, so try to issue a new token
- return issueToken(message, params);
+ return issueToken(message, params, tokenCacher);
} else {
throw ex;
}
@@ -252,7 +210,7 @@ public final class STSTokenRetriever {
SecurityConstants.STS_ISSUE_AFTER_FAILED_RENEW, message, true);
if (issueAfterFailedRenew) {
// Perhaps the STS does not support renewing, so try to issue a new token
- return issueToken(message, params);
+ return issueToken(message, params, tokenCacher);
} else {
throw new Fault(ex);
}
@@ -265,27 +223,6 @@ public final class STSTokenRetriever {
}
}
- // 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;
- }
-
private static void mapSecurityProps(Message message, Map<String, Object> ctx) {
for (String s : SecurityConstants.ALL_PROPERTIES) {
Object v = message.getContextualProperty(s + ".it");
@@ -298,118 +235,7 @@ public final class STSTokenRetriever {
}
}
- /**
- * Parse ActAs/OnBehalfOf appropriately. See if the required token is stored in the cache.
- */
- private static SecurityToken handleDelegation(
- Message message,
- Element onBehalfOfToken,
- Element actAsToken,
- String appliesTo,
- boolean enableAppliesTo) throws Exception {
- TokenStore tokenStore = TokenStoreUtils.getTokenStore(message);
- String key = appliesTo;
- if (!enableAppliesTo || key == null || "".equals(key)) {
- key = ASSOCIATED_TOKEN;
- }
- // See if the token corresponding to the OnBehalfOf Token is stored in the cache
- // and if it points to an issued token
- if (onBehalfOfToken != null) {
- String id = getIdFromToken(onBehalfOfToken);
- SecurityToken cachedToken = tokenStore.getToken(id);
- if (cachedToken != null) {
- Map<String, Object> properties = cachedToken.getProperties();
- if (properties != null && properties.containsKey(key)) {
- String associatedToken = (String)properties.get(key);
- SecurityToken issuedToken = tokenStore.getToken(associatedToken);
- if (issuedToken != null) {
- return issuedToken;
- }
- }
- }
- }
-
- // See if the token corresponding to the ActAs Token is stored in the cache
- // and if it points to an issued token
- if (actAsToken != null) {
- String id = getIdFromToken(actAsToken);
- SecurityToken cachedToken = tokenStore.getToken(id);
- if (cachedToken != null) {
- Map<String, Object> properties = cachedToken.getProperties();
- if (properties != null && properties.containsKey(key)) {
- String associatedToken = (String)properties.get(key);
- SecurityToken issuedToken = tokenStore.getToken(associatedToken);
- if (issuedToken != null) {
- return issuedToken;
- }
- }
- }
- }
- return null;
- }
-
- 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")) {
- return token.getAttributeNS(null, "ID");
- } else if (token.hasAttributeNS(null, "AssertionID")) {
- return token.getAttributeNS(null, "AssertionID");
- }
- }
- return "";
- }
-
- private static void storeDelegationTokens(
- Message message,
- SecurityToken issuedToken,
- Element onBehalfOfToken,
- Element actAsToken,
- String appliesTo,
- boolean enableAppliesTo) throws Exception {
- if (issuedToken == null) {
- return;
- }
- TokenStore tokenStore = TokenStoreUtils.getTokenStore(message);
- String key = appliesTo;
- if (!enableAppliesTo || key == null || "".equals(key)) {
- key = ASSOCIATED_TOKEN;
- }
- if (onBehalfOfToken != null) {
- String id = getIdFromToken(onBehalfOfToken);
- SecurityToken cachedToken = tokenStore.getToken(id);
- if (cachedToken == null) {
- cachedToken = new SecurityToken(id);
- cachedToken.setToken(onBehalfOfToken);
- }
- Map<String, Object> properties = cachedToken.getProperties();
- if (properties == null) {
- properties = new HashMap<>();
- cachedToken.setProperties(properties);
- }
- properties.put(key, issuedToken.getId());
- tokenStore.add(cachedToken);
- }
- if (actAsToken != null) {
- String id = getIdFromToken(actAsToken);
- SecurityToken cachedToken = tokenStore.getToken(id);
- if (cachedToken == null) {
- cachedToken = new SecurityToken(id);
- cachedToken.setToken(actAsToken);
- }
- Map<String, Object> properties = cachedToken.getProperties();
- if (properties == null) {
- properties = new HashMap<>();
- cachedToken.setProperties(properties);
- }
- properties.put(key, issuedToken.getId());
- tokenStore.add(cachedToken);
- }
- }
-
- private static SecurityToken getTokenFromSTS(Message message, STSClient client,
+ private static SecurityToken getTokenFromSTS(STSClient client,
AddressingProperties maps, String appliesTo,
TokenRequestParams params) throws Exception {
client.setTrust(params.getTrust10());
@@ -483,4 +309,4 @@ public final class STSTokenRetriever {
this.claims = claims;
}
}
-}
\ No newline at end of file
+}