You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/02/26 17:34:29 UTC
svn commit: r748200 - in
/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security:
policy/interceptors/ policy/model/ tokenstore/ wss4j/policyhandlers/
Author: dkulp
Date: Thu Feb 26 16:34:26 2009
New Revision: 748200
URL: http://svn.apache.org/viewvc?rev=748200&view=rev
Log:
Implement "Cancel" for WS-SC server side
Use WS-Add Action header if SOAPAction not set (WCF doesn't send a soapaction)
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java Thu Feb 26 16:34:26 2009
@@ -70,7 +70,12 @@
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.policy.SP11Constants;
import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.model.Binding;
+import org.apache.cxf.ws.security.policy.model.Header;
+import org.apache.cxf.ws.security.policy.model.ProtectionToken;
import org.apache.cxf.ws.security.policy.model.SecureConversationToken;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.cxf.ws.security.policy.model.SymmetricBinding;
import org.apache.cxf.ws.security.policy.model.Trust10;
import org.apache.cxf.ws.security.policy.model.Trust13;
import org.apache.cxf.ws.security.tokenstore.MemoryTokenStore;
@@ -317,7 +322,21 @@
public SecureConversationInInterceptor() {
super(Phase.PRE_PROTOCOL);
}
-
+ private Binding getBinding(AssertionInfoMap aim) {
+ Collection<AssertionInfo> ais = aim.get(SP12Constants.SYMMETRIC_BINDING);
+ if (ais != null && !ais.isEmpty()) {
+ return (Binding)ais.iterator().next().getAssertion();
+ }
+ ais = aim.get(SP12Constants.ASYMMETRIC_BINDING);
+ if (ais != null && !ais.isEmpty()) {
+ return (Binding)ais.iterator().next().getAssertion();
+ }
+ ais = aim.get(SP12Constants.TRANSPORT_BINDING);
+ if (ais != null && !ais.isEmpty()) {
+ return (Binding)ais.iterator().next().getAssertion();
+ }
+ return null;
+ }
public void handleMessage(SoapMessage message) throws Fault {
AssertionInfoMap aim = message.get(AssertionInfoMap.class);
// extract Assertion information
@@ -326,25 +345,35 @@
if (ais == null || ais.isEmpty()) {
return;
}
- if (!isRequestor(message)) {
- String s = (String)message.get(SoapBindingConstants.SOAP_ACTION);
+ if (isRequestor(message)) {
+ //client side should be checked on the way out
+ for (AssertionInfo ai : ais) {
+ ai.setAsserted(true);
+ }
+ return;
+ }
+ String s = (String)message.get(SoapBindingConstants.SOAP_ACTION);
+ String addNs = null;
+ AddressingProperties inProps = (AddressingProperties)message
+ .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
+ if (inProps != null) {
+ addNs = inProps.getNamespaceURI();
if (s == null) {
//MS/WCF doesn't put a soap action out for this, must check the headers
- AddressingProperties inProps = (AddressingProperties)message
- .getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
- if (inProps != null) {
- s = inProps.getAction().getValue();
- }
+ s = inProps.getAction().getValue();
}
+ }
+
+ if (s != null
+ && s.contains("/RST/SCT")
+ && (s.startsWith(STSUtils.WST_NS_05_02)
+ || s.startsWith(STSUtils.WST_NS_05_12))) {
- if (s != null
- && s.contains("/RST/SCT")
- && (s.startsWith(STSUtils.WST_NS_05_02)
- || s.startsWith(STSUtils.WST_NS_05_12))) {
-
- SecureConversationToken tok = (SecureConversationToken)ais.iterator()
- .next().getAssertion();
- Policy pol = tok.getBootstrapPolicy();
+ SecureConversationToken tok = (SecureConversationToken)ais.iterator()
+ .next().getAssertion();
+ Policy pol = tok.getBootstrapPolicy();
+ if (s.endsWith("Cancel") || s.endsWith("/Renew")) {
+ //Cancel and Renew just sign with the token
Policy p = new Policy();
ExactlyOne ea = new ExactlyOne();
p.addPolicyComponent(ea);
@@ -352,23 +381,50 @@
PolicyAssertion ass = getAddressingPolicy(aim, false);
all.addPolicyComponent(ass);
ea.addPolicyComponent(all);
- pol = p.merge(pol);
+ SymmetricBinding binding = new SymmetricBinding(SP12Constants.INSTANCE);
+ ProtectionToken token = new ProtectionToken(SP12Constants.INSTANCE);
+ token.setToken(new SecureConversationToken(SP12Constants.INSTANCE));
+ binding.setProtectionToken(token);
+ binding.setEntireHeadersAndBodySignatures(true);
+
+ Binding origBinding = getBinding(aim);
+ binding.setAlgorithmSuite(origBinding.getAlgorithmSuite());
+ all.addPolicyComponent(binding);
- //setup SCT endpoint and forward to it.
- unmapSecurityProps(message);
- String ns = STSUtils.WST_NS_05_12;
- if (s.startsWith(STSUtils.WST_NS_05_02)) {
- ns = STSUtils.WST_NS_05_02;
+ SignedEncryptedParts parts = new SignedEncryptedParts(true,
+ SP12Constants.INSTANCE);
+ parts.setBody(true);
+ if (addNs != null) {
+ parts.addHeader(new Header("To", addNs));
+ parts.addHeader(new Header("From", addNs));
+ parts.addHeader(new Header("FaultTo", addNs));
+ parts.addHeader(new Header("ReplyTO", addNs));
+ parts.addHeader(new Header("MessageID", addNs));
+ parts.addHeader(new Header("RelatesTo", addNs));
+ parts.addHeader(new Header("Action", addNs));
}
- recalcEffectivePolicy(message, ns, pol);
+ all.addPolicyComponent(parts);
+ pol = p;
} else {
- message.getInterceptorChain().add(new SecureConversationTokenFinderInterceptor());
+ Policy p = new Policy();
+ ExactlyOne ea = new ExactlyOne();
+ p.addPolicyComponent(ea);
+ All all = new All();
+ PolicyAssertion ass = getAddressingPolicy(aim, false);
+ all.addPolicyComponent(ass);
+ ea.addPolicyComponent(all);
+ pol = p.merge(pol);
}
+
+ //setup SCT endpoint and forward to it.
+ unmapSecurityProps(message);
+ String ns = STSUtils.WST_NS_05_12;
+ if (s.startsWith(STSUtils.WST_NS_05_02)) {
+ ns = STSUtils.WST_NS_05_02;
+ }
+ recalcEffectivePolicy(message, ns, pol);
} else {
- //client side should be checked on the way out
- for (AssertionInfo ai : ais) {
- ai.setAsserted(true);
- }
+ message.getInterceptorChain().add(new SecureConversationTokenFinderInterceptor());
}
}
}
@@ -429,7 +485,7 @@
AddressingProperties inProps = (AddressingProperties)exchange.getInMessage()
.getContextualProperty(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND);
if (inProps != null) {
- AddressingProperties props = new AddressingPropertiesImpl();
+ AddressingProperties props = new AddressingPropertiesImpl(inProps.getNamespaceURI());
AttributedURIType action = new AttributedURIType();
action.setValue(inProps.getAction().getValue().replace("/RST/", "/RSTR/"));
props.setAction(action);
@@ -440,90 +496,59 @@
MessageContentsList lst = (MessageContentsList)o;
DOMSource src = (DOMSource)lst.get(0);
Node nd = src.getNode();
- Element el = null;
+ Element requestEl = null;
if (nd instanceof Document) {
- el = ((Document)nd).getDocumentElement();
+ requestEl = ((Document)nd).getDocumentElement();
} else {
- el = (Element)nd;
+ requestEl = (Element)nd;
}
- String namespace = el.getNamespaceURI();
- String prefix = el.getPrefix();
- byte clientEntropy[] = null;
- int keySize = 256;
- int ttl = 300000;
- String tokenType = null;
- if ("RequestSecurityToken".equals(el.getLocalName())) {
+ String namespace = requestEl.getNamespaceURI();
+ String prefix = requestEl.getPrefix();
+ SecurityToken cancelToken = null;
+ if ("RequestSecurityToken".equals(requestEl.getLocalName())) {
try {
- el = DOMUtils.getFirstElement(el);
+ W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+ writer.setNsRepairing(true);
+ if (STSUtils.WST_NS_05_12.equals(namespace)) {
+ writer.writeStartElement(prefix, "RequestSecurityTokenResponseCollection",
+ namespace);
+ }
+ writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
+
+ String requestType = null;
+ Element el = DOMUtils.getFirstElement(requestEl);
while (el != null) {
String localName = el.getLocalName();
if (namespace.equals(el.getNamespaceURI())) {
- if ("Entropy".equals(localName)) {
- Element bs = DOMUtils.getFirstElement(el);
- if (bs != null) {
- clientEntropy = Base64.decode(bs.getTextContent());
- }
- } else if ("KeySize".equals(localName)) {
- keySize = Integer.parseInt(el.getTextContent());
- } else if ("TokenType".equals(localName)) {
- tokenType = el.getTextContent();
+ if ("RequestType".equals(localName)) {
+ requestType = el.getTextContent();
+ } else if ("CancelTarget".equals(localName)) {
+ cancelToken = findCancelToken(exchange, el);
}
}
el = DOMUtils.getNextElement(el);
}
+ if (requestType == null) {
+ requestType = "/Issue";
+ }
- W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
- writer.setNsRepairing(true);
- writer.writeStartElement(prefix, "RequestSecurityTokenResponse", namespace);
- writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
- SecurityContextToken sct =
- new SecurityContextToken(getWSCVersion(tokenType), writer.getDocument());
-
- Calendar created = Calendar.getInstance();
- Calendar expires = Calendar.getInstance();
- expires.setTimeInMillis(System.currentTimeMillis() + ttl);
-
- SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
- token.setToken(sct.getElement());
- token.setTokenType(WSConstants.WSC_SCT);
-
- writer.getCurrentNode().appendChild(sct.getElement());
- writer.writeEndElement();
-
- writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
- token.setAttachedReference(writeSecurityTokenReference(writer,
- "#" + sct.getID(),
- tokenType));
- writer.writeEndElement();
-
- writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
- token.setUnattachedReference(writeSecurityTokenReference(writer,
- sct.getIdentifier(),
- tokenType));
- writer.writeEndElement();
-
- XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
- writer.writeStartElement(prefix, "Lifetime", namespace);
- writer.writeNamespace("wsu", WSConstants.WSU_NS);
- writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
- writer.writeCharacters(fmt.format(created.getTime()));
- writer.writeEndElement();
-
- writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
- writer.writeCharacters(fmt.format(expires.getTime()));
- writer.writeEndElement();
- writer.writeEndElement();
-
- byte[] secret = writeProofToken(prefix,
- namespace,
- writer,
- clientEntropy,
- keySize);
- token.setSecret(secret);
- ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
- .getProperty(TokenStore.class.getName())).add(token);
+ if (requestType.endsWith("/Issue")) {
+ doIssue(requestEl, exchange, writer, prefix, namespace);
+ } else if (requestType.endsWith("/Cancel")) {
+ TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+ .getProperty(TokenStore.class.getName());
+ cancelToken.setState(SecurityToken.State.CANCELLED);
+ store.update(cancelToken);
+ writer.writeEmptyElement(prefix, "RequestedTokenCancelled", namespace);
+ exchange.put(SecurityConstants.TOKEN, cancelToken);
+ } else if (requestType.endsWith("/Renew")) {
+ //REVISIT - implement
+ }
writer.writeEndElement();
+ if (STSUtils.WST_NS_05_12.equals(namespace)) {
+ writer.writeEndElement();
+ }
return new MessageContentsList(new DOMSource(writer.getDocument()));
} catch (RuntimeException ex) {
throw ex;
@@ -531,10 +556,94 @@
throw new Fault(ex);
}
} else {
- throw new Fault("Unknown SecureConversation request type: " + el.getLocalName(), LOG);
+ throw new Fault("Unknown SecureConversation element: " + requestEl.getLocalName(), LOG);
}
}
+ private void doIssue(Element requestEl,
+ Exchange exchange, W3CDOMStreamWriter writer,
+ String prefix, String namespace)
+ throws Exception {
+ byte clientEntropy[] = null;
+ int keySize = 256;
+ int ttl = 300000;
+ String tokenType = null;
+ Element el = DOMUtils.getFirstElement(requestEl);
+ while (el != null) {
+ String localName = el.getLocalName();
+ if (namespace.equals(el.getNamespaceURI())) {
+ if ("Entropy".equals(localName)) {
+ Element bs = DOMUtils.getFirstElement(el);
+ if (bs != null) {
+ clientEntropy = Base64.decode(bs.getTextContent());
+ }
+ } else if ("KeySize".equals(localName)) {
+ keySize = Integer.parseInt(el.getTextContent());
+ } else if ("TokenType".equals(localName)) {
+ tokenType = el.getTextContent();
+ }
+ }
+
+ el = DOMUtils.getNextElement(el);
+ }
+
+ writer.writeStartElement(prefix, "RequestedSecurityToken", namespace);
+ SecurityContextToken sct =
+ new SecurityContextToken(getWSCVersion(tokenType), writer.getDocument());
+
+ Calendar created = Calendar.getInstance();
+ Calendar expires = Calendar.getInstance();
+ expires.setTimeInMillis(System.currentTimeMillis() + ttl);
+
+ SecurityToken token = new SecurityToken(sct.getIdentifier(), created, expires);
+ token.setToken(sct.getElement());
+ token.setTokenType(WSConstants.WSC_SCT);
+
+ writer.getCurrentNode().appendChild(sct.getElement());
+ writer.writeEndElement();
+
+ writer.writeStartElement(prefix, "RequestedAttachedReference", namespace);
+ token.setAttachedReference(writeSecurityTokenReference(writer,
+ "#" + sct.getID(),
+ tokenType));
+ writer.writeEndElement();
+
+ writer.writeStartElement(prefix, "RequestedUnattachedReference", namespace);
+ token.setUnattachedReference(writeSecurityTokenReference(writer,
+ sct.getIdentifier(),
+ tokenType));
+ writer.writeEndElement();
+
+ XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+ writer.writeStartElement(prefix, "Lifetime", namespace);
+ writer.writeNamespace("wsu", WSConstants.WSU_NS);
+ writer.writeStartElement("wsu", "Created", WSConstants.WSU_NS);
+ writer.writeCharacters(fmt.format(created.getTime()));
+ writer.writeEndElement();
+
+ writer.writeStartElement("wsu", "Expires", WSConstants.WSU_NS);
+ writer.writeCharacters(fmt.format(expires.getTime()));
+ writer.writeEndElement();
+ writer.writeEndElement();
+
+ byte[] secret = writeProofToken(prefix,
+ namespace,
+ writer,
+ clientEntropy,
+ keySize);
+ token.setSecret(secret);
+ ((TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+ .getProperty(TokenStore.class.getName())).add(token);
+ }
+
+ private SecurityToken findCancelToken(Exchange exchange, Element el) throws WSSecurityException {
+ SecurityTokenReference ref = new SecurityTokenReference(DOMUtils.getFirstElement(el));
+ String uri = ref.getReference().getURI();
+ TokenStore store = (TokenStore)exchange.get(Endpoint.class).getEndpointInfo()
+ .getProperty(TokenStore.class.getName());
+ return store.getToken(uri);
+ }
+
}
}
private static byte[] writeProofToken(String prefix,
@@ -551,7 +660,7 @@
random.nextBytes(secret);
writer.writeStartElement(prefix, "BinarySecret", namespace);
- writer.writeAttribute("", namespace + "/Nonce");
+ writer.writeAttribute("Type", namespace + "/Nonce");
writer.writeCharacters(Base64.encode(secret));
writer.writeEndElement();
} else {
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/model/Header.java Thu Feb 26 16:34:26 2009
@@ -23,6 +23,14 @@
private String name;
private String namespace;
+ public Header() {
+ }
+
+ public Header(String nm, String ns) {
+ name = nm;
+ namespace = ns;
+ }
+
/**
* @return Returns the name.
*/
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java Thu Feb 26 16:34:26 2009
@@ -38,7 +38,7 @@
*
*/
public class SecurityToken {
- enum State {
+ public enum State {
UNKNOWN,
ISSUED,
EXPIRED,
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java?rev=748200&r1=748199&r2=748200&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java Thu Feb 26 16:34:26 2009
@@ -669,7 +669,6 @@
sig.setCustomTokenId(sigTokId);
sig.setSecretKey(tok.getSecret());
- sig.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getAsymmetricSignature());
sig.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature());
Crypto crypto = null;
if (sbinding.getProtectionToken() != null) {