Issue Details (XML | Word | Printable)

Key: SWS-207
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Arjen Poutsma
Reporter: Arjen Poutsma
Votes: 16
Watchers: 7
Operations

If you were logged in you would be able to see more operations.
Spring Web Services

WSS4J-based WS-Security implementation

Created: 06/Oct/07 06:02 AM   Updated: 09/Mar/08 07:25 AM
Component/s: Security
Affects Version/s: None
Fix Version/s: 1.5 M2

Time Tracking:
Not Specified

File Attachments: 1. Java Archive File SWS-207.jar (104 kB)
2. Java Archive File SWS-207.jar (104 kB)
3. Java Archive File SWS-207.jar (89 kB)
4. Java Archive File SWS-207.jar (79 kB)
5. Java Archive File SWS-207.jar (66 kB)
6. Java Archive File SWS-207.jar (56 kB)
7. Java Archive File SWS-207.jar (45 kB)
8. Java Archive File SWS-207.jar (28 kB)
9. Java Archive File SWS-207.jar (17 kB)
10. Java Archive File SWS-207.jar (14 kB)
11. Java Archive File SWS-207.jar (10 kB)
12. Java Archive File SWS-207.jar (9 kB)
13. Java Archive File SWS-207.jar (9 kB)
14. Zip Archive SWS-207.zip (50 kB)

Issue Links:
Depends


 Description  « Hide
The current implementation of WS-Security is based on SUN's XWSS, which requires SUN's JDK 1.5. This means that it cannot be used on WebSphere, for instance.

