Closed gregturn closed 16 years ago
Chad Hahn commented
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 commented
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 commented
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 commented
I really would appreciate somebody working on this, since my TODO-list for version 1.5 is already pretty full.
Tareq Abedrabbo commented
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:
\
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 commented
Great! I will take a look at it as soon as possible.
Tareq Abedrabbo commented
Update:
Tareq Abedrabbo commented
Sorry. I attached the wrong file. Here's the new one.
Arjen Poutsma commented
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 Abedrabbo commented
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 commented
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 Abedrabbo commented
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 Abedrabbo commented
Update:
Remarks: -I'm only working on SimplePasswordValidationCallbackHandler for the moment so AcegiPlainTextPasswordValidationCallbackHandler is out of date
Here's how the configuration looks like:
\
Arjen Poutsma commented
Bean config looks good.
One thing I would change - if possible - is to make the crypto props another bean definition, rather than using \
However, most people will use the Merlin implementation anyway, since that's built into the JDK since 1.4.
Tareq Abedrabbo commented
you're right, the properties are rather ugly. Are you suggesting replacing signatureCryptoProperties with signatureCrypto so that something like the following could be written?
\
Arjen Poutsma commented
Yes, that's what I would prefer. We should probably make it a FactoryBean, to make it easier to configure for users.
Tareq Abedrabbo commented
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 Abedrabbo commented
Forgot to include a config example:
\
\\\\\\\\\
<property name="configLocation" value="classpath:signatureCrypto.properties"/>
</bean>
</property>
\
Tareq Abedrabbo commented
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 commented
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 Abedrabbo commented
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 Abedrabbo commented
Update:
Arjen Poutsma commented
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 Abedrabbo commented
Hi Arjen,
I think that the securement part needs some more work. Here's what's left to do:
In addition to that I need your validation for the following points as they concern existent classes:
If possible I'd appreciate having this week to finalize as much as possible of the these points.
Arjen Poutsma commented
Ok. 1.5 M2 is not planned until February 8th anyway, so I guess we still have some time.
As for the other questions:
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 commented
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 Abedrabbo commented
Sandeep, Thank you for testing the interceptor. I've not come across the exception you described. Have you resolved the problem?
Arjen,
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 commented
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 Abedrabbo commented
Signature validation seemed to work for me. I'll check that again.
Tareq Abedrabbo commented
Update:
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 commented
Tareq, thanks for responding. I'll execute the test case and let u know the results.
Thanks, Kaushik
Tareq Abedrabbo commented
Update:
Claus Ibsen commented
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 Abedrabbo commented
Update:
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 Abedrabbo commented
Update:
Remarks:
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 commented
Hi Tareq,
Good stuff! This is one of the most popular issues to be resolved for 1.5.
Then I think we should remove it. XWSS does remove the header, and the two interceptors need to be consistent.
Hmm, I'm not sure how to solve this. Which particular class do I need to look at?
Tareq Abedrabbo commented
Hi Arjen,
Here's an update on the 2 issues:
A couple of remarks:
Arjen Poutsma commented
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?
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 Abedrabbo commented
Arjen Poutsma commented
OK, added SWS-272. WIll fix it soon (today or tomorrow).
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 Abedrabbo commented
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 Abedrabbo commented
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 commented
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 Abedrabbo commented
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 Abedrabbo commented
I located and corrected the bug. It happens with Axiom messages only. removeHeaderElement works fine. I'll post an update later.
Tareq Abedrabbo commented
-update
Arjen Poutsma commented
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 Abedrabbo commented
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 Abedrabbo commented
Update:
The archive contains a patch of the modified spring-ws classes (security module):
Remarks:
That's what I can think of for the moment. I you need more details or help please let me know.
Arjen Poutsma commented
Ok, I've started incorporating this in the code base. Thanks again, Tareq!
Arjen Poutsma opened SWS-207 and commented
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.
Attachments:
Issue Links:
429 Add removeHeaderElement(QName) to SoapHeader
("depends on")
439 Document Wss4jInterceptor
("is depended on by")
Referenced from: commits https://github.com/spring-projects/spring-ws/commit/8efae9f36cd08f64d077200f97566d7a77d4d973, https://github.com/spring-projects/spring-ws/commit/a0c18b6834e2e183982072dafb7546acf930c238, https://github.com/spring-projects/spring-ws/commit/dc6b14905c6ebd672bffe123ee3b9acee84d7786, https://github.com/spring-projects/spring-ws/commit/671683bddd336791396fe79f880f96e500f2cbce, https://github.com/spring-projects/spring-ws/commit/915cd9462f902e5d0ed2bc61a9dba84ececc3932, https://github.com/spring-projects/spring-ws/commit/53fea29311552c444b3e3d5bb4b044613895a505
16 votes, 7 watchers