spring-projects / spring-ws

Spring Web Services
https://spring.io/projects/spring-ws
Apache License 2.0
319 stars 311 forks source link

WSS4J-based WS-Security implementation [SWS-207] #359

Closed gregturn closed 16 years ago

gregturn commented 17 years ago

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:

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

gregturn commented 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?

gregturn commented 16 years ago

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

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

Arjen Poutsma commented

I really would appreciate somebody working on this, since my TODO-list for version 1.5 is already pretty full.

gregturn commented 16 years ago

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: \ \ \ \ \ \hotdog\ \ \ \ \ \ \ \

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.

gregturn commented 16 years ago

Arjen Poutsma commented

Great! I will take a look at it as soon as possible.

gregturn commented 16 years ago

Tareq Abedrabbo commented

Update:

gregturn commented 16 years ago

Tareq Abedrabbo commented

Sorry. I attached the wrong file. Here's the new one.

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

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 ...

gregturn commented 16 years ago

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:

gregturn commented 16 years ago

Tareq Abedrabbo commented

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?

gregturn commented 16 years ago

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: \ \ \ \ \org.apache.ws.security.components.crypto.Merlin\ \jks\ \123456\ \c:/keystore\ \ \ \ \ \ \ \ \hotdog\ \ \ \ \ \ \ \

gregturn commented 16 years ago

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 \, 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.

gregturn commented 16 years ago

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?

\ \ \ \ \

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

Tareq Abedrabbo commented

Forgot to include a config example: \ \ \ \

\\\\\\\\\

          <property name="configLocation" value="classpath:signatureCrypto.properties"/>
     </bean>
</property>

\

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

Tareq Abedrabbo commented

Update:

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>
gregturn commented 16 years ago

Tareq Abedrabbo commented

Update:

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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

gregturn commented 16 years ago

Tareq Abedrabbo commented

Signature validation seemed to work for me. I'll check that again.

gregturn commented 16 years ago

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 ...)

gregturn commented 16 years ago

kaushik khanna commented

Tareq, thanks for responding. I'll execute the test case and let u know the results.

Thanks, Kaushik

gregturn commented 16 years ago

Tareq Abedrabbo commented

Update:

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

Tareq Abedrabbo commented

Hi Arjen,

Here's an update on the 2 issues:

A couple of remarks:

gregturn commented 16 years ago

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 :).

gregturn commented 16 years ago

Tareq Abedrabbo commented

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

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?

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

Tareq Abedrabbo commented

I located and corrected the bug. It happens with Axiom messages only. removeHeaderElement works fine. I'll post an update later.

gregturn commented 16 years ago

Tareq Abedrabbo commented

-update

gregturn commented 16 years ago

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

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

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.

gregturn commented 16 years ago

Arjen Poutsma commented

Ok, I've started incorporating this in the code base. Thanks again, Tareq!