There is an alternative WS-Security implementation called WSS4J (http://ws.apache.org/wss4j/). We can use this library to build an alternative WS-Security implementation, which does not require SUN's Java 5.



 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Chad Hahn added a comment - 30/Oct/07 12:30 PM
I'd like to see this get done and I'd be willing to help out. Is this already started or what is the status on this?

Arjen Poutsma added a comment - 30/Oct/07 12:37 PM
Great! It's not started yet; it's not even planned yet, but it would be great to get it before 1.1

I suggest looking at the given link, and this one: http://ws.apache.org/wss4j/api.html

The extension point in SWS will probably be: http://static.springframework.org/spring-ws/site/apidocs/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.html

Let me know if you need any more help


Nakul Bhuwalka added a comment - 12/Nov/07 05:57 AM
No comments have been added for a while. It would be a great help to know if someone is already working on this.

Arjen Poutsma added a comment - 15/Nov/07 12:44 PM
I really would appreciate somebody working on this, since my TODO-list for version 1.5 is already pretty full.

Tareq Abed Rabbo added a comment - 19/Nov/07 06:15 PM
I've implemented a limited support for wss4j. For the moment it only contains support for Username token, a SimplePasswordValidationCallbackHandler and an AcegiPlainTextPasswordValidationCallbackHandler. I tried to mime Xwss behavior in Spring-WS as closely as possible. I tested it with both Saaj and Axiom message factories.
Here's a configuration example:
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="callbackHandler">
<bean class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
<property name="users">
<props>
<prop key="bob">hotdog</prop>
</props>
</property>
</bean>
</property>
<property name="secureResponse" value="false"/>
<property name="validateRequest" value="true"/>
</bean>

or

<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor ">
<property name="callbackHandler">
<bean class="org.springframework.ws.soap.security.wss4j.callback.acegi.AcegiPlainTextPasswordValidationCallbackHandler">
<property name="authenticationManager">
<bean class="org.acegisecurity.MockAuthenticationManager"></bean>
</property>
</bean>
</property>
<property name="secureResponse" value="false"/>
<property name="validateRequest" value="true"/>
</bean>

It is still rough and incomplete. It could certainly use some more work. I hope you find it useful.


Arjen Poutsma added a comment - 19/Nov/07 06:33 PM
Great! I will take a look at it as soon as possible.

Tareq Abed Rabbo added a comment - 20/Nov/07 04:40 PM
Update:
  • Improved the implementation of Wss4jSecurityInterceptor and the callback handlers
  • added support for configuration of Wss4jSecurityInterceptor via actions (2 actions supported: UsernameToken and NoSecurity) with the appropriate validations:
    <bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="action" value="UsernameToken"/>
    <property name="callbackHandler">
    <bean class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
    <property name="users">
    <props>
    <prop key="bob">hotdog</prop>
    </props>
    </property>
    </bean>
    </property>
    <property name="secureResponse" value="false"/>
    <property name="validateRequest" value="true"/>
    </bean>
  • WSS4J validates timestamp headers out of the box
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsu:Timestamp wsu:Id="Timestamp-2157164" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsu:Created>2007-11-20T22:17:11.940Z</wsu:Created>
    <wsu:Expires>2007-11-20T22:18:11.940Z</wsu:Expires>
    </wsu:Timestamp>
    </wsse:Security>

Tareq Abed Rabbo added a comment - 20/Nov/07 04:45 PM
Sorry. I attached the wrong file. Here's the new one.

Arjen Poutsma added a comment - 21/Nov/07 04:10 AM
Thanks, Tareq. It will surely make its way into 1.5.

I have request: can you please give me the guarantee that the code that you attached can be released under the Apache License 2.0?


Tareq Abed Rabbo added a comment - 21/Nov/07 04:19 AM
No problem. The code can be released under the Apache License 2.0. Would you like me to include the license in the header of each file?
BTW, I'd like to work on it some more to add features/doc/comments ...

Arjen Poutsma added a comment - 21/Nov/07 05:27 AM
Ok, cool. Adding the license would help, saves me some work, and also makes our lawyers happy. (Yes, I hate this legal stuff just as much as the next guy, but it's important to get it right).

I've taken a look at the code, and I think we can make this work. Some remarks:

  • I'd like to see no dependencies between the wss4j package and the xwss package. If that means moving some classes from org.springframework.ws.soap.security.xwss.callback to a generic package like org.springframework.ws.soap.security.callback, that's fine with me. As long as we keep the public API in the xwss package the same. For instance, the AbstractCallbackHandler can be moved to org.springframework.ws.soap.security.callback. Also, we could create some abstract base classes in that package for stuff shared between xwss and wss4j. I can do this, if you want to.
  • I am a bit confused by WSS4J's callback mechanism. If I read the Javadoc correctly, the role of the handler of WSPasswordCallbacks is to supply passwords and other credentials. That would suggest that the approach should be to put the password in the callback, but your code gets the password from this callback. I wonder how this should work?

Tareq Abed Rabbo added a comment - 21/Nov/07 07:02 AM
  • Ok for the license. I'll take care of it soon.
  • I'm aware that should be no dependencies between wss4j and xwss. I used AbstractCallbackHandler as a quick start. I thought about the refactoring you described but maybe we need a specialized base class for wss4j call handlers (maybe a subclass of a common AbstractCallbackHandler?). If you noticed there's a pattern that is occuring in the 2 callback handlers I implemented, mainly the following test:
    passwordCallback.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN
    As the common part is going to grow as more usages are added, I thought I'd postpone the refactoring a bit till a clearer patterns emerges. What do you think?
  • I was confused too about the callback mechanism. Reading through the code and the documentation here's what I found out:
    The callback handler should test the usage. if it the password is Digest then the callback handler must delegate the processing to the engine. If the password is plain text or any other type (usage = WSPasswordCallback.USERNAME_TOKEN_UNKNOWN that's why I added the test) then the callback handler is responsible for the authentication process and should throw an IOException or UnsupportedCallbackException to express failure.

from the WSPasswordCallback javadoc:
"USERNAME_TOKEN_UNKNOWN - either an not specified password type or a password type passwordText. In these both cases only the password variable is set. The callback class now may check if the username and password match. If they don't match the callback class must throw an exception. The exception can be a UnsupportedCallbackException or an IOException."

from UsernameTokenProcessor.handleUsernameToken javadoc:
"Check the UsernameToken element. Depending on the password type contained in the element the processing differs. If the password type is password digest (a hashed password) then process the password commpletely here. Use the callback class to get a stored password perform hash algorithm and compare the result with the transmitted password."

Is my understanding correct?


Tareq Abed Rabbo added a comment - 23/Nov/07 01:54 PM
Update:
  • Improved the implementation of the interceptor
  • Added support for digest passwords
  • Added support for signatures
  • Supported actions: UsernameToken, Timestamp, Signature

Remarks:
-I'm only working on SimplePasswordValidationCallbackHandler for the moment so AcegiPlainTextPasswordValidationCallbackHandler is out of date

  • Signature verification fails with axiom messages

Here's how the configuration looks like:
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="action" value="UsernameToken Timestamp Signature"/>
<property name="signatureCryptoProperties">
<props>
<prop key="org.apache.ws.security.crypto.provider">org.apache.ws.security.components.crypto.Merlin</prop>
<prop key="org.apache.ws.security.crypto.merlin.keystore.type">jks</prop>
<prop key="org.apache.ws.security.crypto.merlin.keystore.password">123456</prop>
<prop key="org.apache.ws.security.crypto.merlin.file">c:/keystore</prop>
</props>
</property>
<property name="callbackHandler">
<bean class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
<property name="passwordDigestRequired" value="true"/>
<property name="users">
<props>
<prop key="bob">hotdog</prop>
</props>
</property>
</bean>
</property>
<property name="secureResponse" value="false"/>
<property name="validateRequest" value="true"/>
</bean>


Arjen Poutsma added a comment - 23/Nov/07 05:00 PM
Bean config looks good.

One thing I would change - if possible - is to make the crypto props another bean definition, rather than using <props>, which doesn't look very nice.

However, most people will use the Merlin implementation anyway, since that's built into the JDK since 1.4.


Tareq Abed Rabbo added a comment - 25/Nov/07 06:57 AM
you're right, the properties are rather ugly. Are you suggesting replacing signatureCryptoProperties with signatureCrypto so that something like the following could be written?

<property name="signatureCrypto">
<bean class="org.apache.ws.security.components.crypto.CryptoFactory" factory-method="getInstance">
<constructor-arg value="signatureCrypto.properties"/>
</bean>
</property>


Arjen Poutsma added a comment - 25/Nov/07 07:02 AM
Yes, that's what I would prefer. We should probably make it a FactoryBean, to make it easier to configure for users.

Tareq Abed Rabbo added a comment - 26/Nov/07 01:39 PM
Update:
-Added a CryptoFactoryBean as suggested. It basically does the same thing as CryptoFacotry but in a more Spring fashion. It is configured by injecting properties directly or a Spring Resource.
Actually, I didn't delegate to CryptoFactory because it functions in a way that could be confusing for Spring users. CryptoFactory basically reads a property file from the class path (a different class loader can be used) and keeps a singleton instance of a Crypto. If no property file is found a NPE is thrown.
CryptoFactoryBean implementation leaves scope management to Spring and is configured in a way familiar to Spring users. There are a couple of assertions to validate the configuration.
If needed, a CryptoFactory could still be used.
-Added some java doc and comments
What do you think?

Tareq Abed Rabbo added a comment - 26/Nov/07 01:42 PM
Forgot to include a config example:
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="action" value="Signature"/>
<property name="signatureCrypto">
<bean class="org.springframework.ws.soap.security.wss4j.CryptoFactoryBean">
<!-- <property name="cryptoProvider" value="org.apache.ws.security.components.crypto.Merlin"/>-->
<!-- <property name="config">-->
<!-- <props>-->
<!-- <prop key="org.apache.ws.security.crypto.provider">org.apache.ws.security.components.crypto.Merlin</prop>-->
<!-- <prop key="org.apache.ws.security.crypto.merlin.keystore.type">jks</prop>-->
<!-- <prop key="org.apache.ws.security.crypto.merlin.keystore.password">123456</prop>-->
<!-- <prop key="org.apache.ws.security.crypto.merlin.file">e:/privkeystore</prop>-->
<!-- </props>-->
<!-- </property>-->
<property name="configLocation" value="classpath:signatureCrypto.properties"/>
</bean>
</property>
</bean>

Tareq Abed Rabbo added a comment - 02/Dec/07 09:08 AM
I'm working on decryption support at the moment. I have a problem with axiom messages : after calling wss4j to decrypt an incoming message I have to replace tho original encrypted envelope with the decrypted one. I couldn't find a way to achieve that through Axiom api. Something like webServiceMessage.getAxiomMessage().setSOAPEnvelope(envelopeFromDOMDocument) is not permitted by Axiom (throws an UnsupportedOperationException). I didn't find a way to replace a webServiceMessage in Spring WS either.
Any ideas?

Arjen Poutsma added a comment - 02/Dec/07 04:00 PM
Well, there is a setSaajMessage on the SaajSoapEnvelope, but I've just noticed that there is no equivalent on the AxiomSoapMessage. I will add it.

Tareq Abed Rabbo added a comment - 03/Dec/07 05:10 PM
Update:
  • Signature validation works for axiom messages now
  • Support for decryption (only saaj for the moment)
  • Started working on securement actions. I have a query here. Wss4j relies on WSSecurityEngine to analyse WS-Security headers of incoming messages and on a specialized sub-class (Axis1, Axis2, Jax rpc) of WSHandler to secure outgoing messages. WSSecurityEngine has been quite easy to use. However, securing outgoing messages is less straightforward, basically because of the configuration system (String based, scattered through many classes)
    I have 2 choices here:
  • Try to reuse Wss4j classes: Sub class WSHandler and write ugly code to convert parameters from Spring beans to what WSHandler understands. I have to change the signature of AbstractWsSecurityInterceptor.secureMessage to add MessageContext as well beacuse wss4j needs it. This approach has the advantage of reusing Wss4j code.
  • Ignore WSHandler and reimplement its logic in a more Spring fashion. This approach is more elegant but a lot of Wss4j code has to be adapted (mainly WSHandler and Action sub classes code).

I have implemented a working example (though not perfect) of a securement action (Username token) using the first method.
Would you please take a look (if you have time) and tell me which approach you prefer?
Here's a brief configuration example:

<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="UsernameToken"/>
<property name="securementUsername" value="gort"/>
<property name="securementPassword" value="klaatu barada nikto"/>
<property name="securementPasswordType" value="PasswordText"/>
<property name="securementUsernameTokenElements" value="Nonce Created"/>
</bean>


Tareq Abed Rabbo added a comment - 12/Dec/07 12:33 PM
Update:
  • Some corrections
  • Axiom messages are replaced at the end of validation/securement. This is useful with actions that modify the soap message (adding username token, signature, ...). Needs 1.5 m1.
  • Added unit tests (interceptor and username token for the moment). Each test has 2 flavors: Axiom and Saaj.

Arjen Poutsma added a comment - 18/Dec/07 01:18 PM
I would like to incorporate the attached code into SVN, so that it can be part of 1.5 M2.

Tareq, do you feel that it is ready?


Tareq Abed Rabbo added a comment - 18/Dec/07 04:37 PM
Hi Arjen,

I think that the securement part needs some more work. Here's what's left to do:

  • complete/test securement actions and maybe figure out a better configuration model for them
  • Add more unit tests
  • Refactor Callback handlers (extract a base abstract class)
  • Better/more java docs

In addition to that I need your validation for the following points as they concern existent classes:

  • Added 2 methods to AxiomUtils: getDocumentFromSOAPEnvelope and getSOAPEnvelopeFromDomDocument
  • Added MessageContext parameter to AbstractWsSecurityInterceptor.secureMessage

If possible I'd appreciate having this week to finalize as much as possible of the these points.


Arjen Poutsma added a comment - 18/Dec/07 06:14 PM
Ok. 1.5 M2 is not planned until February 8th anyway, so I guess we still have some time.

As for the other questions:

  • I'd prefer using the standard java.xml.transform.Transformer to transform SoapEnvelopes to Documents, instead of adding these methods to AxiomUtils. Performance is not a real issue here, because WS-Security is slow anyway.
  • Adding the MessageContext parameter is fine, though it makes the SoapMessage parameter redundant. Why do you need it?

Also, if you are going to change existing classes - which is fine by me, could you please a patch rather than a jar file? That makes it easier for me to track what has changed. All major IDEs have built-in patch functionality, so it shouldn't be hard to do.


Sandeep Bansal added a comment - 19/Dec/07 04:39 AM
Hi Tareq/Arjen

I am trying to use this wss4j implementation in my project. I know its still under development but can you please help me out of the following issue.

I am trying to validate signature of a soap request. The soap envelope is being signed using the crypto.merlin. When I valdate using directly WSSecurityEngine.processSecurityHeader(...) in a standalone it works fine but when i try to use org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor in a spring application deployed on tomcat 5.0, it throws exception for the same SoapEnvelope. After careful debugging I found that the exception is actually -

org.apache.xml.security.signature.XMLSignatureException: The Reference for URI #id-24446859 has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI #id-24446859 has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Could not find a resolver for URI null and Base null
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Could not find a resolver for URI null and Base null
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Could not find a resolver for URI null and Base null
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Could not find a resolver for URI null and Base null

I am not sure what wrong I have done. Please help.


Tareq Abed Rabbo added a comment - 23/Dec/07 12:45 PM
Sandeep,
Thank you for testing the interceptor. I've not come across the exception you described. Have you resolved the problem?

Arjen,

  • As for using java.xml.transform.Transformer with axiom messages: actually, I started by using that. The resulting xml was semantically identical to the source but not textually. This caused signature validation to fail. That's when I had a look at what apache rampart does. I think this happens because the default xml transformer "optimizes" the xml. I wonder if there is a way to turn xml optimization off in an implementation independent way.
  • As for the message context I need to pass it to my subclass of WSHandler , which is the class that contains the securement logic. Wss4j uses the context to store/retrieve objects.
  • No problem, I'll provide the code as a patch once it is deemed stable.

BTW, I've just added basic support for securement signature and encryption. Now that the basic features are there, I'll start adding support for more options and doing some refactoring.


kaushik khanna added a comment - 28/Dec/07 12:38 AM
Tareq,
I also see same problem as Sandeep mentioned, and the cause for the same is that "The resulting xml is semantically identical to the source but not textually". I did see few namespace missing from the resulting xml. This causes the signature validation to fail.

I believe that XML transformation is done by the Core module and Security module rebuilds the XML for verification, but the resultant xml is not complete. Is there a way to get the original XML (Original SOAP message received) and use that for verification.

Thanks,
kaushik


Tareq Abed Rabbo added a comment - 28/Dec/07 01:15 AM
Signature validation seemed to work for me. I'll check that again.

Tareq Abed Rabbo added a comment - 29/Dec/07 03:30 PM
Update:
  • securement signature and encryption
  • validation and securement actor
  • Unit tests for validating signature (Saaj and Axiom)

Arjen,
I think that the certificate in /spring-ws-1.5.0-m1/security/src/test/resources/org/springframework/ws/soap/security/xwss/test-keystore.jks has expired!

Kaushik,
The problem with XML transformation occured when I used the standard transformation api with Axiom message. There is no transformation for Saaj messages and Axiom messages are now transformed using serialization. So, theoretically there should be no problem there.
Would you please run the unit tests on your environment? It would be nice if you can run them with the xml and keys you are using as well. If you still have problems, give me more details about what you are doing (message factory, xml, keys ...)


kaushik khanna added a comment - 02/Jan/08 09:04 AM
Tareq, thanks for responding.
I'll execute the test case and let u know the results.

Thanks,
Kaushik


Tareq Abed Rabbo added a comment - 02/Jan/08 05:03 PM
Update:
  • support for Username token options & Signature options: (Signature confirmation, signature parts, algorithm, ...)
  • more unit tests: Signature confirmation, encryption and decryption (total tests: 11 x 2)
  • some fixes

Claus Ibsen added a comment - 05/Jan/08 04:38 AM
Tareq this is really cool. We are a lot of people that are forced on the WebSphere wagon (like it or not) so your effort is really appreciated.

Tareq Abed Rabbo added a comment - 06/Jan/08 03:00 PM
Update:
  • Integration of signature and encryption options
  • Completed the implementation: time to live, certificate trust verification, ...
  • added securement callback handler
  • More unit tests (15 x 2)
  • A couple of fixes and improvements
  • Some docs

The interceptor is almost complete I think. I still have to refactor callback handlers and do some cleaning. I'll finish that shortly.

Claus,
Thank you for you encouraging words. I appreciate it.


Tareq Abed Rabbo added a comment - 15/Jan/08 10:56 AM
Update:
  • added support for decryption with an embedded symmetric key name.
  • refactored callback handlers.
  • added more javadocs.

Remarks:

  • Wss4j does not remove WS-Security headers. Is this an issue?
  • When validating a username token with a digest password, Wss4j doesn't give the control back. This means that in acegi callback handler the security context could not be set. I'm still looking for an elegant solution that doesn't introduce dependencies to acegi in the interceptor.

Aside from that, the interceptor is pretty finished. I would like to have your remarks on the above so that I can prepare a patch.


Arjen Poutsma added a comment - 21/Jan/08 04:21 AM
Hi Tareq,

Good stuff! This is one of the most popular issues to be resolved for 1.5.

  • Wss4j does not remove WS-Security headers. Is this an issue?

Then I think we should remove it. XWSS does remove the header, and the two interceptors need to be consistent.

  • When validating a username token with a digest password, Wss4j doesn't give the control back. This means that in acegi callback handler the security context could not be set. I'm still looking for an elegant solution that doesn't introduce dependencies to acegi in the interceptor.

Hmm, I'm not sure how to solve this. Which particular class do I need to look at?


Tareq Abed Rabbo added a comment - 22/Jan/08 07:02 AM
Hi Arjen,

Here's an update on the 2 issues:

  • added code to remove ws-security security header at the end of the validation.
  • added an aspect AcegiSecurityContextUpdateAdvice to set the acegi context after validating a username token with a digest password, in a non-intrusive way.
  • unit tests for the above.

A couple of remarks:

  • removing ws-security header works in a bizarre way with Axiom messages: the headers are removed from the message (tests with xpath expressions on the message's document pass). But they can still be accessed by iterating over the header elements. With Saaj everything is ok.
  • What do you think about using an aspect to solve the second point? It adds a little configuration overhead for the user in the some cases but is the least intrusive way I could think of.

Arjen Poutsma added a comment - 22/Jan/08 09:38 AM
  • removing ws-security header works in a bizarre way with Axiom messages: the headers are removed from the message (tests with xpath expressions on the message's document pass). But they can still be accessed by iterating over the header elements. With Saaj everything is ok.

Weird. Well, let's just say that it isn't the first Axiom issue I've found (https://issues.apache.org/jira/secure/IssueNavigator.jspa?pid=12310250&reporter=poutsma).

It might make sense to add a removeHeaderElement(QName) to the SoapHeader interface to fix this. Is that something you want me to add to the core?

  • What do you think about using an aspect to solve the second point? It adds a little configuration overhead for the user in the some cases but is the least intrusive way I could think of.

Hmm. Dependency-wise, I don't think this is a good idea, since it requires Spring AOP. I'd rather look for an alternate solution, if possible. It seems a bit hackish .


Tareq Abed Rabbo added a comment - 22/Jan/08 11:04 AM
  • adding a removeHeaderElement(QName) sounds good. No more need to hack into the envelope to remove the headers.
  • I agree that using an aspect to fix a gap in wss4j is far from ideal. Here are the other ideas I had:
  • adding specific code in the interceptor to set the context. This adds a dependency to acegi in the interceptor which is not acceptable for users not using acegi. In addition to that, it's not extensible.
  • externalizing context setting: I could introduce generic callback interfaces (validation post processing) with an acegi-specific implementation but I thought that it was too much. That's when I thought about writing an aspect.
    Any ideas?

Arjen Poutsma added a comment - 22/Jan/08 11:23 AM
  • adding a removeHeaderElement(QName) sounds good. No more need to hack into the envelope to remove the headers.

OK, added SWS-272. WIll fix it soon (today or tomorrow).

  • I agree that using an aspect to fix a gap in wss4j is far from ideal. Here are the other ideas I had:
  • adding specific code in the interceptor to set the context. This adds a dependency to acegi in the interceptor which is not acceptable for users not using acegi. In addition to that, it's not extensible.
  • externalizing context setting: I could introduce generic callback interfaces (validation post processing) with an acegi-specific implementation but I thought that it was too much. That's when I thought about writing an aspect.
    Any ideas?

Not yet. But I must say that I have not delved into the code deeply (yet). For the moment, let's leave it open, and clearly mark it with a TODO. Then, when I will incorporate the code into SVN, I will take a good look at it. Does that seem OK?


Tareq Abed Rabbo added a comment - 23/Jan/08 01:51 AM
Sounds sensible. As for SWS-272, I'll update the interceptor when it's done.
By the way, when I was experimenting with the wss4j interceptor, I wrote a JaxRpcHandlerAdapterInterceptor which is, as its name suggests, an interceptor that runs JAX-RPC's handlers in Spring-WS. This could be useful for people wanting to migrate existing web services to Spring-WS, especially headers processing. As an example, I tried it with Wss4j's JAX-RPC handler. It seemed to work but with a couple of drawbacks: saaj only, ugly configuration and a bug in the handler with sun's saaj implementation.
Would you like to see something like that in Spring-WS? Can I contribute it?

Tareq Abed Rabbo added a comment - 30/Jan/08 11:17 AM
Calling soapMessage.getEnvelope().getHeader().removeHeaderElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","wsse")) to remove WS-Security headers doesn't seem to work. My unit tests (with xpath expressions) are failling for both axiom and saaj messages.

Arjen Poutsma added a comment - 31/Jan/08 04:41 PM
You need to remove it with the "Security" localname, and not "wsse" (which is the prefix).

How much time do you think you need after this? We have the 1.5-M2 release coming up next week, and I really want to make it part of that.


Tareq Abed Rabbo added a comment - 01/Feb/08 04:55 AM
I'll have time to work on it tonight. I had tried what you suggested though, with no success. I also made AbstractWsSecurityInterceptor.WS_SECURITY_NAME protected and used it. Anyhow, I'll debug that tonight and hopefully find what's wrong so that the interceptor can make it to M2.

Tareq Abed Rabbo added a comment - 01/Feb/08 08:56 AM
I located and corrected the bug. It happens with Axiom messages only. removeHeaderElement works fine. I'll post an update later.

Tareq Abed Rabbo added a comment - 01/Feb/08 05:30 PM
-update
  • Corrected a bug in the removal of WS-Security header from Axiom messages. Now WS-Security headers are removed properly.

Arjen Poutsma added a comment - 04/Feb/08 06:04 AM
Hi Tareq,

I really want to start incorporating this in the SWS codebase as soon as possible, hopefully tomorrow (5 feb). Is there anything I should be aware off?

Thanks


Tareq Abed Rabbo added a comment - 04/Feb/08 11:17 AM
Hi Arjen,

I'm trying to prepare a complete patch to alleviate the task of integrating the code. As I changed the signature of secureMessage & validateMessage to take message context as a parameter, there is a slight impact on the code of XwsSecurityInterceptor and its unit tests.
I hope to find enough time to complete the work tonight. In all cases I'll post an update and a list of what should be considered to complete the integration.
I've already done a slight change: I've moved the utility method that I had added to AxiomUtil to a separate class so that there is no dependency between the core module and xml security.
Expect an update from me tonight or tomorrow early in the morning.


Tareq Abed Rabbo added a comment - 05/Feb/08 02:04 AM
Update:
  • Moved Axiom transformation methods a new class (Wss4jUtils) to avoid dependency between the core module and xml-security.

The archive contains a patch of the modified spring-ws classes (security module):

  • made AbstractWsSecurityInterceptor.WS_SECURITY_NAME protected
  • changed the signature of validateMessage & secureMessage to take MessageContext as a parameter.
  • moved AbstractCallbackHandler to org.springframework.ws.soap.security
  • modified xwss classes and unit tests in accordance.

Remarks:

  • I tested the various Wss4j functionalities with Bouncy Castle.
  • Each unit test consists of a base test case containing all the code, a Saaj subclass and an Axiom subclass.

That's what I can think of for the moment. I you need more details or help please let me know.


Arjen Poutsma added a comment - 06/Feb/08 05:46 AM
Ok, I've started incorporating this in the code base. Thanks again, Tareq!

Arjen Poutsma added a comment - 09/Feb/08 09:01 PM
Fixed. Many thanks to Tareq Abed Rabbo, for doing the hard work!

Note that the WSS4J still needs full reference documentation (SWS-282), coming in 1.5 RC1.
In the mean time, the airline spring-ws client uses WSS4J for UsernameToken authentication, so you look there.


Arjen Poutsma added a comment - 09/Mar/08 07:25 AM
Closing 1.5 M2 issues.